104 lines
2.9 KiB
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),
|
|
)
|
|
}
|
|
}
|
|
}
|