package metrics import ( "sync" "veza-backend-api/internal/errors" ) // ErrorMetrics collecte et stocke les métriques d'erreurs pour le monitoring type ErrorMetrics struct { mu sync.RWMutex errorsByCode map[errors.ErrorCode]int64 errorsByHTTPStatus map[int]int64 totalErrors int64 aggregated *AggregatedMetrics // Agrégation par fenêtres de temps (T0029) } // NewErrorMetrics crée une nouvelle instance de ErrorMetrics func NewErrorMetrics() *ErrorMetrics { return &ErrorMetrics{ errorsByCode: make(map[errors.ErrorCode]int64), errorsByHTTPStatus: make(map[int]int64), totalErrors: 0, aggregated: NewAggregatedMetrics(), // Initialiser l'agrégation (T0029) } } // RecordError enregistre une erreur dans les métriques func (m *ErrorMetrics) RecordError(code errors.ErrorCode, httpStatus int) { m.mu.Lock() m.errorsByCode[code]++ m.errorsByHTTPStatus[httpStatus]++ m.totalErrors++ m.mu.Unlock() // Enregistrer dans les fenêtres d'agrégation (T0029) if m.aggregated != nil { m.aggregated.AddError("1m", code, httpStatus) m.aggregated.AddError("5m", code, httpStatus) m.aggregated.AddError("1h", code, httpStatus) } } // GetStats retourne les statistiques actuelles des erreurs func (m *ErrorMetrics) GetStats() map[string]interface{} { m.mu.RLock() defer m.mu.RUnlock() return map[string]interface{}{ "total_errors": m.totalErrors, "errors_by_code": m.errorsByCode, "errors_by_http_status": m.errorsByHTTPStatus, } } // Reset réinitialise toutes les métriques (utile pour les tests) func (m *ErrorMetrics) Reset() { m.mu.Lock() defer m.mu.Unlock() m.errorsByCode = make(map[errors.ErrorCode]int64) m.errorsByHTTPStatus = make(map[int]int64) m.totalErrors = 0 // Note: on ne reset pas l'agrégation pour garder l'historique } // GetAggregatedMetrics retourne l'instance AggregatedMetrics func (m *ErrorMetrics) GetAggregatedMetrics() *AggregatedMetrics { return m.aggregated }