|
- package middleware
-
- import (
- "log/slog"
- "net/http"
- "time"
- )
-
- // responseWriter wraps http.ResponseWriter to capture status and bytes written.
- type responseWriter struct {
- http.ResponseWriter
- status int
- bytes int
- }
-
- func (rw *responseWriter) WriteHeader(code int) {
- rw.status = code
- rw.ResponseWriter.WriteHeader(code)
- }
-
- func (rw *responseWriter) Write(b []byte) (int, error) {
- n, err := rw.ResponseWriter.Write(b)
- rw.bytes += n
- return n, err
- }
-
- // Logging logs each request with method, path, status, duration, and bytes written.
- func Logging(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- start := time.Now()
- wrap := &responseWriter{ResponseWriter: w, status: http.StatusOK}
- next.ServeHTTP(wrap, r)
- slog.Info("request",
- "method", r.Method,
- "path", r.URL.Path,
- "status", wrap.status,
- "duration_ms", time.Since(start).Milliseconds(),
- "bytes", wrap.bytes,
- )
- })
- }
|