fix(core): Fix Message Event Bus Metrics not counting up for labeled metrics (#11396)

This commit is contained in:
Danny Martini 2024-10-25 10:24:39 +02:00 committed by GitHub
parent 8cbe94708e
commit 7fc3b25d21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 113 additions and 2 deletions

View file

@ -14,4 +14,5 @@ module.exports = {
], ],
coveragePathIgnorePatterns: ['/src/databases/migrations/'], coveragePathIgnorePatterns: ['/src/databases/migrations/'],
testTimeout: 10_000, testTimeout: 10_000,
prettierPath: null,
}; };

View file

@ -0,0 +1,109 @@
import { GlobalConfig } from '@n8n/config';
import type express from 'express';
import { mock } from 'jest-mock-extended';
import type { InstanceSettings } from 'n8n-core';
import promClient from 'prom-client';
import { EventMessageWorkflow } from '@/eventbus/event-message-classes/event-message-workflow';
import type { EventService } from '@/events/event.service';
import { mockInstance } from '@test/mocking';
import { MessageEventBus } from '../../eventbus/message-event-bus/message-event-bus';
import { PrometheusMetricsService } from '../prometheus-metrics.service';
jest.unmock('@/eventbus/message-event-bus/message-event-bus');
const customPrefix = 'custom_';
const eventService = mock<EventService>();
const instanceSettings = mock<InstanceSettings>({ instanceType: 'main' });
const app = mock<express.Application>();
const eventBus = new MessageEventBus(
mock(),
mock(),
mock(),
mock(),
mock(),
mock(),
mock(),
mock(),
);
describe('workflow_success_total', () => {
test('support workflow id labels', async () => {
// ARRANGE
const globalConfig = mockInstance(GlobalConfig, {
endpoints: {
metrics: {
prefix: '',
includeMessageEventBusMetrics: true,
includeWorkflowIdLabel: true,
},
},
});
const prometheusMetricsService = new PrometheusMetricsService(
mock(),
eventBus,
globalConfig,
eventService,
instanceSettings,
);
await prometheusMetricsService.init(app);
// ACT
const event = new EventMessageWorkflow({
eventName: 'n8n.workflow.success',
payload: { workflowId: '1234' },
});
eventBus.emit('metrics.eventBus.event', event);
// ASSERT
const workflowSuccessCounter =
await promClient.register.getSingleMetricAsString('workflow_success_total');
expect(workflowSuccessCounter).toMatchInlineSnapshot(`
"# HELP workflow_success_total Total number of n8n.workflow.success events.
# TYPE workflow_success_total counter
workflow_success_total{workflow_id="1234"} 1"
`);
});
test('support a custom prefix', async () => {
// ARRANGE
const globalConfig = mockInstance(GlobalConfig, {
endpoints: {
metrics: {
prefix: customPrefix,
},
},
});
const prometheusMetricsService = new PrometheusMetricsService(
mock(),
eventBus,
globalConfig,
eventService,
instanceSettings,
);
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"`);
}
});
});

View file

@ -211,7 +211,6 @@ export class PrometheusMetricsService {
help: `Total number of ${eventName} events.`, help: `Total number of ${eventName} events.`,
labelNames: Object.keys(labels), labelNames: Object.keys(labels),
}); });
counter.labels(labels).inc(0);
this.counters[eventName] = counter; this.counters[eventName] = counter;
} }
@ -224,7 +223,9 @@ export class PrometheusMetricsService {
this.eventBus.on('metrics.eventBus.event', (event: EventMessageTypes) => { this.eventBus.on('metrics.eventBus.event', (event: EventMessageTypes) => {
const counter = this.toCounter(event); const counter = this.toCounter(event);
if (!counter) return; if (!counter) return;
counter.inc(1);
const labels = this.toLabels(event);
counter.inc(labels, 1);
}); });
} }