fix(core): Prometheus metrics can't be ingested by datadog (#15910)

This commit is contained in:
Danny Martini
2025-06-03 11:49:06 +02:00
committed by GitHub
parent 9607908c04
commit d00060adad
3 changed files with 23 additions and 29 deletions

View File

@@ -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,

View File

@@ -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.*'),
]);
});
});

View File

@@ -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`