|
1
|
|
|
package middleware |
|
2
|
|
|
|
|
3
|
|
|
import ( |
|
4
|
|
|
"io" |
|
5
|
|
|
"net" |
|
6
|
|
|
"net/http" |
|
7
|
|
|
|
|
8
|
|
|
"github.com/gorilla/handlers" |
|
9
|
|
|
"github.com/muonsoft/openapi-mock/pkg/logcontext" |
|
10
|
|
|
"github.com/sirupsen/logrus" |
|
11
|
|
|
) |
|
12
|
|
|
|
|
13
|
|
|
type ContextLogger struct { |
|
14
|
|
|
logger *logrus.Logger |
|
15
|
|
|
next http.Handler |
|
16
|
|
|
} |
|
17
|
|
|
|
|
18
|
|
|
func NewContextLogger(logger *logrus.Logger, next http.Handler) *ContextLogger { |
|
19
|
|
|
middleware := &ContextLogger{logger: logger} |
|
20
|
|
|
middleware.next = handlers.CustomLoggingHandler(io.Discard, next, middleware.logRequest) |
|
21
|
|
|
|
|
22
|
|
|
return middleware |
|
23
|
|
|
} |
|
24
|
|
|
|
|
25
|
|
|
func (handler *ContextLogger) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) { |
|
26
|
|
|
requestContext := request.Context() |
|
27
|
|
|
|
|
28
|
|
|
logger := handler.logger.WithFields(logrus.Fields{ |
|
29
|
|
|
"requestId": RequestIDFromContext(requestContext), |
|
30
|
|
|
}) |
|
31
|
|
|
|
|
32
|
|
|
loggerContext := logcontext.WithLogger(requestContext, logger) |
|
33
|
|
|
contextualRequest := request.WithContext(loggerContext) |
|
34
|
|
|
|
|
35
|
|
|
handler.next.ServeHTTP(responseWriter, contextualRequest) |
|
36
|
|
|
} |
|
37
|
|
|
|
|
38
|
|
|
func (handler *ContextLogger) logRequest(_ io.Writer, params handlers.LogFormatterParams) { |
|
39
|
|
|
requestID := RequestIDFromContext(params.Request.Context()) |
|
40
|
|
|
host, _, err := net.SplitHostPort(params.Request.RemoteAddr) |
|
41
|
|
|
if err != nil { |
|
42
|
|
|
host = params.Request.RemoteAddr |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
fields := logrus.Fields{ |
|
46
|
|
|
"requestID": requestID, |
|
47
|
|
|
"proto": params.Request.Proto, |
|
48
|
|
|
"method": params.Request.Method, |
|
49
|
|
|
"userAgent": params.Request.UserAgent(), |
|
50
|
|
|
"referrer": params.Request.Referer(), |
|
51
|
|
|
"host": host, |
|
52
|
|
|
"uri": params.URL.RequestURI(), |
|
53
|
|
|
"statusCode": params.StatusCode, |
|
54
|
|
|
"size": params.Size, |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
handler.logger. |
|
58
|
|
|
WithTime(params.TimeStamp). |
|
59
|
|
|
WithFields(fields). |
|
60
|
|
|
Infof("request completed: %s %s", params.Request.Method, params.Request.URL.Path) |
|
61
|
|
|
} |
|
62
|
|
|
|