From 931ef712505e4997c7e8801af0c3a5f1aa5e5459 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 22 Jan 2026 04:06:58 +0000 Subject: [PATCH] fix: prevent duplicate metric registration error Check if nodejs_eventloop_lag_seconds metric already exists before creating it in SystemMetricsCollector. This prevents conflicts when collectDefaultMetrics from prom-client has already registered metrics with the same name. Added helper functions metricExists() and getExistingMetric() to safely check and retrieve existing metrics from the custom registry. --- src/Utils/prometheus-metrics.ts | 38 +++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/Utils/prometheus-metrics.ts b/src/Utils/prometheus-metrics.ts index 378ce449..3c94b16f 100644 --- a/src/Utils/prometheus-metrics.ts +++ b/src/Utils/prometheus-metrics.ts @@ -95,6 +95,31 @@ export function getConfiguredPrefix(): string { return configuredPrefix } +/** + * Check if a metric with the given name already exists in the custom registry + */ +function metricExists(name: string): boolean { + const fullName = getFullMetricName(name) + try { + const existing = customRegistry.getSingleMetric(fullName) + return existing !== undefined + } catch { + return false + } +} + +/** + * Get an existing metric from the custom registry + */ +function getExistingMetric(name: string): T | undefined { + const fullName = getFullMetricName(name) + try { + return customRegistry.getSingleMetric(fullName) as T | undefined + } catch { + return undefined + } +} + // ============================================ // Configuration // ============================================ @@ -1051,10 +1076,15 @@ export class SystemMetricsCollector { new Gauge('system_load_average', 'System load average', ['period']) ) - // Event loop lag - this.eventLoopLag = registry.register( - new Histogram('nodejs_eventloop_lag_seconds', 'Event loop lag in seconds', [], DEFAULT_LATENCY_BUCKETS) - ) + // Event loop lag - check if already exists (may be created by collectDefaultMetrics) + const existingEventLoopLag = getExistingMetric('nodejs_eventloop_lag_seconds') + if (existingEventLoopLag) { + this.eventLoopLag = existingEventLoopLag + } else { + this.eventLoopLag = registry.register( + new Histogram('nodejs_eventloop_lag_seconds', 'Event loop lag in seconds', [], DEFAULT_LATENCY_BUCKETS) + ) + } // Initialize CPU baseline this.lastCpuUsage = process.cpuUsage()