Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb3fb728

Browse files
committed
refactored logging in the logger middleware and added tests for logger
1 parent8fa91e0 commitb3fb728

File tree

2 files changed

+77
-31
lines changed

2 files changed

+77
-31
lines changed

‎coderd/httpmw/logger.go

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,74 +35,70 @@ func Logger(log slog.Logger) func(next http.Handler) http.Handler {
3535
slog.F("start",start),
3636
)
3737

38-
logContext:=&RequestLoggerContext{
39-
log:&httplog,
40-
written:false,
41-
message:r.Method,
42-
}
43-
deferfunc() {
44-
logContext.WriteLog(r.Context(),sw.Status)
45-
}()
38+
logContext:=NewRequestLoggerContext(httplog,r.Method,start)
4639

4740
ctx:=context.WithValue(r.Context(),logContextKey{},logContext)
4841

4942
next.ServeHTTP(sw,r.WithContext(ctx))
5043

51-
end:=time.Now()
52-
5344
// Don't log successful health check requests.
5445
ifr.URL.Path=="/api/v2"&&sw.Status==http.StatusOK {
5546
return
5647
}
5748

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
6550
// want to log the response body.
6651
ifsw.Status>=http.StatusInternalServerError {
67-
httplog=httplog.With(
52+
logContext.WithFields(
6853
slog.F("response_body",string(sw.ResponseBody())),
6954
)
7055
}
7156

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-
ifsw.Status>=http.StatusInternalServerError {
77-
logLevelFn=httplog.Warn
78-
}
79-
8057
// We already capture most of this information in the span (minus
8158
// the response body which we don't want to capture anyways).
8259
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)
8462
})
8563
})
8664
}
8765
}
8866

8967
typeRequestLoggerContextstruct {
90-
log*slog.Logger
68+
log slog.Logger
9169
writtenbool
9270
messagestring
71+
start time.Time
72+
}
73+
74+
funcNewRequestLoggerContext(log slog.Logger,messagestring,start time.Time)*RequestLoggerContext {
75+
return&RequestLoggerContext{
76+
log:log,
77+
written:false,
78+
message:message,
79+
start:start,
80+
}
9381
}
9482

9583
func (c*RequestLoggerContext)WithFields(fields...slog.Field) {
96-
newLogger:=c.log.With(fields...)
97-
c.log=&newLogger
84+
c.log=c.log.With(fields...)
9885
}
9986

10087
func (c*RequestLoggerContext)WriteLog(ctx context.Context,statusint) {
10188
ifc.written {
10289
return
10390
}
10491
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.
106102
ifstatus>=http.StatusInternalServerError {
107103
c.log.Error(ctx,c.message,"status_code",status)
108104
}else {

‎coderd/httpmw/logger_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package httpmw
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"testing"
7+
"time"
8+
9+
"cdr.dev/slog"
10+
"cdr.dev/slog/sloggers/slogtest"
11+
)
12+
13+
funcTestRequestLoggerContext_WriteLog(t*testing.T) {
14+
t.Parallel()
15+
ctx:=context.Background()
16+
17+
testLogger:=slogtest.Make(t,nil)
18+
startTime:=time.Now()
19+
20+
logCtx:=NewRequestLoggerContext(testLogger,"GET",startTime)
21+
22+
// Add custom fields
23+
logCtx.WithFields(
24+
slog.F("custom_field","custom_value"),
25+
)
26+
27+
// Write log for 200 status
28+
logCtx.WriteLog(ctx,http.StatusOK)
29+
30+
if!logCtxWrittenOnce(t,logCtx) {
31+
t.Error("expected log to be written once")
32+
}
33+
// Attempt to write again (should be skipped).
34+
// If the error log entry gets written,
35+
// slogtest will fail the test.
36+
logCtx.WriteLog(ctx,http.StatusInternalServerError)
37+
}
38+
39+
funclogCtxWrittenOnce(t*testing.T,logCtx*RequestLoggerContext)bool {
40+
returnlogCtxWrittenField(t,logCtx)
41+
}
42+
43+
funclogCtxWrittenField(t*testing.T,logCtx*RequestLoggerContext)bool {
44+
logCtxWritten:=logCtx!=nil&&logCtx.written
45+
if!logCtxWritten {
46+
t.Error("log was not marked as written")
47+
returnfalse
48+
}
49+
returntrue
50+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp