@@ -40,47 +40,68 @@ type Options struct {
40
40
// slog.LevelInfo - log responses (excl. OPTIONS)
41
41
// slog.LevelWarn - log 4xx and 5xx responses only (except for 429)
42
42
// slog.LevelError - log 5xx responses only
43
+ //
44
+ // Use httplog.SetLevel(ctx, slog.DebugLevel) to override the level per-request.
43
45
Level slog.Level
44
46
45
47
// Concise mode causes fewer log attributes to be printed in request logs.
46
48
// This is useful if your console is too noisy during development.
47
49
Concise bool
48
50
49
51
// RecoverPanics recovers from panics occurring in the underlying HTTP handlers
50
- // and middlewares. It returns HTTP 500 unless response status was already set.
52
+ // and middlewares and returns HTTP 500 unless response status was already set.
51
53
//
52
- // NOTE: The request logger logs all panics automatically, regardless of this setting.
54
+ // NOTE: Panics are logged as errors automatically, regardless of this setting.
53
55
RecoverPanics bool
54
56
55
57
// LogRequestHeaders is an explicit list of headers to be logged as attributes.
58
+ // If not provided, the default headers are User-Agent, Referer and Origin.
56
59
LogRequestHeaders []string
57
60
58
61
// LogRequestBody enables logging of request body into a response log attribute.
62
+ //
63
+ // Use httplog.LogRequestBody(ctx) to enable on per-request basis instead.
59
64
LogRequestBody bool
60
65
66
+ // LogRequestCURL enables logging of request body incl. all headers as a CURL command.
67
+ //
68
+ // Use httplog.LogRequestCURL(ctx) to enable on per-request basis instead.
69
+ LogRequestCURL bool
70
+
61
71
// LogResponseHeaders is an explicit list of headers to be logged as attributes.
72
+ //
73
+ // If not provided, there are no default headers.
62
74
LogResponseHeaders []string
63
75
64
76
// LogResponseBody enables logging of response body into a response log attribute.
77
+ // The Content-Type of the response must match.
78
+ //
79
+ // Use httplog.LogResponseBody(ctx) to enable on per-request basis instead.
65
80
LogResponseBody bool
81
+
82
+ // LogResponseBodyContentType defines list of Content-Types for which LogResponseBody is enabled.
83
+ //
84
+ // If not provided, the default list is application/json and text/plain.
85
+ LogResponseBodyContentType []string
66
86
}
67
87
68
88
var defaultOptions = Options {
69
- Level : slog .LevelInfo ,
70
- Concise : false ,
71
- RecoverPanics : true ,
72
- LogRequestHeaders : []string {"User-Agent" , "Referer" , "Origin " },
73
- LogResponseHeaders : []string {"" },
89
+ Level : slog .LevelInfo ,
90
+ RecoverPanics : true ,
91
+ LogRequestHeaders : [] string { "User-Agent" , "Referer" , "Origin" } ,
92
+ LogResponseHeaders : []string {"" },
93
+ LogResponseBodyContentType : []string {"application/json" , "text/plain " },
74
94
}
75
95
76
96
func (l * Logger ) Handle (next http.Handler ) http.Handler {
77
97
return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
78
98
ctx := r .Context ()
79
99
80
- log := & Log {
100
+ log := & log {
81
101
Level : l .opts .Level ,
82
102
Req : r ,
83
- LogRequestBody : l .opts .LogRequestBody ,
103
+ LogRequestCURL : l .opts .LogRequestCURL ,
104
+ LogRequestBody : l .opts .LogRequestBody || l .opts .LogRequestCURL ,
84
105
LogResponseBody : l .opts .LogResponseBody ,
85
106
}
86
107
@@ -121,7 +142,7 @@ func (l *Logger) Handle(next http.Handler) http.Handler {
121
142
122
143
status := ww .Status ()
123
144
124
- log .Resp = & ResponseLog {
145
+ log .Resp = & respLog {
125
146
Header : w .Header ,
126
147
Duration : time .Since (start ),
127
148
}
@@ -153,24 +174,27 @@ func (l *Logger) Handle(next http.Handler) http.Handler {
153
174
})
154
175
}
155
176
156
- type Log struct {
157
- Level slog.Level // Use httplog.SetLevel(ctx, slog.DebugLevel) to override level
158
- Attrs []slog.Attr // Use httplog.SetAttrs(ctx, slog.String("key", "value")) to append
159
- LogRequestBody bool // Use httplog.LogRequestBody(ctx) to force-enable
160
- LogResponseBody bool // Use httplog.LogResponseBody(ctx) to force-enable
177
+ type log struct {
178
+ Level slog.Level
179
+ Attrs []slog.Attr
180
+ LogRequestCURL bool
181
+ LogRequestBody bool
182
+ LogResponseBody bool
161
183
162
- // Fields automatically set by httplog.RequestLogger middleware:
184
+ // Fields set by httplog.RequestLogger middleware:
163
185
Req * http.Request
164
186
ReqBody bytes.Buffer
165
187
ReqBodyFullyRead bool
166
188
WW middleware.WrapResponseWriter
167
- Resp * ResponseLog
189
+ Resp * respLog
168
190
RespBody bytes.Buffer
169
191
Panic any
170
192
PanicPC []uintptr
193
+
194
+ // Fields internal to httplog:
171
195
}
172
196
173
- type ResponseLog struct {
197
+ type respLog struct {
174
198
Header func () http.Header
175
199
Duration time.Duration
176
200
}
0 commit comments