-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlogRequests.go
64 lines (53 loc) · 1.45 KB
/
logRequests.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
//go:build go1.21
package transport
import (
"bytes"
"fmt"
"io"
"net/http"
"time"
"log/slog"
)
type LogOptions struct {
Concise bool
CURL bool
}
func LogRequests(opts LogOptions) func(next http.RoundTripper) http.RoundTripper {
return func(next http.RoundTripper) http.RoundTripper {
return RoundTripFunc(func(req *http.Request) (resp *http.Response, err error) {
ctx := req.Context()
r := CloneRequest(req)
var buf bytes.Buffer
if opts.CURL && r.Body != nil {
r.Body = io.NopCloser(io.TeeReader(r.Body, &buf))
}
slog.LogAttrs(ctx, slog.LevelDebug, fmt.Sprintf("Request: %v %s", r.Method, r.URL.String()))
startTime := time.Now()
defer func() {
level := slog.LevelError
var statusCode int
if resp != nil {
statusCode = resp.StatusCode
if statusCode >= 200 && statusCode < 400 {
level = slog.LevelInfo
}
}
attrs := []slog.Attr{}
if opts.CURL {
attrs = append(attrs, slog.String("curl", curl(r, &buf)))
}
if opts.Concise {
slog.LogAttrs(ctx, level, fmt.Sprintf("Request: %v %s => HTTP %v (%v)", r.Method, r.URL.String(), statusCode, time.Since(startTime)), attrs...)
} else {
attrs = append(attrs,
slog.String("url", r.URL.String()),
slog.Duration("duration", time.Since(startTime)),
slog.Int("status", statusCode),
)
slog.LogAttrs(ctx, level, fmt.Sprintf("Request"), attrs...)
}
}()
return next.RoundTrip(r)
})
}
}