diff --git a/CHANGELOG.md b/CHANGELOG.md index de63ceba..e83676c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,9 +15,8 @@ project adheres to [Semantic Versioning](http://semver.org/). - Organized default metrics - perf: Histogram rendering builds its export list straight from the store iterator instead of an intermediate array. Faster at high series counts on Node 24 and 26, can be slightly slower on Node 22 - fix: Correct content type exported for cluster and worker mode. -- perf: Remove truthy conditionals from default metric collectors +- perf: Remove truthy conditionals from the codebase - fix: Preserve zero-valued Counter exemplars -- perf: Remove object and array fallback truthiness from core metric paths ### Added diff --git a/lib/cluster.js b/lib/cluster.js index b3b04004..91a3089c 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -347,7 +347,7 @@ async function primaryListener(worker, event) { } request.responseHandlers.delete(worker.id); - if (event.error) { + if (event.error !== undefined) { response.reject(new Error(event.error)); } else { response.resolve({ @@ -409,8 +409,7 @@ function scanListeners(messageType, emitter, fn) { const functionString = fn.toString(); for (const listener of emitter.listeners(messageType)) { - // eslint-disable-next-line eqeqeq - if (functionString == listener) { + if (functionString === `${listener}`) { if (['test', 'development'].includes(process.env.NODE_ENV)) { debug('removing duplicate listener', messageType); emitter.off(messageType, listener); diff --git a/lib/counter.js b/lib/counter.js index bead1e25..3ab5e662 100644 --- a/lib/counter.js +++ b/lib/counter.js @@ -109,7 +109,7 @@ class Counter extends Metric { } async get() { - if (this.collect) { + if (this.collect !== undefined) { const v = this.collect(); if (v instanceof Promise) await v; } diff --git a/lib/gauge.js b/lib/gauge.js index 789f620e..9f6d97ba 100644 --- a/lib/gauge.js +++ b/lib/gauge.js @@ -110,7 +110,7 @@ class Gauge extends Metric { } async get() { - if (this.collect) { + if (this.collect !== undefined) { const v = this.collect(); if (v instanceof Promise) await v; } diff --git a/lib/histogram.js b/lib/histogram.js index ee1f8ae5..5b8d28a9 100644 --- a/lib/histogram.js +++ b/lib/histogram.js @@ -116,7 +116,7 @@ class Histogram extends Metric { } async getForPromString() { - if (this.collect) { + if (this.collect !== undefined) { const v = this.collect(); if (v instanceof Promise) await v; } diff --git a/lib/metric.js b/lib/metric.js index 0c519de0..1b2e7b2e 100644 --- a/lib/metric.js +++ b/lib/metric.js @@ -37,10 +37,10 @@ class Metric { defaults, config, ); - if (!this.registers) { - // in case config.registers is `undefined` - this.registers = [Registry.globalRegistry]; - } + + // in case config.registers is `undefined` + this.registers ??= [Registry.globalRegistry]; + if (!this.help) { throw new Error('Missing mandatory help parameter'); } diff --git a/lib/pushgateway.js b/lib/pushgateway.js index f43487b4..cd40b5cc 100644 --- a/lib/pushgateway.js +++ b/lib/pushgateway.js @@ -108,10 +108,7 @@ async function useGateway(method, job, groupings) { this.registry .metrics() .then(metrics => { - if ( - options.headers && - options.headers['Content-Encoding'] === 'gzip' - ) { + if (options.headers?.['Content-Encoding'] === 'gzip') { metrics = gzipSync(metrics); } req.write(metrics); diff --git a/lib/registry.js b/lib/registry.js index 38f3903b..508640db 100644 --- a/lib/registry.js +++ b/lib/registry.js @@ -110,12 +110,12 @@ class Registry { val.value, )}`; - const { exemplar } = val; - if (exemplar && isOpenMetrics) { - const formattedExemplars = formatLabels(exemplar.labelSet); - fullMetricLine += ` # {${formattedExemplars.join( - ',', - )}} ${getValueAsString(exemplar.value)} ${exemplar.timestamp}`; + if (isOpenMetrics) { + const { exemplar } = val; + if (exemplar) { + const formattedExemplars = formatLabels(exemplar.labelSet).join(','); + fullMetricLine += ` # {${formattedExemplars}} ${getValueAsString(exemplar.value)} ${exemplar.timestamp}`; + } } values.push(fullMetricLine); } diff --git a/lib/timeWindowQuantiles.js b/lib/timeWindowQuantiles.js index 357e7dfd..be6633ba 100644 --- a/lib/timeWindowQuantiles.js +++ b/lib/timeWindowQuantiles.js @@ -18,8 +18,8 @@ const { TDigest } = require('tdigest'); class TimeWindowQuantiles { constructor(maxAgeSeconds, ageBuckets) { - this.maxAgeSeconds = maxAgeSeconds || 0; - this.ageBuckets = ageBuckets || 0; + this.maxAgeSeconds = maxAgeSeconds ?? 0; + this.ageBuckets = ageBuckets ?? 0; this.shouldRotate = maxAgeSeconds && ageBuckets; diff --git a/lib/util.js b/lib/util.js index 69f12d52..a6b5ed10 100644 --- a/lib/util.js +++ b/lib/util.js @@ -134,7 +134,7 @@ function hashObject(labels, labelNames) { // is unique for each possible labels object and consistent across // calls with equivalent labels objects. - if (labelNames) { + if (labelNames !== undefined) { return fastHashObject(labelNames, labels); } diff --git a/test/clusterTest.js b/test/clusterTest.js index c475266c..4f85a913 100644 --- a/test/clusterTest.js +++ b/test/clusterTest.js @@ -342,7 +342,7 @@ describe.each([ } finally { jest.dontMock('cluster'); gauge.remove(); - if (connectedDescriptor) { + if (connectedDescriptor !== undefined) { Object.defineProperty(process, 'connected', connectedDescriptor); } else { delete process.connected; @@ -418,7 +418,7 @@ describe('worker message handling', () => { jest.resetModules(); jest.dontMock('cluster'); process.removeListener('message', listener); - if (connectedDescriptor) { + if (connectedDescriptor !== undefined) { Object.defineProperty(process, 'connected', connectedDescriptor); } else { delete process.connected; diff --git a/test/defaultMetricsTest.js b/test/defaultMetricsTest.js index 00ad8c25..24f453aa 100644 --- a/test/defaultMetricsTest.js +++ b/test/defaultMetricsTest.js @@ -27,7 +27,7 @@ describe.each([ beforeAll(() => { cpuUsage = process.cpuUsage; - if (cpuUsage) { + if (cpuUsage !== undefined) { Object.defineProperty(process, 'cpuUsage', { value() { return { user: 1000, system: 10 }; @@ -43,7 +43,7 @@ describe.each([ }); afterAll(() => { - if (cpuUsage) { + if (cpuUsage !== undefined) { Object.defineProperty(process, 'cpuUsage', { value: cpuUsage, }); diff --git a/test/exemplarsTest.js b/test/exemplarsTest.js index a349de39..577be67b 100644 --- a/test/exemplarsTest.js +++ b/test/exemplarsTest.js @@ -280,17 +280,18 @@ describe('Exemplars', () => { }); }); - function getValueByLabel(label, values, key) { + function getValueByLabel(label, values, key = 'le') { return values.reduce((acc, val) => { - if (val.labels && val.labels[key || 'le'] === label) { + if (val.labels?.[key] === label) { acc = val; } return acc; }, {}); } - function getValuesByLabel(label, values, key) { + + function getValuesByLabel(label, values, key = 'le') { return values.reduce((acc, val) => { - if (val.labels && val.labels[key || 'le'] === label) { + if (val.labels?.[key] === label) { acc.push(val); } return acc; diff --git a/test/histogramTest.js b/test/histogramTest.js index 6d44253b..4f126c8c 100644 --- a/test/histogramTest.js +++ b/test/histogramTest.js @@ -503,17 +503,17 @@ describe.each([ return acc; }, {}); } - function getValueByLabel(label, values, key) { + function getValueByLabel(label, values, key = 'le') { return values.reduce((acc, val) => { - if (val.labels && val.labels[key || 'le'] === label) { + if (val.labels?.[key] === label) { acc = val; } return acc; }, {}); } - function getValuesByLabel(label, values, key) { + function getValuesByLabel(label, values, key = 'le') { return values.reduce((acc, val) => { - if (val.labels && val.labels[key || 'le'] === label) { + if (val.labels?.[key] === label) { acc.push(val); } return acc; diff --git a/test/metrics/gcTest.js b/test/metrics/gcTest.js index e7fa89cf..73a4c37d 100644 --- a/test/metrics/gcTest.js +++ b/test/metrics/gcTest.js @@ -50,7 +50,7 @@ describe.each([ // node version is too old } - if (perf_hooks) { + if (perf_hooks !== undefined) { expect(metrics).toHaveLength(1); expect(metrics[0].help).toEqual(