1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-31 13:47:02 +02:00

feat: prefix impact metrics with unleash and type (#10331)

This commit is contained in:
Mateusz Kwasniewski 2025-07-09 09:09:44 +02:00 committed by GitHub
parent 3b6613360c
commit d7be47609d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 25 deletions

View File

@ -111,9 +111,15 @@ test('should store impact metrics in memory and be able to retrieve them', async
const metricsText = response.text; const metricsText = response.text;
expect(metricsText).toContain('# HELP labeled_counter with labels'); expect(metricsText).toContain(
expect(metricsText).toContain('# TYPE labeled_counter counter'); '# HELP unleash_counter_labeled_counter with labels',
expect(metricsText).toMatch(/labeled_counter{foo="bar"} 15/); );
expect(metricsText).toContain(
'# TYPE unleash_counter_labeled_counter counter',
);
expect(metricsText).toMatch(
/unleash_counter_labeled_counter{foo="bar"} 15/,
);
}); });
test('should store impact metrics sent via bulk metrics endpoint', async () => { test('should store impact metrics sent via bulk metrics endpoint', async () => {
@ -155,8 +161,12 @@ test('should store impact metrics sent via bulk metrics endpoint', async () => {
const metricsText = response.text; const metricsText = response.text;
expect(metricsText).toContain( expect(metricsText).toContain(
'# HELP bulk_counter bulk counter with labels', '# HELP unleash_counter_bulk_counter bulk counter with labels',
);
expect(metricsText).toContain(
'# TYPE unleash_counter_bulk_counter counter',
);
expect(metricsText).toMatch(
/unleash_counter_bulk_counter{source="bulk"} 15/,
); );
expect(metricsText).toContain('# TYPE bulk_counter counter');
expect(metricsText).toMatch(/bulk_counter{source="bulk"} 15/);
}); });

View File

@ -32,10 +32,16 @@ describe('MetricsTranslator', () => {
const translator = new MetricsTranslator(registry); const translator = new MetricsTranslator(registry);
const result = await translator.translateAndSerializeMetrics(metrics); const result = await translator.translateAndSerializeMetrics(metrics);
expect(typeof result).toBe('string'); expect(typeof result).toBe('string');
expect(result).toContain('# HELP labeled_counter with labels'); expect(result).toContain(
expect(result).toContain('# TYPE labeled_counter counter'); '# HELP unleash_counter_labeled_counter with labels',
expect(result).toContain('labeled_counter{foo="bar"} 5'); );
expect(result).toContain('test_gauge{env="prod"} 10'); expect(result).toContain(
'# TYPE unleash_counter_labeled_counter counter',
);
expect(result).toContain(
'unleash_counter_labeled_counter{foo="bar"} 5',
);
expect(result).toContain('unleash_gauge_test_gauge{env="prod"} 10');
}); });
it('should ignore unsupported metric types', async () => { it('should ignore unsupported metric types', async () => {
@ -64,10 +70,12 @@ describe('MetricsTranslator', () => {
const translator = new MetricsTranslator(registry); const translator = new MetricsTranslator(registry);
const result = await translator.translateAndSerializeMetrics(metrics); const result = await translator.translateAndSerializeMetrics(metrics);
expect(typeof result).toBe('string'); expect(typeof result).toBe('string');
expect(result).toContain('# HELP test_counter test counter'); expect(result).toContain(
expect(result).toContain('# TYPE test_counter counter'); '# HELP unleash_counter_test_counter test counter',
expect(result).toContain('# HELP test_gauge gauge test'); );
expect(result).toContain('# TYPE test_gauge gauge'); expect(result).toContain('# TYPE unleash_counter_test_counter counter');
expect(result).toContain('# HELP unleash_gauge_test_gauge gauge test');
expect(result).toContain('# TYPE unleash_gauge_test_gauge gauge');
expect(result).not.toContain('unsupported'); expect(result).not.toContain('unsupported');
}); });
@ -101,8 +109,12 @@ describe('MetricsTranslator', () => {
]; ];
const result1 = await translator.translateAndSerializeMetrics(metrics1); const result1 = await translator.translateAndSerializeMetrics(metrics1);
expect(result1).toContain('counter_with_labels{foo="bar"} 5'); expect(result1).toContain(
expect(result1).toContain('gauge_with_labels{env="prod"} 10'); 'unleash_counter_counter_with_labels{foo="bar"} 5',
);
expect(result1).toContain(
'unleash_gauge_gauge_with_labels{env="prod"} 10',
);
const metrics2 = [ const metrics2 = [
{ {
@ -132,10 +144,10 @@ describe('MetricsTranslator', () => {
const result2 = await translator.translateAndSerializeMetrics(metrics2); const result2 = await translator.translateAndSerializeMetrics(metrics2);
expect(result2).toContain( expect(result2).toContain(
'counter_with_labels{foo="bar",baz="qux"} 15', 'unleash_counter_counter_with_labels{foo="bar",baz="qux"} 15',
); );
expect(result2).toContain( expect(result2).toContain(
'gauge_with_labels{env="prod",region="us-east"} 20', 'unleash_gauge_gauge_with_labels{env="prod",region="us-east"} 20',
); );
}); });
}); });

View File

@ -31,7 +31,8 @@ export class MetricsTranslator {
} }
translateMetric(metric: Metric): Counter<string> | Gauge<string> | null { translateMetric(metric: Metric): Counter<string> | Gauge<string> | null {
const existingMetric = this.registry.getSingleMetric(metric.name); const prefixedName = `unleash_${metric.type}_${metric.name}`;
const existingMetric = this.registry.getSingleMetric(prefixedName);
const allLabelNames = new Set<string>(); const allLabelNames = new Set<string>();
for (const sample of metric.samples) { for (const sample of metric.samples) {
@ -48,10 +49,10 @@ export class MetricsTranslator {
if (existingMetric && existingMetric instanceof Counter) { if (existingMetric && existingMetric instanceof Counter) {
if (this.hasNewLabels(existingMetric, labelNames)) { if (this.hasNewLabels(existingMetric, labelNames)) {
this.registry.removeSingleMetric(metric.name); this.registry.removeSingleMetric(prefixedName);
counter = new Counter({ counter = new Counter({
name: metric.name, name: prefixedName,
help: metric.help, help: metric.help,
registers: [this.registry], registers: [this.registry],
labelNames, labelNames,
@ -61,7 +62,7 @@ export class MetricsTranslator {
} }
} else { } else {
counter = new Counter({ counter = new Counter({
name: metric.name, name: prefixedName,
help: metric.help, help: metric.help,
registers: [this.registry], registers: [this.registry],
labelNames, labelNames,
@ -82,10 +83,10 @@ export class MetricsTranslator {
if (existingMetric && existingMetric instanceof Gauge) { if (existingMetric && existingMetric instanceof Gauge) {
if (this.hasNewLabels(existingMetric, labelNames)) { if (this.hasNewLabels(existingMetric, labelNames)) {
this.registry.removeSingleMetric(metric.name); this.registry.removeSingleMetric(prefixedName);
gauge = new Gauge({ gauge = new Gauge({
name: metric.name, name: prefixedName,
help: metric.help, help: metric.help,
registers: [this.registry], registers: [this.registry],
labelNames, labelNames,
@ -95,7 +96,7 @@ export class MetricsTranslator {
} }
} else { } else {
gauge = new Gauge({ gauge = new Gauge({
name: metric.name, name: prefixedName,
help: metric.help, help: metric.help,
registers: [this.registry], registers: [this.registry],
labelNames, labelNames,