package server import ( "log/slog" "net/http" "time" ) // Logging returns a middleware that logs each request's method, path, // status code, duration, and request ID using the provided structured logger. func Logging(logger *slog.Logger) Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() sw := &statusWriter{ResponseWriter: w, status: http.StatusOK} next.ServeHTTP(sw, r) duration := time.Since(start) attrs := []slog.Attr{ slog.String("method", r.Method), slog.String("path", r.URL.Path), slog.Int("status", sw.status), slog.Duration("duration", duration), } if id := RequestIDFromContext(r.Context()); id != "" { attrs = append(attrs, slog.String("request_id", id)) } level := slog.LevelInfo if sw.status >= http.StatusInternalServerError { level = slog.LevelError } logger.LogAttrs(r.Context(), level, "request completed", attrs...) }) } }