veza/veza-backend-api/internal/middleware/monitoring.go

104 lines
2.9 KiB
Go

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),
)
}
}
}