veza/veza-backend-api/internal/monitoring/metrics.go
2026-03-05 23:03:43 +01:00

365 lines
9.9 KiB
Go

package monitoring
import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
// Métriques Prometheus custom pour l'application Veza
var (
// HTTP Requests Metrics
HTTPRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_http_requests_total",
Help: "Total number of HTTP requests",
},
[]string{"method", "endpoint", "status"},
)
HTTPRequestDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Name: "veza_http_request_duration_seconds",
Help: "HTTP request duration in seconds",
Buckets: []float64{0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0},
},
[]string{"method", "endpoint"},
)
// Authentication Metrics
AuthLoginAttempts = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_auth_login_attempts_total",
Help: "Total number of login attempts",
},
[]string{"success"},
)
AuthSessionActive = promauto.NewGauge(
prometheus.GaugeOpts{
Name: "veza_auth_sessions_active",
Help: "Number of active sessions",
},
)
// Database Metrics
DatabaseQueryDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Name: "veza_database_query_duration_seconds",
Help: "Database query duration in seconds",
Buckets: []float64{0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0},
},
[]string{"operation", "table"},
)
DatabaseConnectionsActive = promauto.NewGauge(
prometheus.GaugeOpts{
Name: "veza_database_connections_active",
Help: "Number of active database connections",
},
)
DatabaseQueryErrors = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_database_query_errors_total",
Help: "Total number of database query errors",
},
[]string{"operation", "error_type"},
)
// File Upload Metrics
FileUploadsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_file_uploads_total",
Help: "Total number of file uploads",
},
[]string{"type", "status"},
)
FileUploadSize = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Name: "veza_file_upload_size_bytes",
Help: "File upload size in bytes",
Buckets: prometheus.ExponentialBuckets(1024, 2, 15), // 1KB to 32MB
},
[]string{"type"},
)
// Rate Limiting Metrics
RateLimitHitsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_rate_limit_hits_total",
Help: "Total number of rate limit hits",
},
[]string{"endpoint", "limit_type"},
)
// Active Users Metrics
ActiveUsers = promauto.NewGauge(
prometheus.GaugeOpts{
Name: "veza_active_users",
Help: "Number of active users",
},
)
// WebSocket Metrics
WebSocketConnectionsActive = promauto.NewGauge(
prometheus.GaugeOpts{
Name: "veza_websocket_connections_active",
Help: "Number of active WebSocket connections",
},
)
WebSocketMessagesTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_websocket_messages_total",
Help: "Total number of WebSocket messages",
},
[]string{"type", "status"},
)
// Cache Metrics
CacheHitsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_cache_hits_total",
Help: "Total number of cache hits",
},
[]string{"cache_type"},
)
CacheMissesTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_cache_misses_total",
Help: "Total number of cache misses",
},
[]string{"cache_type"},
)
// Error Metrics
ErrorsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_errors_total",
Help: "Total number of errors",
},
[]string{"type", "severity"},
)
// Health Check Metrics
HealthCheckDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Name: "veza_health_check_duration_ms",
Help: "Health check duration in milliseconds",
Buckets: []float64{1, 5, 10, 25, 50, 100, 250, 500, 1000},
},
[]string{"service"}, // database, redis, chat_server, stream_server
)
HealthCheckStatus = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Name: "veza_health_check_status",
Help: "Health check status (1=ok, 0.5=slow, 0=error)",
},
[]string{"service"},
)
// MOD-P2-003: Business Metrics
TracksUploadedTotal = promauto.NewCounter(
prometheus.CounterOpts{
Name: "veza_tracks_uploaded_total",
Help: "Total number of tracks uploaded",
},
)
// v0.602 INF2: Commerce Metrics
CommerceOrdersTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_commerce_orders_total",
Help: "Total number of commerce orders created",
},
[]string{"status"},
)
CommerceCheckoutDuration = promauto.NewHistogram(
prometheus.HistogramOpts{
Name: "veza_commerce_checkout_duration_seconds",
Help: "Checkout (cart to order) duration in seconds",
Buckets: []float64{0.1, 0.25, 0.5, 1.0, 2.0, 5.0},
},
)
UsersRegisteredTotal = promauto.NewCounter(
prometheus.CounterOpts{
Name: "veza_users_registered_total",
Help: "Total number of users registered",
},
)
PlaylistsCreatedTotal = promauto.NewCounter(
prometheus.CounterOpts{
Name: "veza_playlists_created_total",
Help: "Total number of playlists created",
},
)
UploadsFailedTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "veza_uploads_failed_total",
Help: "Total number of failed uploads",
},
[]string{"reason"}, // ClamAV, validation, quota, etc.
)
// v0.701: Transfer Retry Metrics
TransferRetryTotal = promauto.NewCounter(prometheus.CounterOpts{
Name: "veza_transfer_retry_total",
Help: "Total number of transfer retry attempts",
})
TransferRetrySuccess = promauto.NewCounter(prometheus.CounterOpts{
Name: "veza_transfer_retry_success_total",
Help: "Total number of successful transfer retries",
})
TransferRetryFailures = promauto.NewCounter(prometheus.CounterOpts{
Name: "veza_transfer_retry_failures_total",
Help: "Total number of failed transfer retries",
})
TransferRetryPermanent = promauto.NewCounter(prometheus.CounterOpts{
Name: "veza_transfer_retry_permanent_failures_total",
Help: "Total number of permanently failed transfers (max retries exceeded)",
})
// v0.703: Live Streaming Metrics
LiveStreamsActive = promauto.NewGauge(prometheus.GaugeOpts{
Name: "veza_live_streams_active",
Help: "Number of currently active live streams",
})
LiveStreamViewersTotal = promauto.NewGauge(prometheus.GaugeOpts{
Name: "veza_live_stream_viewers_total",
Help: "Total number of viewers across all active live streams",
})
)
// Middleware pour enregistrer les métriques HTTP
func HTTPMetricsMiddleware(endpoint string, duration time.Duration, statusCode int, method string) {
status := string(rune(statusCode / 100)) // '2', '4', '5'
HTTPRequestsTotal.WithLabelValues(method, endpoint, status).Inc()
HTTPRequestDuration.WithLabelValues(method, endpoint).Observe(duration.Seconds())
}
// Enregistrer une tentative de login
func RecordLoginAttempt(success bool) {
status := "failure"
if success {
status = "success"
}
AuthLoginAttempts.WithLabelValues(status).Inc()
}
// Mettre à jour le nombre de sessions actives
func UpdateActiveSessions(count int) {
AuthSessionActive.Set(float64(count))
}
// Enregistrer une requête database
func RecordDatabaseQuery(operation, table string, duration time.Duration) {
DatabaseQueryDuration.WithLabelValues(operation, table).Observe(duration.Seconds())
}
// Enregistrer une erreur de database
func RecordDatabaseError(operation, errorType string) {
DatabaseQueryErrors.WithLabelValues(operation, errorType).Inc()
}
// Enregistrer un upload de fichier
func RecordFileUpload(fileType, status string, sizeBytes int64) {
FileUploadsTotal.WithLabelValues(fileType, status).Inc()
FileUploadSize.WithLabelValues(fileType).Observe(float64(sizeBytes))
}
// Enregistrer un hit de rate limit
func RecordRateLimitHit(endpoint, limitType string) {
RateLimitHitsTotal.WithLabelValues(endpoint, limitType).Inc()
}
// Mettre à jour le nombre d'utilisateurs actifs
func UpdateActiveUsers(count int) {
ActiveUsers.Set(float64(count))
}
// Enregistrer une connexion WebSocket
func UpdateWebSocketConnections(count int) {
WebSocketConnectionsActive.Set(float64(count))
}
// Enregistrer un message WebSocket
func RecordWebSocketMessage(messageType, status string) {
WebSocketMessagesTotal.WithLabelValues(messageType, status).Inc()
}
// Enregistrer un cache hit
func RecordCacheHit(cacheType string) {
CacheHitsTotal.WithLabelValues(cacheType).Inc()
}
// Enregistrer un cache miss
func RecordCacheMiss(cacheType string) {
CacheMissesTotal.WithLabelValues(cacheType).Inc()
}
// Enregistrer une erreur
func RecordError(errorType, severity string) {
ErrorsTotal.WithLabelValues(errorType, severity).Inc()
}
// Enregistrer un health check
func RecordHealthCheck(service string, durationMs float64, status string) {
HealthCheckDuration.WithLabelValues(service).Observe(durationMs)
// Convertir le status en valeur numérique pour la gauge
var statusValue float64
switch status {
case "ok":
statusValue = 1.0
case "slow":
statusValue = 0.5
case "error":
statusValue = 0.0
default:
statusValue = 0.0
}
HealthCheckStatus.WithLabelValues(service).Set(statusValue)
}
// MOD-P2-003: Business Metrics Functions
// RecordTrackUploaded incrémente le compteur de tracks uploadés
func RecordTrackUploaded() {
TracksUploadedTotal.Inc()
}
// RecordUserRegistered incrémente le compteur d'utilisateurs enregistrés
func RecordUserRegistered() {
UsersRegisteredTotal.Inc()
}
// RecordPlaylistCreated incrémente le compteur de playlists créées
func RecordPlaylistCreated() {
PlaylistsCreatedTotal.Inc()
}
// RecordUploadFailed enregistre un échec d'upload avec la raison
func RecordUploadFailed(reason string) {
UploadsFailedTotal.WithLabelValues(reason).Inc()
}
// v0.701: Transfer Retry Metrics
func RecordTransferRetry() { TransferRetryTotal.Inc() }
func RecordTransferRetrySuccess() { TransferRetrySuccess.Inc() }
func RecordTransferRetryFailure() { TransferRetryFailures.Inc() }
func RecordTransferRetryPermanent() { TransferRetryPermanent.Inc() }