package server import ( "log/slog" "net/http" "time" chimiddleware "github.com/go-chi/chi/v5/middleware" ) // StructuredLogger is a chi-compatible request logger that writes structured // log entries via slog. It replaces chi's default Logger middleware. func StructuredLogger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() ww := chimiddleware.NewWrapResponseWriter(w, r.ProtoMajor) next.ServeHTTP(ww, r) duration := time.Since(start) status := ww.Status() level := slog.LevelInfo if status >= 500 { level = slog.LevelError } else if status >= 400 { level = slog.LevelWarn } attrs := []slog.Attr{ slog.String("method", r.Method), slog.String("path", r.URL.Path), slog.Int("status", status), slog.Duration("duration", duration), slog.Int("bytes", ww.BytesWritten()), } if reqID := chimiddleware.GetReqID(r.Context()); reqID != "" { attrs = append(attrs, slog.String("request_id", reqID)) } if r.URL.RawQuery != "" { attrs = append(attrs, slog.String("query", r.URL.RawQuery)) } slog.LogAttrs(r.Context(), level, "http request", attrs...) }) }