in internal/httplog/roundtripper.go [147:189]
func logRequest(log *slog.Logger, req *http.Request, maxBodyLen int, extra ...slog.Attr) (_ *http.Request, parts []slog.Attr, errorsMessages []string) {
reqParts := append([]slog.Attr{
slog.String("url.original", req.URL.String()),
slog.String("url.scheme", req.URL.Scheme),
slog.String("url.path", req.URL.Path),
slog.String("url.domain", req.URL.Hostname()),
slog.String("url.port", req.URL.Port()),
slog.String("url.query", req.URL.RawQuery),
slog.String("http.request.method", req.Method),
slog.String("user_agent.original", req.Header.Get("User-Agent")),
}, extra...)
var (
body []byte
err error
)
req.Body, body, err = copyBody(req.Body)
if err != nil {
errorsMessages = append(errorsMessages, fmt.Sprintf("failed to read request body: %s", err))
}
reqParts = append(reqParts,
slog.Any("http.request.body.content", byteString(body[:min(len(body), maxBodyLen)])),
slog.Bool("http.request.body.truncated", maxBodyLen < len(body)),
slog.Int("http.request.body.bytes", len(body)),
slog.String("http.request.mime_type", req.Header.Get("Content-Type")),
)
message, err := httputil.DumpRequestOut(req, false)
if err != nil {
errorsMessages = append(errorsMessages, fmt.Sprintf("failed to dump request: %s", err))
} else {
reqParts = append(reqParts, slog.Any("event.original", byteString(message)))
}
switch len(errorsMessages) {
case 0:
case 1:
reqParts = append(reqParts, slog.String("error.message", errorsMessages[0]))
default:
reqParts = append(reqParts, slog.Any("error.message", errorsMessages))
}
log.LogAttrs(context.Background(), slog.LevelInfo, "HTTP request", reqParts...)
return req, reqParts[:0], errorsMessages
}