@libp2p/opentelemetry-metrics 1.0.16 → 1.0.17
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/dist/index.min.js +1 -1
- package/dist/index.min.js.map +3 -3
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +113 -51
- package/dist/src/index.js.map +1 -1
- package/package.json +5 -4
- package/src/index.ts +158 -57
package/src/index.ts
CHANGED
|
@@ -48,14 +48,15 @@ import { OpenTelemetryMetric } from './metric.js'
|
|
|
48
48
|
import { OpenTelemetrySummaryGroup } from './summary-group.js'
|
|
49
49
|
import { OpenTelemetrySummary } from './summary.js'
|
|
50
50
|
import { collectSystemMetrics } from './system-metrics.js'
|
|
51
|
-
import type { MultiaddrConnection, Stream, Connection, Metric, MetricGroup, Metrics, CalculatedMetricOptions, MetricOptions, Counter, CounterGroup, Histogram, HistogramOptions, HistogramGroup, Summary, SummaryOptions, SummaryGroup, CalculatedHistogramOptions, CalculatedSummaryOptions, NodeInfo, TraceFunctionOptions, TraceGeneratorFunctionOptions, TraceAttributes } from '@libp2p/interface'
|
|
52
|
-
import type { Span, Attributes } from '@opentelemetry/api'
|
|
51
|
+
import type { MultiaddrConnection, Stream, Connection, Metric, MetricGroup, Metrics, CalculatedMetricOptions, MetricOptions, Counter, CounterGroup, Histogram, HistogramOptions, HistogramGroup, Summary, SummaryOptions, SummaryGroup, CalculatedHistogramOptions, CalculatedSummaryOptions, NodeInfo, TraceFunctionOptions, TraceGeneratorFunctionOptions, TraceAttributes, ComponentLogger, Logger } from '@libp2p/interface'
|
|
52
|
+
import type { Span, Attributes, Meter, Observable } from '@opentelemetry/api'
|
|
53
53
|
import type { Duplex } from 'it-stream-types'
|
|
54
54
|
|
|
55
55
|
// see https://betterstack.com/community/guides/observability/opentelemetry-metrics-nodejs/#prerequisites
|
|
56
56
|
|
|
57
57
|
export interface OpenTelemetryComponents {
|
|
58
58
|
nodeInfo: NodeInfo
|
|
59
|
+
logger: ComponentLogger
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
export interface OpenTelemetryMetricsInit {
|
|
@@ -92,14 +93,20 @@ export interface OpenTelemetryMetricsInit {
|
|
|
92
93
|
class OpenTelemetryMetrics implements Metrics {
|
|
93
94
|
private transferStats: Map<string, number>
|
|
94
95
|
private readonly tracer: ReturnType<typeof trace.getTracer>
|
|
95
|
-
private readonly
|
|
96
|
+
private readonly meter: Meter
|
|
97
|
+
private readonly log: Logger
|
|
98
|
+
private metrics: Map<string, OpenTelemetryMetric | OpenTelemetryMetricGroup | OpenTelemetryCounter | OpenTelemetryCounterGroup | OpenTelemetryHistogram | OpenTelemetryHistogramGroup | OpenTelemetrySummary | OpenTelemetrySummaryGroup>
|
|
99
|
+
private observables: Map<string, Observable>
|
|
96
100
|
|
|
97
101
|
constructor (components: OpenTelemetryComponents, init?: OpenTelemetryMetricsInit) {
|
|
102
|
+
this.log = components.logger.forComponent('libp2p:open-telemetry-metrics')
|
|
98
103
|
this.tracer = trace.getTracer(init?.appName ?? components.nodeInfo.name, init?.appVersion ?? components.nodeInfo.version)
|
|
104
|
+
this.metrics = new Map()
|
|
105
|
+
this.observables = new Map()
|
|
99
106
|
|
|
100
107
|
// holds global and per-protocol sent/received stats
|
|
101
108
|
this.transferStats = new Map()
|
|
102
|
-
this.
|
|
109
|
+
this.meter = metrics.getMeterProvider().getMeter(init?.meterName ?? components.nodeInfo.name)
|
|
103
110
|
|
|
104
111
|
this.registerCounterGroup('libp2p_data_transfer_bytes_total', {
|
|
105
112
|
label: 'protocol',
|
|
@@ -111,7 +118,7 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
// reset counts for next time
|
|
114
|
-
this.transferStats
|
|
121
|
+
this.transferStats.clear()
|
|
115
122
|
|
|
116
123
|
return output
|
|
117
124
|
}
|
|
@@ -126,6 +133,14 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
126
133
|
'@libp2p/metrics'
|
|
127
134
|
]
|
|
128
135
|
|
|
136
|
+
start (): void {
|
|
137
|
+
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
stop (): void {
|
|
141
|
+
this.transferStats.clear()
|
|
142
|
+
}
|
|
143
|
+
|
|
129
144
|
/**
|
|
130
145
|
* Increment the transfer stat for the passed key, making sure
|
|
131
146
|
* it exists first
|
|
@@ -177,23 +192,38 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
177
192
|
throw new InvalidParametersError('Metric name is required')
|
|
178
193
|
}
|
|
179
194
|
|
|
180
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
181
|
-
|
|
182
195
|
if (isCalculatedMetricOptions<CalculatedMetricOptions>(opts)) {
|
|
183
|
-
|
|
184
|
-
|
|
196
|
+
let gauge = this.observables.get(name)
|
|
197
|
+
|
|
198
|
+
if (gauge != null) {
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
gauge = this.meter.createObservableGauge(name, {
|
|
185
203
|
description: opts?.help ?? name
|
|
186
204
|
})
|
|
187
|
-
|
|
205
|
+
|
|
206
|
+
const calculate = opts.calculate
|
|
207
|
+
gauge.addCallback(async (result) => {
|
|
188
208
|
result.observe(await calculate())
|
|
189
209
|
})
|
|
190
210
|
|
|
211
|
+
this.observables.set(name, gauge)
|
|
212
|
+
|
|
191
213
|
return
|
|
192
214
|
}
|
|
193
215
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
216
|
+
let metric = this.metrics.get(name)
|
|
217
|
+
|
|
218
|
+
if (metric == null) {
|
|
219
|
+
metric = new OpenTelemetryMetric(this.meter.createGauge(name, {
|
|
220
|
+
description: opts?.help ?? name
|
|
221
|
+
}))
|
|
222
|
+
|
|
223
|
+
this.metrics.set(name, metric)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return metric
|
|
197
227
|
}
|
|
198
228
|
|
|
199
229
|
registerMetricGroup (name: string, opts: CalculatedMetricOptions<Record<string, number>>): void
|
|
@@ -203,14 +233,20 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
203
233
|
throw new InvalidParametersError('Metric name is required')
|
|
204
234
|
}
|
|
205
235
|
|
|
206
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
207
236
|
const label = opts?.label ?? name
|
|
208
237
|
|
|
209
238
|
if (isCalculatedMetricOptions<CalculatedMetricOptions<Record<string, number>>>(opts)) {
|
|
210
|
-
|
|
211
|
-
|
|
239
|
+
let gauge = this.observables.get(name)
|
|
240
|
+
|
|
241
|
+
if (gauge != null) {
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
gauge = this.meter.createObservableGauge(name, {
|
|
212
246
|
description: opts?.help ?? name
|
|
213
247
|
})
|
|
248
|
+
|
|
249
|
+
const calculate = opts.calculate
|
|
214
250
|
gauge.addCallback(async (observable) => {
|
|
215
251
|
const observed = await calculate()
|
|
216
252
|
|
|
@@ -221,12 +257,22 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
221
257
|
}
|
|
222
258
|
})
|
|
223
259
|
|
|
260
|
+
this.observables.set(name, gauge)
|
|
261
|
+
|
|
224
262
|
return
|
|
225
263
|
}
|
|
226
264
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
265
|
+
let metric = this.metrics.get(name)
|
|
266
|
+
|
|
267
|
+
if (metric == null) {
|
|
268
|
+
metric = new OpenTelemetryMetricGroup(label, this.meter.createGauge(name, {
|
|
269
|
+
description: opts?.help ?? name
|
|
270
|
+
}))
|
|
271
|
+
|
|
272
|
+
this.metrics.set(name, metric)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return metric
|
|
230
276
|
}
|
|
231
277
|
|
|
232
278
|
registerCounter (name: string, opts: CalculatedMetricOptions): void
|
|
@@ -236,23 +282,38 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
236
282
|
throw new InvalidParametersError('Metric name is required')
|
|
237
283
|
}
|
|
238
284
|
|
|
239
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
240
|
-
|
|
241
285
|
if (isCalculatedMetricOptions<CalculatedMetricOptions>(opts)) {
|
|
242
|
-
|
|
243
|
-
|
|
286
|
+
let counter = this.observables.get(name)
|
|
287
|
+
|
|
288
|
+
if (counter != null) {
|
|
289
|
+
return
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
counter = this.meter.createObservableCounter(name, {
|
|
244
293
|
description: opts?.help ?? name
|
|
245
294
|
})
|
|
295
|
+
|
|
296
|
+
const calculate = opts.calculate
|
|
246
297
|
counter.addCallback(async (result) => {
|
|
247
298
|
result.observe(await calculate())
|
|
248
299
|
})
|
|
249
300
|
|
|
301
|
+
this.observables.set(name, counter)
|
|
302
|
+
|
|
250
303
|
return
|
|
251
304
|
}
|
|
252
305
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
306
|
+
let metric = this.metrics.get(name)
|
|
307
|
+
|
|
308
|
+
if (metric == null) {
|
|
309
|
+
metric = new OpenTelemetryCounter(this.meter.createCounter(name, {
|
|
310
|
+
description: opts?.help ?? name
|
|
311
|
+
}))
|
|
312
|
+
|
|
313
|
+
this.metrics.set(name, metric)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return metric
|
|
256
317
|
}
|
|
257
318
|
|
|
258
319
|
registerCounterGroup (name: string, opts: CalculatedMetricOptions<Record<string, number>>): void
|
|
@@ -262,15 +323,21 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
262
323
|
throw new InvalidParametersError('Metric name is required')
|
|
263
324
|
}
|
|
264
325
|
|
|
265
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
266
326
|
const label = opts?.label ?? name
|
|
267
327
|
|
|
268
328
|
if (isCalculatedMetricOptions<CalculatedMetricOptions<Record<string, number>>>(opts)) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
329
|
+
let counter = this.observables.get(name)
|
|
330
|
+
|
|
331
|
+
if (counter != null) {
|
|
332
|
+
return
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
counter = this.meter.createObservableCounter(name, {
|
|
272
336
|
description: opts?.help ?? name
|
|
273
337
|
})
|
|
338
|
+
|
|
339
|
+
const values: Record<string, number> = {}
|
|
340
|
+
const calculate = opts.calculate
|
|
274
341
|
counter.addCallback(async (observable) => {
|
|
275
342
|
const observed = await calculate()
|
|
276
343
|
|
|
@@ -290,9 +357,17 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
290
357
|
return
|
|
291
358
|
}
|
|
292
359
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
360
|
+
let metric = this.metrics.get(name)
|
|
361
|
+
|
|
362
|
+
if (metric == null) {
|
|
363
|
+
metric = new OpenTelemetryCounterGroup(label, this.meter.createCounter(name, {
|
|
364
|
+
description: opts?.help ?? name
|
|
365
|
+
}))
|
|
366
|
+
|
|
367
|
+
this.metrics.set(name, metric)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return metric
|
|
296
371
|
}
|
|
297
372
|
|
|
298
373
|
registerHistogram (name: string, opts: CalculatedHistogramOptions): void
|
|
@@ -302,18 +377,24 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
302
377
|
throw new InvalidParametersError('Metric name is required')
|
|
303
378
|
}
|
|
304
379
|
|
|
305
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
306
|
-
|
|
307
380
|
if (isCalculatedMetricOptions<CalculatedHistogramOptions>(opts)) {
|
|
308
381
|
return
|
|
309
382
|
}
|
|
310
383
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
384
|
+
let metric = this.metrics.get(name)
|
|
385
|
+
|
|
386
|
+
if (metric == null) {
|
|
387
|
+
metric = new OpenTelemetryHistogram(this.meter.createHistogram(name, {
|
|
388
|
+
advice: {
|
|
389
|
+
explicitBucketBoundaries: opts.buckets
|
|
390
|
+
},
|
|
391
|
+
description: opts?.help ?? name
|
|
392
|
+
}))
|
|
393
|
+
|
|
394
|
+
this.metrics.set(name, metric)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return metric
|
|
317
398
|
}
|
|
318
399
|
|
|
319
400
|
registerHistogramGroup (name: string, opts: CalculatedHistogramOptions<Record<string, number>>): void
|
|
@@ -323,19 +404,26 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
323
404
|
throw new InvalidParametersError('Metric name is required')
|
|
324
405
|
}
|
|
325
406
|
|
|
326
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
327
407
|
const label = opts?.label ?? name
|
|
328
408
|
|
|
329
409
|
if (isCalculatedMetricOptions<CalculatedHistogramOptions<Record<string, number>>>(opts)) {
|
|
330
410
|
return
|
|
331
411
|
}
|
|
332
412
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
413
|
+
let metric = this.metrics.get(name)
|
|
414
|
+
|
|
415
|
+
if (metric == null) {
|
|
416
|
+
metric = new OpenTelemetryHistogramGroup(label, this.meter.createHistogram(name, {
|
|
417
|
+
advice: {
|
|
418
|
+
explicitBucketBoundaries: opts.buckets
|
|
419
|
+
},
|
|
420
|
+
description: opts?.help ?? name
|
|
421
|
+
}))
|
|
422
|
+
|
|
423
|
+
this.metrics.set(name, metric)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return metric
|
|
339
427
|
}
|
|
340
428
|
|
|
341
429
|
registerSummary (name: string, opts: CalculatedSummaryOptions): void
|
|
@@ -345,15 +433,21 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
345
433
|
throw new InvalidParametersError('Metric name is required')
|
|
346
434
|
}
|
|
347
435
|
|
|
348
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
349
|
-
|
|
350
436
|
if (isCalculatedMetricOptions<CalculatedHistogramOptions>(opts)) {
|
|
351
437
|
return
|
|
352
438
|
}
|
|
353
439
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
440
|
+
let metric = this.metrics.get(name)
|
|
441
|
+
|
|
442
|
+
if (metric == null) {
|
|
443
|
+
metric = new OpenTelemetrySummary(this.meter.createGauge(name, {
|
|
444
|
+
description: opts?.help ?? name
|
|
445
|
+
}))
|
|
446
|
+
|
|
447
|
+
this.metrics.set(name, metric)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return metric
|
|
357
451
|
}
|
|
358
452
|
|
|
359
453
|
registerSummaryGroup (name: string, opts: CalculatedSummaryOptions<Record<string, number>>): void
|
|
@@ -363,16 +457,23 @@ class OpenTelemetryMetrics implements Metrics {
|
|
|
363
457
|
throw new InvalidParametersError('Metric name is required')
|
|
364
458
|
}
|
|
365
459
|
|
|
366
|
-
const meter = metrics.getMeterProvider().getMeter(this.meterName)
|
|
367
460
|
const label = opts?.label ?? name
|
|
368
461
|
|
|
369
462
|
if (isCalculatedMetricOptions<CalculatedSummaryOptions>(opts)) {
|
|
370
463
|
return
|
|
371
464
|
}
|
|
372
465
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
466
|
+
let metric = this.metrics.get(name)
|
|
467
|
+
|
|
468
|
+
if (metric == null) {
|
|
469
|
+
metric = new OpenTelemetrySummaryGroup(label, this.meter.createGauge(name, {
|
|
470
|
+
description: opts?.help ?? name
|
|
471
|
+
}))
|
|
472
|
+
|
|
473
|
+
this.metrics.set(name, metric)
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return metric
|
|
376
477
|
}
|
|
377
478
|
|
|
378
479
|
createTrace (): any {
|