parent
be7210d375
commit
c5f289946c
6 changed files with 84 additions and 47 deletions
53
package-lock.json
generated
53
package-lock.json
generated
|
@ -11,6 +11,7 @@
|
|||
"dependencies": {
|
||||
"@fastify/auth": "^4.1.0",
|
||||
"@fastify/basic-auth": "^5.0.0",
|
||||
"array.prototype.group": "^1.1.2",
|
||||
"bcrypt": "^5.1.0",
|
||||
"fastify": "^4.9.2",
|
||||
"hap-node-client": "^0.2.1",
|
||||
|
@ -2351,6 +2352,18 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/array.prototype.group": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/array.prototype.group/-/array.prototype.group-1.1.2.tgz",
|
||||
"integrity": "sha512-XTy3DE/Tz1nsrhPaYXgVTzQrRf1/0/RWySM5o5qC6BSBG7NWQ/AxggKNiLyLCRkLxM+mJoq5GEFosYZ846QlHw==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
"es-abstract": "^1.20.4",
|
||||
"es-shim-unscopables": "^1.0.0",
|
||||
"get-intrinsic": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/array.prototype.map": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.5.tgz",
|
||||
|
@ -3718,7 +3731,6 @@
|
|||
"version": "1.20.4",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz",
|
||||
"integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"es-to-primitive": "^1.2.1",
|
||||
|
@ -3780,7 +3792,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
|
||||
"integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
|
@ -3789,7 +3800,6 @@
|
|||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
|
||||
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-callable": "^1.1.4",
|
||||
"is-date-object": "^1.0.1",
|
||||
|
@ -4895,7 +4905,6 @@
|
|||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
|
||||
"integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3",
|
||||
|
@ -5001,7 +5010,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
|
||||
"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.1"
|
||||
|
@ -5753,7 +5761,6 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
||||
"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.0",
|
||||
"has": "^1.0.3",
|
||||
|
@ -5986,7 +5993,6 @@
|
|||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
||||
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
|
@ -6094,7 +6100,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
|
||||
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2"
|
||||
},
|
||||
|
@ -6199,7 +6204,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
||||
"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2"
|
||||
},
|
||||
|
@ -9022,7 +9026,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
|
||||
"integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.3",
|
||||
|
@ -9377,7 +9380,6 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
|
||||
"integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
|
@ -9391,7 +9393,6 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
|
||||
"integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
|
@ -9900,7 +9901,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||
"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"has-bigints": "^1.0.2",
|
||||
|
@ -12230,6 +12230,18 @@
|
|||
"es-shim-unscopables": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"array.prototype.group": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/array.prototype.group/-/array.prototype.group-1.1.2.tgz",
|
||||
"integrity": "sha512-XTy3DE/Tz1nsrhPaYXgVTzQrRf1/0/RWySM5o5qC6BSBG7NWQ/AxggKNiLyLCRkLxM+mJoq5GEFosYZ846QlHw==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
"es-abstract": "^1.20.4",
|
||||
"es-shim-unscopables": "^1.0.0",
|
||||
"get-intrinsic": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"array.prototype.map": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.5.tgz",
|
||||
|
@ -13238,7 +13250,6 @@
|
|||
"version": "1.20.4",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz",
|
||||
"integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"es-to-primitive": "^1.2.1",
|
||||
|
@ -13291,7 +13302,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
|
||||
"integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
|
@ -13300,7 +13310,6 @@
|
|||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
|
||||
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-callable": "^1.1.4",
|
||||
"is-date-object": "^1.0.1",
|
||||
|
@ -14143,7 +14152,6 @@
|
|||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
|
||||
"integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3",
|
||||
|
@ -14216,7 +14224,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
|
||||
"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.1"
|
||||
|
@ -14756,7 +14763,6 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
||||
"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.1.0",
|
||||
"has": "^1.0.3",
|
||||
|
@ -14907,8 +14913,7 @@
|
|||
"is-negative-zero": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
||||
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA=="
|
||||
},
|
||||
"is-npm": {
|
||||
"version": "6.0.0",
|
||||
|
@ -14971,7 +14976,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
|
||||
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2"
|
||||
}
|
||||
|
@ -15040,7 +15044,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
||||
"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2"
|
||||
}
|
||||
|
@ -17096,7 +17099,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
|
||||
"integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.3",
|
||||
|
@ -17380,7 +17382,6 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
|
||||
"integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
|
@ -17391,7 +17392,6 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
|
||||
"integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.4",
|
||||
|
@ -17750,7 +17750,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||
"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"has-bigints": "^1.0.2",
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
"dependencies": {
|
||||
"@fastify/auth": "^4.1.0",
|
||||
"@fastify/basic-auth": "^5.0.0",
|
||||
"array.prototype.group": "^1.1.2",
|
||||
"bcrypt": "^5.1.0",
|
||||
"fastify": "^4.9.2",
|
||||
"hap-node-client": "^0.2.1",
|
||||
|
|
9
src/ambient.d.ts
vendored
9
src/ambient.d.ts
vendored
|
@ -18,3 +18,12 @@ declare module 'hap-node-client' {
|
|||
declare module '@homebridge/dbus-native' {
|
||||
type InvokeError = unknown
|
||||
}
|
||||
|
||||
declare module 'array.prototype.group' {
|
||||
function shim(): void
|
||||
}
|
||||
|
||||
interface Array<T> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
group<U>(fn: (value: T, index: number, array: T[]) => U, thisArg?: any): { U: T[] }
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ import type { Logger } from 'homebridge'
|
|||
import type { HttpConfig, HttpResponse, HttpServer } from './adapters/http'
|
||||
import type { Metric } from './metrics'
|
||||
import { strTrimRight } from './std'
|
||||
import { shim } from 'array.prototype.group'
|
||||
shim()
|
||||
|
||||
export class MetricsRenderer {
|
||||
private readonly prefix: string
|
||||
|
@ -10,17 +12,24 @@ export class MetricsRenderer {
|
|||
this.prefix = strTrimRight(prefix, '_')
|
||||
}
|
||||
|
||||
render(metric: Metric): string {
|
||||
const name = this.metricName(metric.name)
|
||||
return [
|
||||
`# TYPE ${name} ${name.endsWith('_total') ? 'counter' : 'gauge'}`,
|
||||
`${name}${this.renderLabels(metric.labels)} ${metric.value}${
|
||||
metric.timestamp !== null ? ' ' + String(metric.timestamp.getTime()) : ''
|
||||
}`,
|
||||
].join('\n')
|
||||
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')
|
||||
}
|
||||
|
||||
private renderLabels(labels: Metric['labels']): string {
|
||||
private formatMetric(metric: Metric): string {
|
||||
return `${this.metricName(metric.name)}${MetricsRenderer.renderLabels(metric.labels)} ${metric.value}${
|
||||
metric.timestamp !== null ? ' ' + String(metric.timestamp.getTime()) : ''
|
||||
}`
|
||||
}
|
||||
|
||||
private static renderLabels(labels: Metric['labels']): string {
|
||||
const rendered = Object.entries(labels)
|
||||
.map(([label, val]) => `${sanitizePrometheusMetricName(label)}="${escapeAttributeValue(val)}"`)
|
||||
.join(',')
|
||||
|
@ -91,7 +100,7 @@ export class PrometheusServer implements HttpServer {
|
|||
}
|
||||
|
||||
onMetricsDiscovery(metrics: Metric[]): void {
|
||||
this.metricsResponse = metrics.map((metric) => this.renderer.render(metric)).join('\n')
|
||||
this.metricsResponse = this.renderer.render(metrics)
|
||||
this.metricsDiscovered = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ describe('Fastify HTTP adapter', () => {
|
|||
[
|
||||
'# TYPE homebridge_metric gauge',
|
||||
'homebridge_metric{name="metric"} 0.1 1577836800000',
|
||||
'',
|
||||
'# TYPE homebridge_something_total counter',
|
||||
'homebridge_something_total{name="counter"} 100 1577836800000',
|
||||
].join('\n'),
|
||||
|
@ -117,6 +118,7 @@ describe('Fastify HTTP adapter', () => {
|
|||
[
|
||||
'# TYPE homebridge_metric gauge',
|
||||
'homebridge_metric{name="metric"} 0.1 1577836800000',
|
||||
'',
|
||||
'# TYPE homebridge_something_total counter',
|
||||
'homebridge_something_total{name="counter"} 100 1577836800000',
|
||||
].join('\n'),
|
||||
|
|
|
@ -6,14 +6,14 @@ describe('Render prometheus metrics', () => {
|
|||
const renderer = new MetricsRenderer('prefix')
|
||||
|
||||
test('Renders simple metric', () => {
|
||||
expect(renderer.render(new Metric('metric', 0.000001))).toEqual(
|
||||
expect(renderer.render([new Metric('metric', 0.000001)])).toEqual(
|
||||
`# TYPE prefix_metric gauge
|
||||
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(
|
||||
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`,
|
||||
)
|
||||
|
@ -21,9 +21,9 @@ prefix_metric 0.000001 946684800000`,
|
|||
|
||||
test('Renders simple metric with labels', () => {
|
||||
expect(
|
||||
renderer.render(
|
||||
renderer.render([
|
||||
new Metric('metric', 0.000001, new Date('2000-01-01 00:00:00 UTC'), { label: 'Some Label' }),
|
||||
),
|
||||
]),
|
||||
).toEqual(
|
||||
`# TYPE prefix_metric gauge
|
||||
prefix_metric{label="Some Label"} 0.000001 946684800000`,
|
||||
|
@ -33,9 +33,9 @@ prefix_metric{label="Some Label"} 0.000001 946684800000`,
|
|||
test('Renders total as counter', () => {
|
||||
for (const metricName of ['some_total_metric', 'some_metric_total', 'total_some_metric']) {
|
||||
expect(
|
||||
renderer.render(
|
||||
renderer.render([
|
||||
new Metric(metricName, 42, new Date('2000-01-01 00:00:00 UTC'), { label: 'Some Label' }),
|
||||
),
|
||||
]),
|
||||
).toEqual(
|
||||
`# TYPE prefix_some_metric_total counter
|
||||
prefix_some_metric_total{label="Some Label"} 42 946684800000`,
|
||||
|
@ -43,29 +43,46 @@ prefix_some_metric_total{label="Some Label"} 42 946684800000`,
|
|||
}
|
||||
})
|
||||
|
||||
test('Renders multiple metrics correctly', () => {
|
||||
expect(
|
||||
renderer.render([
|
||||
new Metric('some_gauge', 10, new Date('2000-01-01 00:00:00 UTC')),
|
||||
new Metric('another_gauge', 30, new Date('2000-01-01 00:00:00 UTC')),
|
||||
new Metric('some_gauge', 20, new Date('2000-01-01 00:00:00 UTC')),
|
||||
]),
|
||||
).toEqual(
|
||||
`# TYPE prefix_some_gauge gauge
|
||||
prefix_some_gauge 10 946684800000
|
||||
prefix_some_gauge 20 946684800000
|
||||
|
||||
# TYPE prefix_another_gauge gauge
|
||||
prefix_another_gauge 30 946684800000`,
|
||||
)
|
||||
})
|
||||
|
||||
test('Sanitizes metric names', () => {
|
||||
expect(renderer.render(new Metric('mätric name', 0))).toEqual(
|
||||
expect(renderer.render([new Metric('mätric name', 0)])).toEqual(
|
||||
`# TYPE prefix_m_tric_name gauge
|
||||
prefix_m_tric_name 0`,
|
||||
)
|
||||
})
|
||||
|
||||
test('Sanitizes label names', () => {
|
||||
expect(renderer.render(new Metric('metric', 0, null, { 'yet another label': 'foo' }))).toEqual(
|
||||
expect(renderer.render([new Metric('metric', 0, null, { 'yet another label': 'foo' })])).toEqual(
|
||||
`# TYPE prefix_metric gauge
|
||||
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(
|
||||
expect(renderer.render([new Metric('metric', 0, null, { label: 'foo\nbar' })])).toEqual(
|
||||
`# TYPE prefix_metric gauge
|
||||
prefix_metric{label="foo\\nbar"} 0`,
|
||||
)
|
||||
})
|
||||
|
||||
test('Escapes quotes in attribute value', () => {
|
||||
expect(renderer.render(new Metric('metric', 0, null, { label: 'foo"bar' }))).toEqual(
|
||||
expect(renderer.render([new Metric('metric', 0, null, { label: 'foo"bar' })])).toEqual(
|
||||
`# TYPE prefix_metric gauge
|
||||
prefix_metric{label="foo\\"bar"} 0`,
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue