package httpapi import ( "time" "github.com/gin-gonic/gin" "go.uber.org/zap" ) func requestLogMiddleware(logger *zap.Logger) gin.HandlerFunc { baseLogger := logger if baseLogger == nil { baseLogger = zap.NewNop() } return func(c *gin.Context) { startedAt := time.Now() path := c.Request.URL.Path query := c.Request.URL.RawQuery c.Next() status := c.Writer.Status() latency := time.Since(startedAt) requestID := requestIDFromContext(c) if path == "/v1/health" && status < 400 { return } fields := []zap.Field{ zap.String("requestId", requestID), zap.String("method", c.Request.Method), zap.String("path", path), zap.Int("status", status), zap.Duration("latency", latency), zap.String("clientIP", c.ClientIP()), zap.String("userAgent", c.Request.UserAgent()), zap.Int("responseBytes", c.Writer.Size()), } if query != "" { fields = append(fields, zap.String("query", query)) } if len(c.Errors) > 0 { fields = append(fields, zap.String("errors", c.Errors.String())) } switch { case status >= 500: baseLogger.Error("http request completed with server error", fields...) case status >= 400: baseLogger.Warn("http request completed with client error", fields...) default: baseLogger.Info("http request completed", fields...) } } }