-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger.go
141 lines (127 loc) · 3.71 KB
/
logger.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
package gin_logrus
import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"net/http"
"time"
)
var (
// defaultTransformer is the default log transform function Logger middleware uses.
defaultTransformer = func(logger *logrus.Logger, params FieldsParams) {
fields := logrus.Fields{}
//
option := params.Option
if option.Host {
fields["Host"] = params.Request.Host
}
if option.Header {
fields["Header"] = params.Request.Header
}
if option.UserAgent {
fields["UserAgent"] = params.Request.UserAgent()
}
if option.Referer {
fields["Referer"] = params.Request.Referer()
}
fields["Latency"] = params.Latency
fields["ClientIP"] = params.ClientIP
fields["Path"] = params.Path
fields["TimeStamp"] = params.TimeStamp
entry := logger.WithFields(fields)
code := params.StatusCode
switch {
case code >= http.StatusOK && code < http.StatusBadRequest:
entry.Debugf("[gin-logrus]%d %s %3s", params.StatusCode, params.Method, http.StatusText(params.StatusCode))
case code >= http.StatusBadRequest && code < http.StatusInternalServerError:
entry.Warnf("[gin-logrus]%d %s %3s", params.StatusCode, params.Method, http.StatusText(params.StatusCode))
default:
entry.Errorf("[gin-logrus]%d %s %3s", params.StatusCode, params.Method, http.StatusText(params.StatusCode))
}
}
)
type LogTransformer func(logger *logrus.Logger, params FieldsParams)
// FieldsParams is the logrus Fields params·
type FieldsParams struct {
Request *http.Request
// TimeStamp shows the time after the server returns a response.
TimeStamp time.Time
// StatusCode is HTTP response code.
StatusCode int
// Latency is how much time the server cost to process a certain request.
Latency time.Duration
// ClientIP equals Context's ClientIP method.
ClientIP string
// Method is the HTTP method given to the request.
Method string
// Path is a path the client requests.
Path string
// ErrorMessage is set if error has occurred in processing the request.
ErrorMessage string
// BodySize is the size of the Response Body
BodySize int
// Keys are the keys set on the request's context.
Keys map[string]interface{}
Option OptionalFieldsParams
}
type OptionalFieldsParams struct {
//Optional fields
Host bool
Referer bool
UserAgent bool
Header bool
}
// LoggerConfig defines the config for Logger middleware.
type LoggerConfig struct {
Logger *logrus.Logger
Formatter LogTransformer
SkipPaths []string
Option OptionalFieldsParams
}
func Logger() gin.HandlerFunc {
return LoggerWithConfig(LoggerConfig{
Logger: logrus.New(),
Option: OptionalFieldsParams{},
})
}
func LoggerWithConfig(config LoggerConfig) gin.HandlerFunc {
logger := config.Logger
transformer := config.Formatter
if transformer == nil {
transformer = defaultTransformer
}
var skip map[string]struct{}
if length := len(config.SkipPaths); length > 0 {
skip = make(map[string]struct{}, length)
for _, path := range config.SkipPaths {
skip[path] = struct{}{}
}
}
return func(ctx *gin.Context) {
start := time.Now()
path := ctx.Request.URL.Path
raw := ctx.Request.URL.RawQuery
// Process request
ctx.Next()
// Log only when path is not being skipped
if _, ok := skip[path]; !ok {
param := FieldsParams{
Request: ctx.Request,
Keys: ctx.Keys,
Option: config.Option,
}
// Stop timer
param.TimeStamp = time.Now()
param.Latency = param.TimeStamp.Sub(start)
param.ClientIP = ctx.ClientIP()
param.Method = ctx.Request.Method
param.StatusCode = ctx.Writer.Status()
param.ErrorMessage = ctx.Errors.ByType(gin.ErrorTypePrivate).String()
param.BodySize = ctx.Writer.Size()
if raw != "" {
path = path + "?" + raw
}
param.Path = path
transformer(logger, param)
}
}
}