diff --git a/src/prometheus.ts b/src/prometheus.ts index 798036f..e86371a 100644 --- a/src/prometheus.ts +++ b/src/prometheus.ts @@ -13,14 +13,16 @@ export class MetricsRenderer { } render(metrics: Metric[]): string { - return Object.entries(metrics.sort().group((metric) => this.metricName(metric.name))) - .map(([name, metrics]) => { - return [ - `# TYPE ${name} ${name.endsWith('_total') ? 'counter' : 'gauge'}`, - metrics.map((metric) => this.formatMetric(metric)).join('\n'), - ].join('\n') - }) - .join('\n\n') + return ( + Object.entries(metrics.sort().group((metric) => this.metricName(metric.name))) + .map(([name, metrics]) => { + return [ + `# TYPE ${name} ${name.endsWith('_total') ? 'counter' : 'gauge'}`, + metrics.map((metric) => this.formatMetric(metric)).join('\n'), + ].join('\n') + }) + .join('\n\n') + '\n' + ) } private formatMetric(metric: Metric): string { diff --git a/tests/adapters/http/fastify.test.ts b/tests/adapters/http/fastify.test.ts index df3beaa..d94f5b3 100644 --- a/tests/adapters/http/fastify.test.ts +++ b/tests/adapters/http/fastify.test.ts @@ -74,6 +74,7 @@ describe('Fastify HTTP adapter', () => { '', '# TYPE homebridge_something_total counter', 'homebridge_something_total{name="counter"} 100 1577836800000', + '', ].join('\n'), ) }) @@ -121,6 +122,7 @@ describe('Fastify HTTP adapter', () => { '', '# TYPE homebridge_something_total counter', 'homebridge_something_total{name="counter"} 100 1577836800000', + '', ].join('\n'), ) }) diff --git a/tests/prometheus.test.ts b/tests/prometheus.test.ts index 0ff6c9c..33d48b7 100644 --- a/tests/prometheus.test.ts +++ b/tests/prometheus.test.ts @@ -8,14 +8,16 @@ describe('Render prometheus metrics', () => { test('Renders simple metric', () => { expect(renderer.render([new Metric('metric', 0.000001)])).toEqual( `# TYPE prefix_metric gauge -prefix_metric 0.000001`, +prefix_metric 0.000001 +`, ) }) test('Renders simple metric with timestamp', () => { expect(renderer.render([new Metric('metric', 0.000001, new Date('2000-01-01 00:00:00 UTC'))])).toEqual( `# TYPE prefix_metric gauge -prefix_metric 0.000001 946684800000`, +prefix_metric 0.000001 946684800000 +`, ) }) @@ -26,7 +28,8 @@ prefix_metric 0.000001 946684800000`, ]), ).toEqual( `# TYPE prefix_metric gauge -prefix_metric{label="Some Label"} 0.000001 946684800000`, +prefix_metric{label="Some Label"} 0.000001 946684800000 +`, ) }) @@ -38,7 +41,8 @@ prefix_metric{label="Some Label"} 0.000001 946684800000`, ]), ).toEqual( `# TYPE prefix_some_metric_total counter -prefix_some_metric_total{label="Some Label"} 42 946684800000`, +prefix_some_metric_total{label="Some Label"} 42 946684800000 +`, ) } }) @@ -56,35 +60,40 @@ prefix_some_gauge 10 946684800000 prefix_some_gauge 20 946684800000 # TYPE prefix_another_gauge gauge -prefix_another_gauge 30 946684800000`, +prefix_another_gauge 30 946684800000 +`, ) }) test('Sanitizes metric names', () => { expect(renderer.render([new Metric('mätric name', 0)])).toEqual( `# TYPE prefix_m_tric_name gauge -prefix_m_tric_name 0`, +prefix_m_tric_name 0 +`, ) }) test('Sanitizes label names', () => { expect(renderer.render([new Metric('metric', 0, null, { 'yet another label': 'foo' })])).toEqual( `# TYPE prefix_metric gauge -prefix_metric{yet_another_label="foo"} 0`, +prefix_metric{yet_another_label="foo"} 0 +`, ) }) test('Escapes newlines in attribute value', () => { expect(renderer.render([new Metric('metric', 0, null, { label: 'foo\nbar' })])).toEqual( `# TYPE prefix_metric gauge -prefix_metric{label="foo\\nbar"} 0`, +prefix_metric{label="foo\\nbar"} 0 +`, ) }) test('Escapes quotes in attribute value', () => { expect(renderer.render([new Metric('metric', 0, null, { label: 'foo"bar' })])).toEqual( `# TYPE prefix_metric gauge -prefix_metric{label="foo\\"bar"} 0`, +prefix_metric{label="foo\\"bar"} 0 +`, ) }) })