From 35d9295a91cdbae96708291fdc19721e5d4eaf3f Mon Sep 17 00:00:00 2001 From: Andrei Dobre Date: Sun, 12 Mar 2023 22:04:10 +0100 Subject: [PATCH 1/2] Fix exemplar formating - Fixed improper formating of exemplars - Added snapshot test for exemplars --- CHANGELOG.md | 1 + lib/registry.js | 15 +++---- test/__snapshots__/exemplarsTest.js.snap | 25 +++++++++++ test/__snapshots__/registerTest.js.snap | 13 ++++++ test/exemplarsTest.js | 4 ++ test/registerTest.js | 56 ++++++++++++++++++++---- 6 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 test/__snapshots__/exemplarsTest.js.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index f1218536..3bf01503 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ project adheres to [Semantic Versioning](http://semver.org/). ### Changed +- Fix exemplar formating, improve test suite - Refactor `escapeString` helper in `lib/registry.js` to improve performance and avoid an unnecessarily complex regex. diff --git a/lib/registry.js b/lib/registry.js index 70d4f5ce..4b264874 100644 --- a/lib/registry.js +++ b/lib/registry.js @@ -57,19 +57,18 @@ class Registry { ? `{${formattedLabels.join(',')}}` : ''; - values.push( - `${metricName}${labelsString} ${getValueAsString(val.value)}`, - ); + let fullMetricLine = `${metricName}${labelsString} ${getValueAsString( + val.value, + )}`; const { exemplar } = val; if (exemplar && this.contentType === Registry.OPENMETRICS_CONTENT_TYPE) { const formattedExemplars = formatLabels(exemplar.labelSet); - values.push( - ` # {${formattedExemplars.join(',')}} ${getValueAsString( - exemplar.value, - )} ${exemplar.timestamp}`, - ); + fullMetricLine += ` # {${formattedExemplars.join( + ',', + )}} ${getValueAsString(exemplar.value)} ${exemplar.timestamp}`; } + values.push(fullMetricLine); } return values.join('\n'); diff --git a/test/__snapshots__/exemplarsTest.js.snap b/test/__snapshots__/exemplarsTest.js.snap new file mode 100644 index 00000000..d1229ca1 --- /dev/null +++ b/test/__snapshots__/exemplarsTest.js.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Exemplars with OpenMetrics registry should make histogram with exemplars on multiple buckets 1`] = ` +"# HELP counter_exemplar_test help +# TYPE counter_exemplar_test counter +counter_exemplar_test_total{method="get",code="200"} 2 # {traceId="trace_id_test",spanId="span_id_test"} 2 1678654679 +# HELP histogram_exemplar_test test +# TYPE histogram_exemplar_test histogram +histogram_exemplar_test_bucket{le="0.005",method="get",code="200"} 0 +histogram_exemplar_test_bucket{le="0.01",method="get",code="200"} 1 # {traceId="trace_id_test_1",spanId="span_id_test_1"} 0.007 1678654679 +histogram_exemplar_test_bucket{le="0.025",method="get",code="200"} 1 +histogram_exemplar_test_bucket{le="0.05",method="get",code="200"} 1 +histogram_exemplar_test_bucket{le="0.1",method="get",code="200"} 1 +histogram_exemplar_test_bucket{le="0.25",method="get",code="200"} 1 +histogram_exemplar_test_bucket{le="0.5",method="get",code="200"} 2 # {traceId="trace_id_test_2",spanId="span_id_test_2"} 0.4 1678654679 +histogram_exemplar_test_bucket{le="1",method="get",code="200"} 2 +histogram_exemplar_test_bucket{le="2.5",method="get",code="200"} 2 +histogram_exemplar_test_bucket{le="5",method="get",code="200"} 2 +histogram_exemplar_test_bucket{le="10",method="get",code="200"} 2 +histogram_exemplar_test_bucket{le="+Inf",method="get",code="200"} 3 # {traceId="trace_id_test_3",spanId="span_id_test_3"} 11 1678654679 +histogram_exemplar_test_sum{method="get",code="200"} 11.407 +histogram_exemplar_test_count{method="get",code="200"} 3 +# EOF +" +`; diff --git a/test/__snapshots__/registerTest.js.snap b/test/__snapshots__/registerTest.js.snap index 000b1446..588097d4 100644 --- a/test/__snapshots__/registerTest.js.snap +++ b/test/__snapshots__/registerTest.js.snap @@ -13,6 +13,19 @@ exports[`Register with OpenMetrics type should not output all initialized metric " `; +exports[`Register with OpenMetrics type should not output all initialized metrics at value 0 if labels and exemplars enabled 1`] = ` +"# HELP counter help +# TYPE counter counter +# HELP gauge help +# TYPE gauge gauge +# HELP histogram help +# TYPE histogram histogram +# HELP summary help +# TYPE summary summary +# EOF +" +`; + exports[`Register with OpenMetrics type should output all initialized metrics at value 0 1`] = ` "# HELP counter help # TYPE counter counter diff --git a/test/exemplarsTest.js b/test/exemplarsTest.js index ef5c2254..7396ba57 100644 --- a/test/exemplarsTest.js +++ b/test/exemplarsTest.js @@ -5,6 +5,8 @@ const globalRegistry = require('../index').register; const Histogram = require('../index').Histogram; const Counter = require('../index').Counter; +Date.now = jest.fn(() => 1678654679000); + describe('Exemplars', () => { it('should throw when using with Prometheus registry', async () => { globalRegistry.setContentType(Registry.PROMETHEUS_CONTENT_TYPE); @@ -96,6 +98,8 @@ describe('Exemplars', () => { getValuesByLabel('+Inf', vals)[0].exemplar.labelSet.traceId, ).toEqual('trace_id_test_3'); expect(getValuesByLabel('+Inf', vals)[0].exemplar.value).toEqual(11); + + expect(await globalRegistry.metrics()).toMatchSnapshot(); }); it('should throw if exemplar is too long', async () => { diff --git a/test/registerTest.js b/test/registerTest.js index 1e4623cf..9a956cdb 100644 --- a/test/registerTest.js +++ b/test/registerTest.js @@ -223,24 +223,64 @@ describe('Register', () => { } }); - it('should output all initialized metrics at value 0', async () => { - new Counter({ name: 'counter', help: 'help' }); - new Gauge({ name: 'gauge', help: 'help' }); - new Histogram({ name: 'histogram', help: 'help' }); - new Summary({ name: 'summary', help: 'help' }); + if (regType === Registry.OPENMETRICS_CONTENT_TYPE) { + it('should output all initialized metrics at value 0', async () => { + new Counter({ name: 'counter', help: 'help', enableExemplars: true }); + new Gauge({ name: 'gauge', help: 'help' }); + new Histogram({ + name: 'histogram', + help: 'help', + enableExemplars: true, + }); + new Summary({ name: 'summary', help: 'help' }); - expect(await register.metrics()).toMatchSnapshot(); - }); + expect(await register.metrics()).toMatchSnapshot(); + }); + } else { + it('should output all initialized metrics at value 0', async () => { + new Counter({ name: 'counter', help: 'help' }); + new Gauge({ name: 'gauge', help: 'help' }); + new Histogram({ name: 'histogram', help: 'help' }); + new Summary({ name: 'summary', help: 'help' }); + + expect(await register.metrics()).toMatchSnapshot(); + }); + } it('should not output all initialized metrics at value 0 if labels', async () => { new Counter({ name: 'counter', help: 'help', labelNames: ['label'] }); new Gauge({ name: 'gauge', help: 'help', labelNames: ['label'] }); - new Histogram({ name: 'histogram', help: 'help', labelNames: ['label'] }); + new Histogram({ + name: 'histogram', + help: 'help', + labelNames: ['label'], + }); new Summary({ name: 'summary', help: 'help', labelNames: ['label'] }); expect(await register.metrics()).toMatchSnapshot(); }); + if (regType === Registry.OPENMETRICS_CONTENT_TYPE) { + it('should not output all initialized metrics at value 0 if labels and exemplars enabled', async () => { + new Counter({ + name: 'counter', + help: 'help', + labelNames: ['label'], + enableExemplars: true, + }); + new Gauge({ name: 'gauge', help: 'help', labelNames: ['label'] }); + new Histogram({ + name: 'histogram', + help: 'help', + labelNames: ['label'], + enableExemplars: true, + }); + new Summary({ name: 'summary', help: 'help', labelNames: ['label'] }); + + expect(await register.metrics()).toMatchSnapshot(); + }); + } + describe('should escape', () => { let escapedResult; beforeEach(async () => { From 133b25f02b8180236f3a72468c4147f451d41921 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 13 Mar 2023 08:56:45 +0100 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bf01503..f1218536 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,6 @@ project adheres to [Semantic Versioning](http://semver.org/). ### Changed -- Fix exemplar formating, improve test suite - Refactor `escapeString` helper in `lib/registry.js` to improve performance and avoid an unnecessarily complex regex.