package middleware import ( "log" "net/http" "time" ) // responseWriter wraps http.ResponseWriter to capture status code type responseWriter struct { http.ResponseWriter status int written int64 wroteHeader bool } func (rw *responseWriter) WriteHeader(code int) { if !rw.wroteHeader { rw.status = code rw.ResponseWriter.WriteHeader(code) rw.wroteHeader = true } } func (rw *responseWriter) Write(b []byte) (int, error) { if !rw.wroteHeader { rw.WriteHeader(http.StatusOK) } n, err := rw.ResponseWriter.Write(b) rw.written += int64(n) return n, err } // Logger logs HTTP requests with method, path, status, and duration func Logger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() // Wrap response writer wrapped := &responseWriter{ ResponseWriter: w, status: http.StatusOK, } // Process request next.ServeHTTP(wrapped, r) // Log request duration := time.Since(start) log.Printf( "[%s] %s %s - %d (%v)", r.Method, r.URL.Path, r.RemoteAddr, wrapped.status, duration, ) }) }