forked from rocksolidlabs/gin-logrus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathginlogrus.go
191 lines (172 loc) · 4.51 KB
/
ginlogrus.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Package ginlogrus provides a logging middleware to get
// https://github.com/sirupsen/logrus 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.
//
// Derived on https://github.com/zalando/gin-glog
//
// Example:
// package main
// import (
// "flag"
// "time"
// log "github.com/sirupsen/logrus"
// "github.com/rocksolidlabs/gin-logrus"
// "github.com/gin-gonic/gin"
// )
// func main() {
// flag.Parse()
// router := gin.New()
// router.Use(ginlogrus. Logger("MYAPI", false, true, os.Stdout, logrus.WarnLevel))
// //..
// router.Use(gin.Recovery())
// log.Info("bootstrapped application")
// router.Run(":8080")
// }
//
package ginlogrus
import (
"io"
"time"
"github.com/sirupsen/logrus"
"github.com/gin-gonic/gin"
)
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(ginlogrus.Logger(false, true, os.Stdout, log.WarnLevel))
func Logger(log *logrus.Logger, outputTag string, outputJSON bool, outputColor bool, outputFile io.Writer, outLevel logrus.Level) gin.HandlerFunc {
// Set the output tag
if outputTag == "" {
outputTag = "GIN"
}
// Log as JSON instead of the default ASCII formatter.
if outputJSON {
log.Formatter = &logrus.JSONFormatter{}
reset = ""
}
// Turn off logrus color
if !outputColor && !outputJSON {
log.Formatter = &logrus.TextFormatter{FullTimestamp: true, DisableColors: true}
reset = ""
}
// Output to stdout instead of the default stderr, could also be a file.
log.Out = outputFile
// Set log severity oputLevel or above.
log.SetLevel(outLevel)
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 := reset
methodColor := reset
if outputColor {
statusColor = colorForStatus(statusCode)
methodColor = colorForMethod(method)
}
path := c.Request.URL.Path
switch {
case statusCode >= 400 && statusCode <= 499:
{
log.Warningf("[%s] |%s %3d %s| %12v | %s |%s %s %-7s %s %s",
outputTag,
statusColor, statusCode, reset,
latency,
clientIP,
methodColor, reset, method,
path,
c.Errors.String(),
)
}
case statusCode >= 500:
{
log.Errorf("[%s] |%s %3d %s| %12v | %s |%s %s %-7s %s %s",
outputTag,
statusColor, statusCode, reset,
latency,
clientIP,
methodColor, reset, method,
path,
c.Errors.String(),
)
}
default:
log.Debugf("[%s] |%s %3d %s| %12v | %s |%s %s %-7s %s\n%s",
outputTag,
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
}
}