-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttp_middleware.go
93 lines (74 loc) · 2.07 KB
/
http_middleware.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
package events
import (
"log/slog"
"net"
"net/http"
"strings"
)
type HTTPMiddleware struct {
next http.Handler
logger *slog.Logger
BuildEvent func(r *http.Request, e *Event)
TrustForwardedFor bool
RequestIDHeaderKey string
RequestLogMessage string
EventLogMessage string
LogRequest func(e *Event)
LogEvent func(e *Event)
}
func NewHTTPMiddleware(next http.Handler, logger *slog.Logger) *HTTPMiddleware {
return &HTTPMiddleware{
next: next,
logger: logger,
BuildEvent: nil,
TrustForwardedFor: true,
RequestIDHeaderKey: "X-Request-Id",
RequestLogMessage: "HTTP request",
EventLogMessage: "Event",
LogRequest: nil,
LogEvent: nil,
}
}
func (m *HTTPMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
e := NewEvent(m.logger)
ctx := NewEventContext(r.Context(), e)
e.SetAttr(AttrProtocol, "http")
e.SetAttr(AttrHTTPMethod, r.Method)
e.SetAttr(AttrHTTPURI, r.RequestURI)
e.SetAttr(AttrHTTPRemoteAddr, r.RemoteAddr)
e.SetAttr(AttrHTTPSourceIP, RequestIP(r, m.TrustForwardedFor))
e.SetAttr(AttrHTTPUserAgent, r.UserAgent())
if requestID := r.Header.Get(m.RequestIDHeaderKey); requestID != "" {
e.SetAttr(AttrRequestID, requestID)
}
if m.BuildEvent != nil {
m.BuildEvent(r, e)
}
if m.LogRequest != nil {
m.LogRequest(e)
} else {
e.Logger().LogAttrs(ctx, slog.LevelDebug, m.RequestLogMessage)
}
r = r.WithContext(ctx)
captureWriter := NewCaptureResponseWriter(w)
m.next.ServeHTTP(captureWriter, r)
e.SetAttr(AttrDuration, captureWriter.Duration())
e.SetAttr(AttrHTTPRespStatus, captureWriter.StatusCode)
e.SetAttr(AttrHTTPRespLen, captureWriter.ResponseLength)
if m.LogEvent != nil {
m.LogEvent(e)
} else {
e.Logger().LogAttrs(r.Context(), slog.LevelInfo, m.EventLogMessage)
}
}
func RequestIP(r *http.Request, trustForwardedFor bool) string {
ip := r.Header.Get("X-Forwarded-For")
if ip != "" && trustForwardedFor {
if strings.ContainsRune(ip, ',') {
ip = strings.Split(ip, ",")[0]
}
} else {
ip, _, _ = net.SplitHostPort(r.RemoteAddr)
}
return ip
}