diff --git a/lib/formatter.js b/lib/formatter.js index 982d9383..f4e5a9db 100644 --- a/lib/formatter.js +++ b/lib/formatter.js @@ -30,22 +30,33 @@ function getFormatter(metric, defaultLabels) { } function getLabelsCode(metric, defaultLabelNames, defaultLabels) { - let labelString = ''; + const labelString = []; const labelNames = getLabelNames(metric, defaultLabelNames); for (let index = 0; index < labelNames.length; index++) { + const comma = index > 0 ? ',' : ''; const labelName = labelNames[index]; if (labelName === 'quantile') { - labelString += `\${val.labels.quantile != null ? \`quantile="\${escapeLabelValue(val.labels.quantile)}"\` : ''}`; + labelString.push( + `\${val.labels.quantile != null ? \`${comma}quantile="\${escapeLabelValue(val.labels.quantile)}"\` : ''}`, + ); } else if (labelName === 'le') { - labelString += `\${val.labels.le != null ? \`le="\${escapeLabelValue(val.labels.le)}"\` : ''}`; + labelString.push( + `\${val.labels.le != null ? \`${comma}le="\${escapeLabelValue(val.labels.le)}"\` : ''}`, + ); } else { - labelString += `${labelName}="\${val.labels['${labelName}'] ? escapeLabelValue(val.labels['${labelName}']) : escapeLabelValue('${defaultLabels[labelName]}')}"`; - } - if (index !== labelNames.length - 1 && labelString.length > 0) { - labelString += ','; + const defaultLabelValue = defaultLabels[labelName]; + if (typeof defaultLabelValue === 'undefined') { + labelString.push( + `\${val.labels['${labelName}'] != null ? \`${comma}${labelName}="\${escapeLabelValue(val.labels['${labelName}'])}"\` : ''}`, + ); + } else { + labelString.push( + `${comma}${labelName}="\${escapeLabelValue(val.labels['${labelName}'] || '${defaultLabelValue}')}"`, + ); + } } } - return labelString; + return labelString.join(''); } function getLabelNames(metric, defaultLabelNames) { diff --git a/test/registerTest.js b/test/registerTest.js index 370b7305..1ecc63a2 100644 --- a/test/registerTest.js +++ b/test/registerTest.js @@ -103,6 +103,32 @@ describe('register', () => { expect(output).toEqual('test_metric{testLabel="testValue"} 1'); }); + it('should handle a metric with default labels with value 0', () => { + register.setDefaultLabels({ testLabel: 0 }); + const counter = new Counter({ + name: 'test_metric', + help: 'A test metric', + }); + counter.inc(1); + register.registerMetric(counter); + + const output = register.metrics().split('\n')[2]; + expect(output).toEqual('test_metric{testLabel="0"} 1'); + }); + + it('should handle a metrics with labels subset', () => { + const gauge = new Gauge({ + name: 'test_metric', + help: 'help', + labelNames: ['code', 'success'], + }); + gauge.inc({ code: '200' }, 10); + register.registerMetric(gauge); + + const output = register.metrics().split('\n')[2]; + expect(output).toEqual('test_metric{code="200"} 10'); + }); + it('labeled metrics should take precidence over defaulted', () => { register.setDefaultLabels({ testLabel: 'testValue' }); const counter = new Counter({