@@ -35,74 +35,70 @@ func Logger(log slog.Logger) func(next http.Handler) http.Handler {
35
35
slog .F ("start" ,start ),
36
36
)
37
37
38
- logContext := & RequestLoggerContext {
39
- log :& httplog ,
40
- written :false ,
41
- message :r .Method ,
42
- }
43
- defer func () {
44
- logContext .WriteLog (r .Context (),sw .Status )
45
- }()
38
+ logContext := NewRequestLoggerContext (httplog ,r .Method ,start )
46
39
47
40
ctx := context .WithValue (r .Context (),logContextKey {},logContext )
48
41
49
42
next .ServeHTTP (sw ,r .WithContext (ctx ))
50
43
51
- end := time .Now ()
52
-
53
44
// Don't log successful health check requests.
54
45
if r .URL .Path == "/api/v2" && sw .Status == http .StatusOK {
55
46
return
56
47
}
57
48
58
- httplog = httplog .With (
59
- slog .F ("took" ,end .Sub (start )),
60
- slog .F ("status_code" ,sw .Status ),
61
- slog .F ("latency_ms" ,float64 (end .Sub (start )/ time .Millisecond )),
62
- )
63
-
64
- // For status codes 400 and higher we
49
+ // For status codes 500 and higher we
65
50
// want to log the response body.
66
51
if sw .Status >= http .StatusInternalServerError {
67
- httplog = httplog . With (
52
+ logContext . WithFields (
68
53
slog .F ("response_body" ,string (sw .ResponseBody ())),
69
54
)
70
55
}
71
56
72
- // We should not log at level ERROR for 5xx status codes because 5xx
73
- // includes proxy errors etc. It also causes slogtest to fail
74
- // instantly without an error message by default.
75
- logLevelFn := httplog .Debug
76
- if sw .Status >= http .StatusInternalServerError {
77
- logLevelFn = httplog .Warn
78
- }
79
-
80
57
// We already capture most of this information in the span (minus
81
58
// the response body which we don't want to capture anyways).
82
59
tracing .RunWithoutSpan (r .Context (),func (ctx context.Context ) {
83
- logLevelFn (ctx ,r .Method )
60
+ // logLevelFn(ctx, r.Method)
61
+ logContext .WriteLog (r .Context (),sw .Status )
84
62
})
85
63
})
86
64
}
87
65
}
88
66
89
67
type RequestLoggerContext struct {
90
- log * slog.Logger
68
+ log slog.Logger
91
69
written bool
92
70
message string
71
+ start time.Time
72
+ }
73
+
74
+ func NewRequestLoggerContext (log slog.Logger ,message string ,start time.Time )* RequestLoggerContext {
75
+ return & RequestLoggerContext {
76
+ log :log ,
77
+ written :false ,
78
+ message :message ,
79
+ start :start ,
80
+ }
93
81
}
94
82
95
83
func (c * RequestLoggerContext )WithFields (fields ... slog.Field ) {
96
- newLogger := c .log .With (fields ... )
97
- c .log = & newLogger
84
+ c .log = c .log .With (fields ... )
98
85
}
99
86
100
87
func (c * RequestLoggerContext )WriteLog (ctx context.Context ,status int ) {
101
88
if c .written {
102
89
return
103
90
}
104
91
c .written = true
105
-
92
+ end := time .Now ()
93
+
94
+ c .WithFields (
95
+ slog .F ("took" ,end .Sub (c .start )),
96
+ slog .F ("status_code" ,status ),
97
+ slog .F ("latency_ms" ,float64 (end .Sub (c .start )/ time .Millisecond )),
98
+ )
99
+ // We should not log at level ERROR for 5xx status codes because 5xx
100
+ // includes proxy errors etc. It also causes slogtest to fail
101
+ // instantly without an error message by default.
106
102
if status >= http .StatusInternalServerError {
107
103
c .log .Error (ctx ,c .message ,"status_code" ,status )
108
104
}else {