@platformatic/metrics 3.54.0 → 3.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +142 -50
- package/package.json +1 -1
- package/test/helper.js +20 -14
- package/test/index.test.js +77 -6
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import collectHttpMetrics from '@platformatic/http-metrics'
|
|
2
|
+
import { subscribe, unsubscribe } from 'node:diagnostics_channel'
|
|
2
3
|
import os from 'node:os'
|
|
3
4
|
import { performance } from 'node:perf_hooks'
|
|
4
5
|
import client from '@platformatic/prom-client'
|
|
@@ -21,9 +22,17 @@ import gc from '@platformatic/prom-client/lib/metrics/gc.js'
|
|
|
21
22
|
export * as client from '@platformatic/prom-client'
|
|
22
23
|
|
|
23
24
|
const { eventLoopUtilization } = performance
|
|
24
|
-
const { Registry, Gauge, Counter, collectDefaultMetrics } = client
|
|
25
|
+
const { Registry, Gauge, Counter, Histogram, collectDefaultMetrics } = client
|
|
25
26
|
|
|
26
27
|
export const kMetricsGroups = Symbol('plt.metrics.MetricsGroups')
|
|
28
|
+
const kMetricsCleanups = Symbol('plt.metrics.MetricsCleanups')
|
|
29
|
+
const kHttpClientRequestStart = Symbol('plt.metrics.HttpClientRequestStart')
|
|
30
|
+
const kHttpClientRequestStatusCode = Symbol('plt.metrics.HttpClientRequestStatusCode')
|
|
31
|
+
|
|
32
|
+
function getRegistrySet (registry, key) {
|
|
33
|
+
registry[key] ??= new Set()
|
|
34
|
+
return registry[key]
|
|
35
|
+
}
|
|
27
36
|
|
|
28
37
|
// Process-level metrics (same across all workers, collect once in main thread)
|
|
29
38
|
export const PROCESS_LEVEL_METRICS = [
|
|
@@ -69,8 +78,7 @@ export const THREAD_LEVEL_METRICS = [
|
|
|
69
78
|
]
|
|
70
79
|
|
|
71
80
|
export function registerMetricsGroup (registry, group) {
|
|
72
|
-
registry
|
|
73
|
-
registry[kMetricsGroups].add(group)
|
|
81
|
+
getRegistrySet(registry, kMetricsGroups).add(group)
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
export function hasMetricsGroup (registry, group) {
|
|
@@ -80,23 +88,141 @@ export function hasMetricsGroup (registry, group) {
|
|
|
80
88
|
// Use this method when dealing with metrics registration in async functions.
|
|
81
89
|
// This will ensure that the group is registered only once.
|
|
82
90
|
export function ensureMetricsGroup (registry, group) {
|
|
83
|
-
|
|
91
|
+
const groups = getRegistrySet(registry, kMetricsGroups)
|
|
84
92
|
|
|
85
|
-
if (
|
|
93
|
+
if (groups.has(group)) {
|
|
86
94
|
return true
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
|
|
97
|
+
groups.add(group)
|
|
90
98
|
return false
|
|
91
99
|
}
|
|
92
100
|
|
|
101
|
+
export function registerMetricsCleanup (registry, cleanup) {
|
|
102
|
+
getRegistrySet(registry, kMetricsCleanups).add(cleanup)
|
|
103
|
+
}
|
|
104
|
+
|
|
93
105
|
export function clearRegistry (registry) {
|
|
106
|
+
if (registry[kMetricsCleanups]) {
|
|
107
|
+
for (const cleanup of registry[kMetricsCleanups]) {
|
|
108
|
+
cleanup()
|
|
109
|
+
}
|
|
110
|
+
registry[kMetricsCleanups].clear()
|
|
111
|
+
}
|
|
112
|
+
|
|
94
113
|
registry.clear()
|
|
95
114
|
if (registry[kMetricsGroups]) {
|
|
96
115
|
registry[kMetricsGroups].clear()
|
|
97
116
|
}
|
|
98
117
|
}
|
|
99
118
|
|
|
119
|
+
function getHttpClientRequestOrigin (request) {
|
|
120
|
+
return typeof request.origin === 'string' && request.origin.length > 0 ? request.origin : 'unknown'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getHttpClientErrorType (error) {
|
|
124
|
+
return error ? String(error.code ?? error.name ?? 'unknown') : ''
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isHttpClientMetricsEnabled (metricsConfig) {
|
|
128
|
+
return metricsConfig.httpClientMetrics === true || metricsConfig.httpClientMetrics === 'true'
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function collectHttpClientMetrics (registry) {
|
|
132
|
+
if (ensureMetricsGroup(registry, 'http-client')) {
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const requestDurationMetric = new Histogram({
|
|
137
|
+
name: 'http_client_request_duration_seconds',
|
|
138
|
+
help: 'outgoing HTTP client request duration in seconds',
|
|
139
|
+
labelNames: ['method', 'status_code', 'dispatcher_stats_url', 'error_type'],
|
|
140
|
+
collect: function () {
|
|
141
|
+
process.nextTick(() => this.reset())
|
|
142
|
+
},
|
|
143
|
+
registers: [registry]
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
const onRequestCreate = ({ request }) => {
|
|
147
|
+
if (request && typeof request === 'object') {
|
|
148
|
+
request[kHttpClientRequestStart] = performance.now()
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const onRequestHeaders = ({ request, response }) => {
|
|
153
|
+
if (request && typeof request === 'object') {
|
|
154
|
+
request[kHttpClientRequestStatusCode] = response?.statusCode ?? ''
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const observeRequest = ({ request, response, error }) => {
|
|
159
|
+
if (!request || typeof request !== 'object') {
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const start = request[kHttpClientRequestStart]
|
|
164
|
+
if (start === undefined) {
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const duration = (performance.now() - start) / 1000
|
|
169
|
+
const method = request.method ?? 'unknown'
|
|
170
|
+
const statusCode = response?.statusCode ?? request[kHttpClientRequestStatusCode] ?? ''
|
|
171
|
+
const dispatcherStatsUrl = getHttpClientRequestOrigin(request)
|
|
172
|
+
const errorType = getHttpClientErrorType(error)
|
|
173
|
+
|
|
174
|
+
delete request[kHttpClientRequestStart]
|
|
175
|
+
delete request[kHttpClientRequestStatusCode]
|
|
176
|
+
|
|
177
|
+
requestDurationMetric.observe({
|
|
178
|
+
method,
|
|
179
|
+
status_code: statusCode,
|
|
180
|
+
dispatcher_stats_url: dispatcherStatsUrl,
|
|
181
|
+
error_type: errorType
|
|
182
|
+
}, duration)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
subscribe('undici:request:create', onRequestCreate)
|
|
186
|
+
subscribe('undici:request:headers', onRequestHeaders)
|
|
187
|
+
subscribe('undici:request:trailers', observeRequest)
|
|
188
|
+
subscribe('undici:request:error', observeRequest)
|
|
189
|
+
|
|
190
|
+
registerMetricsCleanup(registry, () => {
|
|
191
|
+
unsubscribe('undici:request:create', onRequestCreate)
|
|
192
|
+
unsubscribe('undici:request:headers', onRequestHeaders)
|
|
193
|
+
unsubscribe('undici:request:trailers', observeRequest)
|
|
194
|
+
unsubscribe('undici:request:error', observeRequest)
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function collectHttpServerMetrics (registry, metricsConfig) {
|
|
199
|
+
if (ensureMetricsGroup(registry, 'http')) {
|
|
200
|
+
return
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Build custom labels configuration
|
|
204
|
+
const { customLabels, getCustomLabels } = buildCustomLabelsConfig(metricsConfig.httpCustomLabels)
|
|
205
|
+
|
|
206
|
+
collectHttpMetrics(registry, {
|
|
207
|
+
customLabels,
|
|
208
|
+
getCustomLabels,
|
|
209
|
+
histogram: {
|
|
210
|
+
name: 'http_request_all_duration_seconds',
|
|
211
|
+
help: 'request duration in seconds summary for all requests',
|
|
212
|
+
collect: function () {
|
|
213
|
+
process.nextTick(() => this.reset())
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
summary: {
|
|
217
|
+
name: 'http_request_all_summary_seconds',
|
|
218
|
+
help: 'request duration in seconds histogram for all requests',
|
|
219
|
+
collect: function () {
|
|
220
|
+
process.nextTick(() => this.reset())
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
|
|
100
226
|
export async function collectThreadCpuMetrics (registry) {
|
|
101
227
|
if (ensureMetricsGroup(registry, 'threadCpuUsage')) {
|
|
102
228
|
return
|
|
@@ -283,28 +409,11 @@ export async function collectThreadMetrics (applicationId, workerId, metricsConf
|
|
|
283
409
|
await collectThreadCpuMetrics(registry)
|
|
284
410
|
}
|
|
285
411
|
|
|
286
|
-
if (metricsConfig.httpMetrics
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
customLabels,
|
|
292
|
-
getCustomLabels,
|
|
293
|
-
histogram: {
|
|
294
|
-
name: 'http_request_all_duration_seconds',
|
|
295
|
-
help: 'request duration in seconds summary for all requests',
|
|
296
|
-
collect: function () {
|
|
297
|
-
process.nextTick(() => this.reset())
|
|
298
|
-
}
|
|
299
|
-
},
|
|
300
|
-
summary: {
|
|
301
|
-
name: 'http_request_all_summary_seconds',
|
|
302
|
-
help: 'request duration in seconds histogram for all requests',
|
|
303
|
-
collect: function () {
|
|
304
|
-
process.nextTick(() => this.reset())
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
})
|
|
412
|
+
if (metricsConfig.httpMetrics) {
|
|
413
|
+
collectHttpServerMetrics(registry, metricsConfig)
|
|
414
|
+
if (isHttpClientMetricsEnabled(metricsConfig)) {
|
|
415
|
+
collectHttpClientMetrics(registry)
|
|
416
|
+
}
|
|
308
417
|
}
|
|
309
418
|
|
|
310
419
|
return {
|
|
@@ -365,28 +474,11 @@ export async function collectMetrics (applicationId, workerId, metricsConfig = {
|
|
|
365
474
|
await collectThreadCpuMetrics(registry)
|
|
366
475
|
}
|
|
367
476
|
|
|
368
|
-
if (metricsConfig.httpMetrics
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
customLabels,
|
|
374
|
-
getCustomLabels,
|
|
375
|
-
histogram: {
|
|
376
|
-
name: 'http_request_all_duration_seconds',
|
|
377
|
-
help: 'request duration in seconds summary for all requests',
|
|
378
|
-
collect: function () {
|
|
379
|
-
process.nextTick(() => this.reset())
|
|
380
|
-
}
|
|
381
|
-
},
|
|
382
|
-
summary: {
|
|
383
|
-
name: 'http_request_all_summary_seconds',
|
|
384
|
-
help: 'request duration in seconds histogram for all requests',
|
|
385
|
-
collect: function () {
|
|
386
|
-
process.nextTick(() => this.reset())
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
})
|
|
477
|
+
if (metricsConfig.httpMetrics) {
|
|
478
|
+
collectHttpServerMetrics(registry, metricsConfig)
|
|
479
|
+
if (isHttpClientMetricsEnabled(metricsConfig)) {
|
|
480
|
+
collectHttpClientMetrics(registry)
|
|
481
|
+
}
|
|
390
482
|
}
|
|
391
483
|
|
|
392
484
|
return {
|
package/package.json
CHANGED
package/test/helper.js
CHANGED
|
@@ -123,7 +123,8 @@ export const expectedMetrics = [
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
name: 'http_request_all_duration_seconds',
|
|
126
|
-
type: 'histogram'
|
|
126
|
+
type: 'histogram',
|
|
127
|
+
buckets: ['0.005', '0.01', '0.025', '0.05', '0.1', '0.25', '0.5', '1', '2.5', '5', '10']
|
|
127
128
|
}
|
|
128
129
|
]
|
|
129
130
|
|
|
@@ -141,19 +142,24 @@ function assertSummary (metrics, metric) {
|
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
function assertHistogram (metrics, metric) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
ok(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
145
|
+
const lines = metrics.split('\n')
|
|
146
|
+
const bucketLines = lines.filter(line => line.startsWith(`${metric.name}_bucket{`))
|
|
147
|
+
|
|
148
|
+
if (!metric.buckets) {
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
ok(bucketLines.length > 0, `Metric ${metric.name} buckets not found`)
|
|
153
|
+
|
|
154
|
+
for (const bucket of metric.buckets ?? []) {
|
|
155
|
+
ok(
|
|
156
|
+
bucketLines.some(line => line.includes(`le="${bucket}"`)),
|
|
157
|
+
`Metric ${metric.name} bucket ${bucket} not found`
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
ok(lines.some(line => line.startsWith(`${metric.name}_sum{`)), `Metric ${metric.name} sum not found`)
|
|
162
|
+
ok(lines.some(line => line.startsWith(`${metric.name}_count{`)), `Metric ${metric.name} count not found`)
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
export function assertMetric (metrics, metric) {
|
package/test/index.test.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
|
+
import { channel } from 'node:diagnostics_channel'
|
|
2
3
|
import { test } from 'node:test'
|
|
3
|
-
import { buildCustomLabelsConfig, client, collectMetrics } from '../index.js'
|
|
4
|
+
import { buildCustomLabelsConfig, clearRegistry, client, collectMetrics } from '../index.js'
|
|
4
5
|
|
|
5
6
|
const nextTick = () => new Promise(resolve => process.nextTick(resolve))
|
|
6
7
|
|
|
@@ -58,21 +59,88 @@ test('workerId is NOT included in labels when negative', async () => {
|
|
|
58
59
|
assert.strictEqual(values[0].labels.workerId, undefined)
|
|
59
60
|
})
|
|
60
61
|
|
|
61
|
-
test('httpMetrics creates histogram and summary with collect functions', async
|
|
62
|
+
test('httpMetrics creates histogram and summary with collect functions', async t => {
|
|
62
63
|
const result = await collectMetrics('test-service', 1, { httpMetrics: true })
|
|
64
|
+
t.after(() => clearRegistry(result.registry))
|
|
63
65
|
const metrics = await result.registry.getMetricsAsJSON()
|
|
64
66
|
|
|
65
67
|
const histogram = metrics.find(m => m.name === 'http_request_all_duration_seconds')
|
|
66
68
|
const summary = metrics.find(m => m.name === 'http_request_all_summary_seconds')
|
|
69
|
+
const clientHistogram = metrics.find(m => m.name === 'http_client_request_duration_seconds')
|
|
67
70
|
|
|
68
71
|
assert.ok(histogram, 'histogram metric should exist')
|
|
69
72
|
assert.ok(summary, 'summary metric should exist')
|
|
73
|
+
assert.strictEqual(clientHistogram, undefined, 'client histogram metric should not exist by default')
|
|
70
74
|
assert.strictEqual(histogram.help, 'request duration in seconds summary for all requests')
|
|
71
75
|
assert.strictEqual(summary.help, 'request duration in seconds histogram for all requests')
|
|
72
76
|
})
|
|
73
77
|
|
|
74
|
-
test('httpMetrics
|
|
78
|
+
test('httpMetrics creates HTTP client histogram when enabled', async t => {
|
|
79
|
+
const result = await collectMetrics('test-service', 1, { httpMetrics: true, httpClientMetrics: true })
|
|
80
|
+
t.after(() => clearRegistry(result.registry))
|
|
81
|
+
const metrics = await result.registry.getMetricsAsJSON()
|
|
82
|
+
|
|
83
|
+
const clientHistogram = metrics.find(m => m.name === 'http_client_request_duration_seconds')
|
|
84
|
+
|
|
85
|
+
assert.ok(clientHistogram, 'client histogram metric should exist')
|
|
86
|
+
assert.strictEqual(clientHistogram.help, 'outgoing HTTP client request duration in seconds')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('httpMetrics observes outgoing HTTP client request durations', async t => {
|
|
90
|
+
const result = await collectMetrics('test-service', 2, { httpMetrics: true, httpClientMetrics: true })
|
|
91
|
+
t.after(() => clearRegistry(result.registry))
|
|
92
|
+
|
|
93
|
+
const request = {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
origin: 'https://api.example.com:8443',
|
|
96
|
+
path: '/v1/resources'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
channel('undici:request:create').publish({ request })
|
|
100
|
+
channel('undici:request:headers').publish({ request, response: { statusCode: 201 } })
|
|
101
|
+
channel('undici:request:trailers').publish({ request })
|
|
102
|
+
|
|
103
|
+
const metrics = await result.registry.getMetricsAsJSON()
|
|
104
|
+
const histogram = metrics.find(m => m.name === 'http_client_request_duration_seconds')
|
|
105
|
+
const count = histogram.values.find(v => v.metricName === 'http_client_request_duration_seconds_count')
|
|
106
|
+
|
|
107
|
+
assert.strictEqual(count.value, 1)
|
|
108
|
+
assert.strictEqual(count.labels.applicationId, 'test-service')
|
|
109
|
+
assert.strictEqual(count.labels.workerId, 2)
|
|
110
|
+
assert.strictEqual(count.labels.method, 'POST')
|
|
111
|
+
assert.strictEqual(count.labels.status_code, 201)
|
|
112
|
+
assert.strictEqual(count.labels.dispatcher_stats_url, 'https://api.example.com:8443')
|
|
113
|
+
assert.strictEqual(count.labels.error_type, '')
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('httpMetrics observes outgoing HTTP client request errors', async t => {
|
|
117
|
+
const result = await collectMetrics('test-service', 3, { httpMetrics: true, httpClientMetrics: true })
|
|
118
|
+
t.after(() => clearRegistry(result.registry))
|
|
119
|
+
|
|
120
|
+
const request = {
|
|
121
|
+
method: 'GET',
|
|
122
|
+
origin: 'http://dependency.internal',
|
|
123
|
+
path: '/health'
|
|
124
|
+
}
|
|
125
|
+
const error = Object.assign(new Error('socket closed'), { code: 'UND_ERR_SOCKET' })
|
|
126
|
+
|
|
127
|
+
channel('undici:request:create').publish({ request })
|
|
128
|
+
channel('undici:request:error').publish({ request, error })
|
|
129
|
+
|
|
130
|
+
const metrics = await result.registry.getMetricsAsJSON()
|
|
131
|
+
const histogram = metrics.find(m => m.name === 'http_client_request_duration_seconds')
|
|
132
|
+
const count = histogram.values.find(v => v.metricName === 'http_client_request_duration_seconds_count')
|
|
133
|
+
|
|
134
|
+
assert.strictEqual(count.value, 1)
|
|
135
|
+
assert.strictEqual(count.labels.method, 'GET')
|
|
136
|
+
assert.strictEqual(count.labels.status_code, '')
|
|
137
|
+
assert.strictEqual(count.labels.dispatcher_stats_url, 'http://dependency.internal')
|
|
138
|
+
assert.strictEqual(count.labels.error_type, 'UND_ERR_SOCKET')
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
test('httpMetrics histogram resets after metric collection', async t => {
|
|
75
142
|
const result = await collectMetrics('test-service', 1, { httpMetrics: true })
|
|
143
|
+
t.after(() => clearRegistry(result.registry))
|
|
76
144
|
|
|
77
145
|
// Get the histogram metric using the public API
|
|
78
146
|
const histogramMetric = result.registry.getSingleMetric('http_request_all_duration_seconds')
|
|
@@ -99,8 +167,9 @@ test('httpMetrics histogram resets after metric collection', async () => {
|
|
|
99
167
|
assert.strictEqual(count?.value || 0, 0, 'histogram count should be reset to 0')
|
|
100
168
|
})
|
|
101
169
|
|
|
102
|
-
test('httpMetrics summary resets after metric collection', async
|
|
170
|
+
test('httpMetrics summary resets after metric collection', async t => {
|
|
103
171
|
const result = await collectMetrics('test-service', 1, { httpMetrics: true })
|
|
172
|
+
t.after(() => clearRegistry(result.registry))
|
|
104
173
|
|
|
105
174
|
// Get the summary metric using the public API
|
|
106
175
|
const summaryMetric = result.registry.getSingleMetric('http_request_all_summary_seconds')
|
|
@@ -203,7 +272,7 @@ test('buildCustomLabelsConfig handles case-insensitive header names', () => {
|
|
|
203
272
|
assert.deepStrictEqual(labels, { domain: 'example.com' })
|
|
204
273
|
})
|
|
205
274
|
|
|
206
|
-
test('httpMetrics with custom labels configuration', async
|
|
275
|
+
test('httpMetrics with custom labels configuration', async t => {
|
|
207
276
|
const httpCustomLabels = [
|
|
208
277
|
{ name: 'domain', header: 'x-forwarded-host', default: 'localhost' }
|
|
209
278
|
]
|
|
@@ -212,6 +281,7 @@ test('httpMetrics with custom labels configuration', async () => {
|
|
|
212
281
|
httpMetrics: true,
|
|
213
282
|
httpCustomLabels
|
|
214
283
|
})
|
|
284
|
+
t.after(() => clearRegistry(result.registry))
|
|
215
285
|
|
|
216
286
|
const metrics = await result.registry.getMetricsAsJSON()
|
|
217
287
|
const histogram = metrics.find(m => m.name === 'http_request_all_duration_seconds')
|
|
@@ -230,8 +300,9 @@ test('httpMetrics with custom labels configuration', async () => {
|
|
|
230
300
|
assert.ok(hasCustomLabel, 'custom domain label should be present in histogram values')
|
|
231
301
|
})
|
|
232
302
|
|
|
233
|
-
test('httpMetrics does not include telemetry_id label by default', async
|
|
303
|
+
test('httpMetrics does not include telemetry_id label by default', async t => {
|
|
234
304
|
const result = await collectMetrics('test-service', 1, { httpMetrics: true })
|
|
305
|
+
t.after(() => clearRegistry(result.registry))
|
|
235
306
|
|
|
236
307
|
const histogramMetric = result.registry.getSingleMetric('http_request_all_duration_seconds')
|
|
237
308
|
assert.ok(histogramMetric, 'histogram metric should exist')
|