// Package logging emits a single info-level access log entry per HTTP request, // enriched with the active OpenTelemetry trace fields and the resolved request // id when present. package logging import ( "time" "galaxy/backend/internal/server/middleware/requestid" "galaxy/backend/internal/telemetry" "github.com/gin-gonic/gin" "go.uber.org/zap" ) // Middleware returns the access-log gin middleware. The provided logger should // already carry the per-process service-name field; the middleware adds the // request method, matched route, status, latency, request id, and trace // fields. func Middleware(logger *zap.Logger) gin.HandlerFunc { if logger == nil { logger = zap.NewNop() } return func(c *gin.Context) { start := time.Now() c.Next() duration := time.Since(start) fields := make([]zap.Field, 0, 6) fields = append(fields, zap.String("method", c.Request.Method), zap.String("path", c.FullPath()), zap.Int("status", c.Writer.Status()), zap.Duration("duration", duration), ) if requestID, ok := requestid.FromGin(c); ok { fields = append(fields, zap.String("request_id", requestID)) } fields = append(fields, telemetry.TraceFieldsFromContext(c.Request.Context())...) logger.Info("http request", fields...) } }