forked from szuecs/gin-glog
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathginglog.go
168 lines (154 loc) · 3.89 KB
/
ginglog.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Package ginglog provides a logging middleware to get
// https://github.com/golang/glog as logging library for
// https://github.com/gin-gonic/gin. It can be used as replacement for
// the internal logging middleware
// http://godoc.org/github.com/gin-gonic/gin#Logger.
//
// Example:
// package main
// import (
// "flag
// "time"
// "github.com/golang/glog"
// "github.com/szuecs/gin-glog"
// "github.com/gin-gonic/gin"
// )
// func main() {
// flag.Parse()
// router := gin.New()
// router.Use(ginglog.Logger(3 * time.Second))
// //..
// router.Use(gin.Recovery())
// glog.Info("bootstrapped application")
// router.Run(":8080")
// }
//
// Your service will get new command line parameters from
// https://github.com/golang/glog.
package ginglog
import (
"time"
"github.com/gin-gonic/gin"
"github.com/golang/glog"
)
func setupLogging(duration time.Duration) {
go func() {
for range time.Tick(duration) {
glog.Flush()
}
}()
}
var (
green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
cyan = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
reset = string([]byte{27, 91, 48, 109})
)
// ErrorLogger returns an ErrorLoggerT with parameter gin.ErrorTypeAny
func ErrorLogger() gin.HandlerFunc {
return ErrorLoggerT(gin.ErrorTypeAny)
}
// ErrorLoggerT returns an ErrorLoggerT middleware with the given
// type gin.ErrorType.
func ErrorLoggerT(typ gin.ErrorType) gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
if !c.Writer.Written() {
json := c.Errors.ByType(typ).JSON()
if json != nil {
c.JSON(-1, json)
}
}
}
}
// Logger prints a logline for each request and measures the time to
// process for a call. It formats the log entries similar to
// http://godoc.org/github.com/gin-gonic/gin#Logger does.
//
// Example:
// router := gin.New()
// router.Use(ginglog.Logger(3 * time.Second))
func Logger(duration time.Duration) gin.HandlerFunc {
setupLogging(duration)
return func(c *gin.Context) {
t := time.Now()
// process request
c.Next()
latency := time.Since(t)
clientIP := c.ClientIP()
method := c.Request.Method
statusCode := c.Writer.Status()
statusColor := colorForStatus(statusCode)
methodColor := colorForMethod(method)
path := c.Request.URL.Path
switch {
case statusCode >= 400 && statusCode <= 499:
{
glog.Warningf("[GIN] |%s %3d %s| %12v | %s |%s %s %-7s %s\n%s",
statusColor, statusCode, reset,
latency,
clientIP,
methodColor, reset, method,
path,
c.Errors.String(),
)
}
case statusCode >= 500:
{
glog.Errorf("[GIN] |%s %3d %s| %12v | %s |%s %s %-7s %s\n%s",
statusColor, statusCode, reset,
latency,
clientIP,
methodColor, reset, method,
path,
c.Errors.String(),
)
}
default:
glog.V(2).Infof("[GIN] |%s %3d %s| %12v | %s |%s %s %-7s %s\n%s",
statusColor, statusCode, reset,
latency,
clientIP,
methodColor, reset, method,
path,
c.Errors.String(),
)
}
}
}
func colorForStatus(code int) string {
switch {
case code >= 200 && code <= 299:
return green
case code >= 300 && code <= 399:
return white
case code >= 400 && code <= 499:
return yellow
default:
return red
}
}
func colorForMethod(method string) string {
switch {
case method == "GET":
return blue
case method == "POST":
return cyan
case method == "PUT":
return yellow
case method == "DELETE":
return red
case method == "PATCH":
return green
case method == "HEAD":
return magenta
case method == "OPTIONS":
return white
default:
return reset
}
}