fix: initialize metrics with labels to show zero values in Prometheus

Metrics with labels only appear in Prometheus output after being
incremented at least once. This fix pre-initializes all labeled metrics
with zero values so they appear in Grafana dashboards immediately,
including buffer_destroyed_total which was showing "No data".
This commit is contained in:
Claude
2026-01-22 15:14:29 +00:00
parent b3917299cd
commit bc7fcca45f
+47
View File
@@ -2104,12 +2104,59 @@ export function getMetricsManager(config?: Partial<MetricsConfig>): PrometheusMe
return globalMetricsManager
}
/**
* Initialize metrics with labels to zero values
* This ensures they appear in Prometheus output even before first increment
*/
function initializeMetricsWithLabels(): void {
try {
// Buffer destroyed metric
metrics.bufferDestroyed?.inc({ reason: 'normal', had_pending_flush: 'true' }, 0)
metrics.bufferDestroyed?.inc({ reason: 'normal', had_pending_flush: 'false' }, 0)
metrics.bufferDestroyed?.inc({ reason: 'error', had_pending_flush: 'true' }, 0)
metrics.bufferDestroyed?.inc({ reason: 'error', had_pending_flush: 'false' }, 0)
// Buffer flushes metric
metrics.bufferFlushes?.inc({ type: 'event', reason: 'normal' }, 0)
metrics.bufferFlushes?.inc({ type: 'event', reason: 'forced' }, 0)
// Connection metrics
metrics.connectionAttempts?.inc({ status: 'success' }, 0)
metrics.connectionAttempts?.inc({ status: 'failure' }, 0)
metrics.connectionErrors?.inc({ error_type: 'timeout' }, 0)
metrics.connectionErrors?.inc({ error_type: 'closed' }, 0)
metrics.connectionErrors?.inc({ error_type: 'unknown' }, 0)
// Message metrics
metrics.messagesSent?.inc({ type: 'text' }, 0)
metrics.messagesSent?.inc({ type: 'media' }, 0)
metrics.messagesSent?.inc({ type: 'other' }, 0)
metrics.messagesReceived?.inc({ type: 'text' }, 0)
metrics.messagesReceived?.inc({ type: 'media' }, 0)
metrics.messagesReceived?.inc({ type: 'notification' }, 0)
metrics.messagesReceived?.inc({ type: 'other' }, 0)
metrics.messageRetries?.inc({ type: 'text' }, 0)
metrics.messageRetries?.inc({ type: 'other' }, 0)
metrics.messageFailures?.inc({ type: 'text', reason: 'max_retries' }, 0)
metrics.messageFailures?.inc({ type: 'other', reason: 'max_retries' }, 0)
// Circuit breaker metric
metrics.circuitBreakerTrips?.inc({ name: 'main' }, 0)
console.log('[Prometheus] Initialized metrics with labels')
} catch (error) {
console.error('[Prometheus] Error initializing metrics with labels:', error)
}
}
/**
* Initialize global metrics (call once at application startup)
*/
export async function initializeMetrics(config?: Partial<MetricsConfig>): Promise<PrometheusMetricsManager> {
const manager = getMetricsManager(config)
await manager.initialize()
// Initialize metrics with labels to zero values
initializeMetricsWithLabels()
return manager
}