From f9ed1dc16f308465ea206f0d2fbcf053066e3bf6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 22 Jan 2026 13:57:34 +0000 Subject: [PATCH] feat: add adaptive metrics and circuit breaker trips tracking Added metrics tracking for: - circuit_breaker_trips_total: Incremented when circuit opens - adaptive_health_status: 1 if healthy (not in aggressive mode), 0 otherwise - adaptive_event_rate: Current events per second Added methods to AdaptiveTimeoutCalculator: - getEventRate(): Returns current event rate in events/second - isHealthy(): Returns true if not in aggressive mode Metrics are updated on each buffer flush when adaptive timeout is enabled. --- src/Utils/circuit-breaker.ts | 5 +++++ src/Utils/event-buffer.ts | 30 ++++++++++++++++++++++++++++++ src/Utils/prometheus-metrics.ts | 13 +++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/Utils/circuit-breaker.ts b/src/Utils/circuit-breaker.ts index fc20e135..143f0729 100644 --- a/src/Utils/circuit-breaker.ts +++ b/src/Utils/circuit-breaker.ts @@ -380,6 +380,11 @@ export class CircuitBreaker extends EventEmitter { this.options.onOpen() this.emit('open') + // Record circuit breaker trip metric + if (this.options.collectMetrics) { + metrics.circuitBreakerTrips?.inc({ name: this.options.name }) + } + // Schedule transition to HALF_OPEN this.resetTimer = setTimeout(() => { this.transitionTo('half-open') diff --git a/src/Utils/event-buffer.ts b/src/Utils/event-buffer.ts index c5f67c1b..64aec7b2 100644 --- a/src/Utils/event-buffer.ts +++ b/src/Utils/event-buffer.ts @@ -329,6 +329,31 @@ class AdaptiveTimeoutCalculator { } return 'balanced' } + + /** + * Get current event rate in events per second + */ + getEventRate(): number { + if (this.eventTimestamps.length < 2) { + return 0 + } + const oldest = this.eventTimestamps[0]! + const newest = this.eventTimestamps[this.eventTimestamps.length - 1]! + const timeSpan = newest - oldest + if (timeSpan === 0) return 0 + return (this.eventTimestamps.length / timeSpan) * 1000 + } + + /** + * Check if system is healthy based on current mode + * Conservative mode with low event rate is healthy + * Aggressive mode might indicate high load + */ + isHealthy(): boolean { + const mode = this.getMode() + // System is considered healthy if not in aggressive mode (high load) + return mode !== 'aggressive' + } } // ============================================================================ @@ -563,6 +588,11 @@ export const makeEventBuffer = ( // Record metrics recordFlushMetrics(eventCount, force, historyCache.size) + // Update adaptive metrics + if (config.enableAdaptiveTimeout && metricsModule) { + metricsModule.updateAdaptiveMetrics(adaptiveTimeout.getEventRate(), adaptiveTimeout.isHealthy()) + } + // Log with [BAILEYS] prefix - use getMode() to avoid duplicating mode calculation logic const flushDuration = Date.now() - flushStartTime logEventBuffer('buffer_flush', { diff --git a/src/Utils/prometheus-metrics.ts b/src/Utils/prometheus-metrics.ts index 7eadbf3d..85b1bec1 100644 --- a/src/Utils/prometheus-metrics.ts +++ b/src/Utils/prometheus-metrics.ts @@ -1958,6 +1958,19 @@ export function recordBufferFinalFlush(): void { } } +/** + * Update adaptive system metrics + * Used by event-buffer.ts to report adaptive timeout health and event rate + */ +export function updateAdaptiveMetrics(eventRate: number, isHealthy: boolean): void { + try { + metrics.adaptiveEventRate?.set({}, eventRate) + metrics.adaptiveHealthStatus?.set({}, isHealthy ? 1 : 0) + } catch { + // Metrics not initialized, ignore silently + } +} + // ============================================ // Global Instance // ============================================