package middleware import ( "net/http" "time" "veza-backend-api/internal/services" "github.com/gin-gonic/gin" "go.uber.org/zap" ) // INT-021: APIMonitoringMiddleware tracks API health and triggers alerts on failures // This middleware monitors request failures, response times, and error rates func APIMonitoringMiddleware(logger *zap.Logger, monitoringService *services.MonitoringAlertingService) gin.HandlerFunc { if monitoringService == nil { // If monitoring service is not available, return a no-op middleware return func(c *gin.Context) { c.Next() } } return func(c *gin.Context) { startTime := time.Now() // Process request c.Next() // Calculate request duration duration := time.Since(startTime) statusCode := c.Writer.Status() // INT-021: Track API failures and trigger alerts // Monitor 5xx errors (server errors) if statusCode >= http.StatusInternalServerError { logger.Warn("API failure detected", zap.String("method", c.Request.Method), zap.String("path", c.Request.URL.Path), zap.Int("status_code", statusCode), zap.Duration("duration", duration), zap.String("client_ip", c.ClientIP()), ) // Track failure in monitoring service // This will be used by alert rules to detect high error rates // The actual alerting is handled by Prometheus queries in MonitoringAlertingService } // INT-021: Track slow requests (potential performance issues) if duration > 1*time.Second { logger.Warn("Slow API request detected", zap.String("method", c.Request.Method), zap.String("path", c.Request.URL.Path), zap.Int("status_code", statusCode), zap.Duration("duration", duration), ) } // INT-021: Track timeouts (requests taking too long) if duration > 30*time.Second { logger.Error("API request timeout", zap.String("method", c.Request.Method), zap.String("path", c.Request.URL.Path), zap.Int("status_code", statusCode), zap.Duration("duration", duration), ) } } } // INT-021: HealthCheckMonitoring tracks health check failures // This is a specialized middleware for health check endpoints func HealthCheckMonitoring(logger *zap.Logger, monitoringService *services.MonitoringAlertingService) gin.HandlerFunc { if monitoringService == nil { return func(c *gin.Context) { c.Next() } } return func(c *gin.Context) { startTime := time.Now() c.Next() statusCode := c.Writer.Status() duration := time.Since(startTime) // INT-021: Alert on health check failures if statusCode != http.StatusOK { logger.Error("Health check failed", zap.String("path", c.Request.URL.Path), zap.Int("status_code", statusCode), zap.Duration("duration", duration), ) } // INT-021: Alert on slow health checks if duration > 5*time.Second { logger.Warn("Health check slow", zap.String("path", c.Request.URL.Path), zap.Duration("duration", duration), ) } } }