Files
calculate_negative_points/internal/api/middleware/logging.go
Eugene Howe b0957bfa49
Some checks failed
Docker Build and Publish / publish (push) Failing after 1m33s
webapp
2026-02-17 09:47:30 -05:00

51 lines
1.4 KiB
Go

package middleware
import (
"context"
"encoding/json"
"net/http"
"strings"
"time"
"github.com/go-chi/chi/v5/middleware"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
type ContextKey string
const (
LoggerContext = ContextKey("logger")
)
func LoggingMiddleware(logger *zap.Logger) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
start := time.Now()
defer func() {
if ww.Status() < 300 && strings.HasPrefix(r.URL.Path, "/health") {
// Don't log health checks unless they fail (ping endpoint returns empty response, HTTP status 204).
return
}
var body map[string]interface{}
json.NewDecoder(r.Body).Decode(&body)
fields := []zapcore.Field{
zap.Any("body", r.Body),
zap.String("remote_ip", r.RemoteAddr),
zap.String("method", r.Method),
zap.String("uri", r.URL.Path),
zap.String("request_id", middleware.GetReqID(r.Context())),
zap.Int("status", ww.Status()),
zap.Float64("latency_ms", float64(time.Since(start))/float64(time.Millisecond)),
zap.Int("size", ww.BytesWritten()),
}
logger.Info("HTTP request processed", fields...)
}()
r = r.WithContext(context.WithValue(r.Context(), LoggerContext, logger))
next.ServeHTTP(ww, r)
}
return http.HandlerFunc(fn)
}
}