Files
gohoarder/pkg/logger/middleware.go
T
2026-01-02 23:14:23 +00:00

66 lines
1.4 KiB
Go

package logger
import (
"net/http"
"time"
"github.com/lukaszraczylo/gohoarder/pkg/uuid"
"github.com/rs/zerolog/log"
)
// responseWriter wraps http.ResponseWriter to capture status code
type responseWriter struct {
http.ResponseWriter
statusCode int
written int64
}
func (rw *responseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}
func (rw *responseWriter) Write(b []byte) (int, error) {
n, err := rw.ResponseWriter.Write(b)
rw.written += int64(n)
return n, err
}
// Middleware is HTTP middleware for request logging
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Generate request ID
requestID := r.Header.Get("X-Request-ID")
if requestID == "" {
requestID = "req_" + uuid.New().String()[:8]
}
// Wrap response writer
rw := &responseWriter{
ResponseWriter: w,
statusCode: http.StatusOK,
}
// Set request ID in response header
rw.Header().Set("X-Request-ID", requestID)
// Call next handler
next.ServeHTTP(rw, r)
// Log request
duration := time.Since(start)
log.Info().
Str("request_id", requestID).
Str("method", r.Method).
Str("path", r.URL.Path).
Str("remote_addr", r.RemoteAddr).
Str("user_agent", r.UserAgent()).
Int("status", rw.statusCode).
Int64("bytes", rw.written).
Dur("duration_ms", duration).
Msg("HTTP request")
})
}