package middleware import ( "time" "github.com/gin-gonic/gin" "go.uber.org/zap" "go.uber.org/zap/zapcore" "uzdb/internal/config" ) // LoggerMiddleware returns a logging middleware using Zap func LoggerMiddleware() gin.HandlerFunc { return func(c *gin.Context) { logger := config.GetLogger() // Start timer start := time.Now() // Process request c.Next() // Calculate duration duration := time.Since(start) // Get client IP clientIP := c.ClientIP() // Get method method := c.Request.Method // Get path path := c.Request.URL.Path // Get status code statusCode := c.Writer.Status() // Get body size bodySize := c.Writer.Size() // Determine log level based on status code var level zapcore.Level switch { case statusCode >= 500: level = zapcore.ErrorLevel case statusCode >= 400: level = zapcore.WarnLevel default: level = zapcore.InfoLevel } // Create fields fields := []zap.Field{ zap.Int("status", statusCode), zap.String("method", method), zap.String("path", path), zap.String("ip", clientIP), zap.Duration("duration", duration), zap.Int("body_size", bodySize), } // Add error message if any if len(c.Errors) > 0 { fields = append(fields, zap.String("error", c.Errors.String())) } // Log the request logger.Log(level, "HTTP request", fields...) } } // RequestIDMiddleware adds a request ID to each request func RequestIDMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // Try to get request ID from header requestID := c.GetHeader("X-Request-ID") // Generate if not present if requestID == "" { requestID = generateRequestID() } // Set request ID in context c.Set("request_id", requestID) // Add to response header c.Header("X-Request-ID", requestID) c.Next() } } // generateRequestID generates a simple request ID func generateRequestID() string { return time.Now().Format("20060102150405") + "-" + time.Now().Format("000000.000000")[7:] }