diff --git a/packages/cli/src/metrics/__tests__/prometheus-metrics.service.test.ts b/packages/cli/src/metrics/__tests__/prometheus-metrics.service.test.ts index 9e5bfb1d31..e6ca160d1f 100644 --- a/packages/cli/src/metrics/__tests__/prometheus-metrics.service.test.ts +++ b/packages/cli/src/metrics/__tests__/prometheus-metrics.service.test.ts @@ -151,6 +151,7 @@ describe('PrometheusMetricsService', () => { await prometheusMetricsService.init(app); expect(promBundle).toHaveBeenCalledWith({ + httpDurationMetricName: 'n8n_http_request_duration_seconds', autoregister: false, includeUp: false, includePath: false, diff --git a/packages/cli/src/metrics/__tests__/prometheus-metrics.service.unmocked.test.ts b/packages/cli/src/metrics/__tests__/prometheus-metrics.service.unmocked.test.ts index a000dfc81e..07e740dbc1 100644 --- a/packages/cli/src/metrics/__tests__/prometheus-metrics.service.unmocked.test.ts +++ b/packages/cli/src/metrics/__tests__/prometheus-metrics.service.unmocked.test.ts @@ -95,22 +95,28 @@ workflow_success_total{workflow_id="1234"} 1" workflowRepository, ); + // ACT await prometheusMetricsService.init(app); - // ACT - const event = new EventMessageWorkflow({ - eventName: 'n8n.workflow.success', - payload: { workflowId: '1234' }, - }); - - eventBus.emit('metrics.eventBus.event', event); - // ASSERT - const versionInfoMetric = promClient.register.getSingleMetric(`${customPrefix}version_info`); - - if (!versionInfoMetric) { - fail(`Could not find a metric called "${customPrefix}version_info"`); - } + // native metric from promClient + const eventLoopLagMetric = await promClient.register.getSingleMetricAsString( + `${customPrefix}nodejs_eventloop_lag_seconds`, + ); + expect(eventLoopLagMetric.split('\n')).toMatchObject([ + '# HELP custom_nodejs_eventloop_lag_seconds Lag of event loop in seconds.', + '# TYPE custom_nodejs_eventloop_lag_seconds gauge', + expect.stringMatching('custom_nodejs_eventloop_lag_seconds .*'), + ]); + // custom metric + const versionMetric = await promClient.register.getSingleMetricAsString( + `${customPrefix}version_info`, + ); + expect(versionMetric.split('\n')).toMatchObject([ + '# HELP custom_version_info n8n version info.', + '# TYPE custom_version_info gauge', + expect.stringMatching('custom_version_info.*'), + ]); }); }); diff --git a/packages/cli/src/metrics/prometheus-metrics.service.ts b/packages/cli/src/metrics/prometheus-metrics.service.ts index 530f37796b..7dc1f46cf5 100644 --- a/packages/cli/src/metrics/prometheus-metrics.service.ts +++ b/packages/cli/src/metrics/prometheus-metrics.service.ts @@ -116,7 +116,7 @@ export class PrometheusMetricsService { private initDefaultMetrics() { if (!this.includes.metrics.default) return; - promClient.collectDefaultMetrics(); + promClient.collectDefaultMetrics({ prefix: this.globalConfig.endpoints.metrics.prefix }); } /** @@ -132,6 +132,7 @@ export class PrometheusMetricsService { includePath: this.includes.labels.apiPath, includeMethod: this.includes.labels.apiMethod, includeStatusCode: this.includes.labels.apiStatusCode, + httpDurationMetricName: this.prefix + 'http_request_duration_seconds', }); const activityGauge = new promClient.Gauge({ @@ -165,25 +166,11 @@ export class PrometheusMetricsService { private mountMetricsEndpoint(app: express.Application) { app.get('/metrics', async (_req: express.Request, res: express.Response) => { const metrics = await promClient.register.metrics(); - const prefixedMetrics = this.addPrefixToMetrics(metrics); res.setHeader('Content-Type', promClient.register.contentType); - res.send(prefixedMetrics).end(); + res.send(metrics).end(); }); } - private addPrefixToMetrics(metrics: string) { - return metrics - .split('\n') - .map((rawLine) => { - const line = rawLine.trim(); - - if (!line || line.startsWith('#') || line.startsWith(this.prefix)) return rawLine; - - return this.prefix + line; - }) - .join('\n'); - } - /** * Set up cache metrics: `n8n_cache_hits_total`, `n8n_cache_misses_total`, and * `n8n_cache_updates_total`