@aztec/telemetry-client 0.0.0-test.0 → 0.0.1-commit.21caa21
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/dest/attributes.d.ts +24 -9
- package/dest/attributes.d.ts.map +1 -1
- package/dest/attributes.js +17 -8
- package/dest/bench.d.ts +4 -1
- package/dest/bench.d.ts.map +1 -1
- package/dest/bench.js +7 -0
- package/dest/config.d.ts +7 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +29 -1
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/l1_metrics.d.ts +17 -0
- package/dest/l1_metrics.d.ts.map +1 -0
- package/dest/l1_metrics.js +70 -0
- package/dest/lmdb_metrics.d.ts +4 -2
- package/dest/lmdb_metrics.d.ts.map +1 -1
- package/dest/lmdb_metrics.js +8 -0
- package/dest/metrics.d.ts +98 -13
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +98 -13
- package/dest/nodejs_metrics_monitor.d.ts +21 -0
- package/dest/nodejs_metrics_monitor.d.ts.map +1 -0
- package/dest/{event_loop_monitor.js → nodejs_metrics_monitor.js} +55 -12
- package/dest/noop.d.ts +4 -2
- package/dest/noop.d.ts.map +1 -1
- package/dest/noop.js +2 -0
- package/dest/otel.d.ts +9 -5
- package/dest/otel.d.ts.map +1 -1
- package/dest/otel.js +93 -19
- package/dest/otel_filter_metric_exporter.d.ts +12 -4
- package/dest/otel_filter_metric_exporter.d.ts.map +1 -1
- package/dest/otel_filter_metric_exporter.js +38 -4
- package/dest/otel_logger_provider.d.ts +1 -1
- package/dest/otel_propagation.d.ts +1 -1
- package/dest/otel_resource.d.ts +1 -1
- package/dest/otel_resource.d.ts.map +1 -1
- package/dest/otel_resource.js +31 -2
- package/dest/prom_otel_adapter.d.ts +58 -9
- package/dest/prom_otel_adapter.d.ts.map +1 -1
- package/dest/prom_otel_adapter.js +143 -43
- package/dest/start.d.ts +1 -1
- package/dest/start.js +4 -4
- package/dest/telemetry.d.ts +29 -12
- package/dest/telemetry.d.ts.map +1 -1
- package/dest/telemetry.js +1 -1
- package/dest/vendor/attributes.d.ts +1 -1
- package/dest/vendor/otel-pino-stream.d.ts +1 -2
- package/dest/vendor/otel-pino-stream.d.ts.map +1 -1
- package/dest/vendor/otel-pino-stream.js +2 -2
- package/dest/with_tracer.d.ts +1 -1
- package/dest/with_tracer.d.ts.map +1 -1
- package/dest/wrappers/fetch.d.ts +2 -2
- package/dest/wrappers/fetch.d.ts.map +1 -1
- package/dest/wrappers/fetch.js +7 -5
- package/dest/wrappers/index.d.ts +1 -1
- package/dest/wrappers/json_rpc_server.d.ts +2 -2
- package/dest/wrappers/json_rpc_server.d.ts.map +1 -1
- package/dest/wrappers/l2_block_stream.d.ts +2 -2
- package/dest/wrappers/l2_block_stream.d.ts.map +1 -1
- package/package.json +19 -15
- package/src/attributes.ts +29 -11
- package/src/bench.ts +15 -5
- package/src/config.ts +54 -2
- package/src/index.ts +1 -0
- package/src/l1_metrics.ts +80 -0
- package/src/lmdb_metrics.ts +24 -3
- package/src/metrics.ts +118 -12
- package/src/{event_loop_monitor.ts → nodejs_metrics_monitor.ts} +59 -10
- package/src/noop.ts +4 -1
- package/src/otel.ts +80 -21
- package/src/otel_filter_metric_exporter.ts +47 -5
- package/src/otel_resource.ts +40 -2
- package/src/prom_otel_adapter.ts +191 -59
- package/src/start.ts +4 -4
- package/src/telemetry.ts +50 -12
- package/src/vendor/otel-pino-stream.ts +1 -4
- package/src/wrappers/fetch.ts +24 -31
- package/src/wrappers/json_rpc_server.ts +1 -1
- package/src/wrappers/l2_block_stream.ts +1 -1
- package/dest/event_loop_monitor.d.ts +0 -18
- package/dest/event_loop_monitor.d.ts.map +0 -1
package/src/prom_otel_adapter.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
2
3
|
|
|
3
4
|
import { Registry } from 'prom-client';
|
|
4
5
|
|
|
5
|
-
import type { Meter, MetricsType, ObservableGauge, TelemetryClient } from './telemetry.js';
|
|
6
|
+
import type { Histogram, Meter, MetricsType, ObservableGauge, TelemetryClient } from './telemetry.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Types matching the gossipsub and libp2p services
|
|
@@ -125,7 +126,7 @@ export class OtelGauge<Labels extends LabelsGeneric = NoLabels> implements IGaug
|
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
for (const [labelStr, value] of this.labeledValues.entries()) {
|
|
128
|
-
const labels =
|
|
129
|
+
const labels = parseLabelsSafely(labelStr, this.logger);
|
|
129
130
|
if (labels) {
|
|
130
131
|
result.observe(value, labels);
|
|
131
132
|
}
|
|
@@ -146,7 +147,7 @@ export class OtelGauge<Labels extends LabelsGeneric = NoLabels> implements IGaug
|
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
if (labelsOrValue) {
|
|
149
|
-
|
|
150
|
+
validateLabels(labelsOrValue, this.labelNames, 'Gauge');
|
|
150
151
|
const labelKey = JSON.stringify(labelsOrValue);
|
|
151
152
|
const currentValue = this.labeledValues.get(labelKey) ?? 0;
|
|
152
153
|
this.labeledValues.set(labelKey, currentValue + (value ?? 1));
|
|
@@ -169,7 +170,7 @@ export class OtelGauge<Labels extends LabelsGeneric = NoLabels> implements IGaug
|
|
|
169
170
|
return;
|
|
170
171
|
}
|
|
171
172
|
|
|
172
|
-
|
|
173
|
+
validateLabels(labelsOrValue, this.labelNames, 'Gauge');
|
|
173
174
|
const labelKey = JSON.stringify(labelsOrValue);
|
|
174
175
|
this.labeledValues.set(labelKey, value!);
|
|
175
176
|
}
|
|
@@ -180,7 +181,7 @@ export class OtelGauge<Labels extends LabelsGeneric = NoLabels> implements IGaug
|
|
|
180
181
|
*/
|
|
181
182
|
dec(labels?: Labels): void {
|
|
182
183
|
if (labels) {
|
|
183
|
-
|
|
184
|
+
validateLabels(labels, this.labelNames, 'Gauge');
|
|
184
185
|
const labelKey = JSON.stringify(labels);
|
|
185
186
|
const currentValue = this.labeledValues.get(labelKey) ?? 0;
|
|
186
187
|
this.labeledValues.set(labelKey, currentValue - 1);
|
|
@@ -197,84 +198,215 @@ export class OtelGauge<Labels extends LabelsGeneric = NoLabels> implements IGaug
|
|
|
197
198
|
this.currentValue = 0;
|
|
198
199
|
this.labeledValues.clear();
|
|
199
200
|
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Implementation of a Histogram collector
|
|
205
|
+
*/
|
|
206
|
+
export class OtelHistogram<Labels extends LabelsGeneric = NoLabels> implements IHistogram<Labels> {
|
|
207
|
+
private histogram: Histogram;
|
|
208
|
+
|
|
209
|
+
constructor(
|
|
210
|
+
private logger: Logger,
|
|
211
|
+
meter: Meter,
|
|
212
|
+
name: string,
|
|
213
|
+
help: string,
|
|
214
|
+
buckets: number[] = [],
|
|
215
|
+
private labelNames: Array<keyof Labels> = [],
|
|
216
|
+
) {
|
|
217
|
+
this.histogram = meter.createHistogram(name as MetricsType, {
|
|
218
|
+
description: help,
|
|
219
|
+
advice: buckets.length ? { explicitBucketBoundaries: buckets } : undefined,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
200
222
|
|
|
201
223
|
/**
|
|
202
|
-
*
|
|
203
|
-
* @param labels -
|
|
204
|
-
* @throws Error if invalid labels are provided
|
|
224
|
+
* Starts a timer and returns a function that when called will record the time elapsed
|
|
225
|
+
* @param labels - Optional labels for the observation
|
|
205
226
|
*/
|
|
206
|
-
|
|
207
|
-
if (
|
|
208
|
-
|
|
227
|
+
startTimer(labels?: Labels): () => void {
|
|
228
|
+
if (labels) {
|
|
229
|
+
validateLabels(labels, this.labelNames, 'Histogram');
|
|
209
230
|
}
|
|
210
231
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
232
|
+
const timer = new Timer();
|
|
233
|
+
return () => {
|
|
234
|
+
// Use timer.s() here to get the duration in seconds since this is only currently used by gossipsub_heartbeat_duration_seconds
|
|
235
|
+
const duration = timer.s();
|
|
236
|
+
if (labels) {
|
|
237
|
+
this.observe(labels, duration);
|
|
238
|
+
} else {
|
|
239
|
+
this.observe(duration);
|
|
214
240
|
}
|
|
215
|
-
}
|
|
241
|
+
};
|
|
216
242
|
}
|
|
217
243
|
|
|
218
244
|
/**
|
|
219
|
-
*
|
|
220
|
-
* @param
|
|
221
|
-
|
|
245
|
+
* Observes a value
|
|
246
|
+
* @param value - Value to observe
|
|
247
|
+
*/
|
|
248
|
+
observe(value: number): void;
|
|
249
|
+
/**
|
|
250
|
+
* Observes a value with labels
|
|
251
|
+
* @param labels - Labels object
|
|
252
|
+
* @param value - Value to observe
|
|
222
253
|
*/
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
254
|
+
observe(labels: Labels, value: number): void;
|
|
255
|
+
observe(labelsOrValue: Labels | number, value?: number): void {
|
|
256
|
+
if (typeof labelsOrValue === 'number') {
|
|
257
|
+
this.histogram.record(labelsOrValue);
|
|
258
|
+
} else {
|
|
259
|
+
validateLabels(labelsOrValue, this.labelNames, 'Histogram');
|
|
260
|
+
this.histogram.record(value!, labelsOrValue);
|
|
229
261
|
}
|
|
230
262
|
}
|
|
263
|
+
|
|
264
|
+
reset(): void {
|
|
265
|
+
// OpenTelemetry histograms cannot be reset, but we implement the interface
|
|
266
|
+
this.logger.silent('OpenTelemetry histograms cannot be fully reset');
|
|
267
|
+
}
|
|
231
268
|
}
|
|
232
269
|
|
|
233
270
|
/**
|
|
234
|
-
*
|
|
271
|
+
* Implementation of an AvgMinMax collector
|
|
235
272
|
*/
|
|
236
|
-
class
|
|
273
|
+
export class OtelAvgMinMax<Labels extends LabelsGeneric = NoLabels> implements IAvgMinMax<Labels> {
|
|
274
|
+
private gauges: {
|
|
275
|
+
avg: ObservableGauge;
|
|
276
|
+
min: ObservableGauge;
|
|
277
|
+
max: ObservableGauge;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
private currentValues: number[] = [];
|
|
281
|
+
private labeledValues: Map<string, number[]> = new Map();
|
|
282
|
+
|
|
237
283
|
constructor(
|
|
238
284
|
private logger: Logger,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
285
|
+
meter: Meter,
|
|
286
|
+
name: string,
|
|
287
|
+
help: string,
|
|
288
|
+
private labelNames: Array<keyof Labels> = [],
|
|
289
|
+
) {
|
|
290
|
+
// Create three separate gauges for avg, min, and max
|
|
291
|
+
this.gauges = {
|
|
292
|
+
avg: meter.createObservableGauge(`${name}_avg` as MetricsType, {
|
|
293
|
+
description: `${help} (average)`,
|
|
294
|
+
}),
|
|
295
|
+
min: meter.createObservableGauge(`${name}_min` as MetricsType, {
|
|
296
|
+
description: `${help} (minimum)`,
|
|
297
|
+
}),
|
|
298
|
+
max: meter.createObservableGauge(`${name}_max` as MetricsType, {
|
|
299
|
+
description: `${help} (maximum)`,
|
|
300
|
+
}),
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
// Register callbacks for each gauge
|
|
304
|
+
this.gauges.avg.addCallback(this.observeAvg.bind(this));
|
|
305
|
+
this.gauges.min.addCallback(this.observeMin.bind(this));
|
|
306
|
+
this.gauges.max.addCallback(this.observeMax.bind(this));
|
|
253
307
|
}
|
|
254
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Sets the values for calculating avg, min, max
|
|
311
|
+
* @param values - Array of values
|
|
312
|
+
*/
|
|
313
|
+
set(values: number[]): void;
|
|
314
|
+
/**
|
|
315
|
+
* Sets the values for calculating avg, min, max with labels
|
|
316
|
+
* @param labels - Labels object
|
|
317
|
+
* @param values - Array of values
|
|
318
|
+
*/
|
|
319
|
+
set(labels: Labels, values: number[]): void;
|
|
320
|
+
set(labelsOrValues: number[] | Labels, values?: number[]): void {
|
|
321
|
+
if (Array.isArray(labelsOrValues)) {
|
|
322
|
+
this.currentValues = labelsOrValues;
|
|
323
|
+
return;
|
|
324
|
+
} else {
|
|
325
|
+
validateLabels(labelsOrValues, this.labelNames, 'AvgMinMax');
|
|
326
|
+
const labelKey = JSON.stringify(labelsOrValues);
|
|
327
|
+
this.labeledValues.set(labelKey, values || []);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Resets all stored values
|
|
333
|
+
*/
|
|
255
334
|
reset(): void {
|
|
256
|
-
|
|
257
|
-
this.
|
|
335
|
+
this.currentValues = [];
|
|
336
|
+
this.labeledValues.clear();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* General function to observe an aggregation
|
|
341
|
+
* @param result - Observer result
|
|
342
|
+
* @param aggregateFn - Function that calculates the aggregation
|
|
343
|
+
*/
|
|
344
|
+
private observeAggregation(result: any, aggregateFn: (arr: number[]) => number): void {
|
|
345
|
+
// Observe unlabeled values
|
|
346
|
+
if (this.currentValues.length > 0) {
|
|
347
|
+
result.observe(aggregateFn(this.currentValues));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Observe labeled values
|
|
351
|
+
for (const [labelStr, values] of this.labeledValues.entries()) {
|
|
352
|
+
if (values.length > 0) {
|
|
353
|
+
const labels = parseLabelsSafely(labelStr, this.logger);
|
|
354
|
+
if (labels) {
|
|
355
|
+
result.observe(aggregateFn(values), labels);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
private observeAvg(result: any): void {
|
|
362
|
+
this.observeAggregation(result, arr => arr.reduce((sum, val) => sum + val, 0) / arr.length);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
private observeMin(result: any): void {
|
|
366
|
+
this.observeAggregation(result, arr => Math.min.apply(null, arr));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private observeMax(result: any): void {
|
|
370
|
+
this.observeAggregation(result, arr => Math.max.apply(null, arr));
|
|
258
371
|
}
|
|
259
372
|
}
|
|
260
373
|
|
|
261
374
|
/**
|
|
262
|
-
*
|
|
375
|
+
* Validates that provided labels match the expected schema
|
|
376
|
+
* @param labels - Labels object to validate
|
|
377
|
+
* @param labelNames - Array of allowed label names
|
|
378
|
+
* @param metricType - Type of metric for error message ('Gauge', 'Histogram', 'AvgMinMax')
|
|
379
|
+
* @throws Error if invalid labels are provided
|
|
263
380
|
*/
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
381
|
+
function validateLabels<Labels extends LabelsGeneric>(
|
|
382
|
+
labels: Labels,
|
|
383
|
+
labelNames: Array<keyof Labels>,
|
|
384
|
+
metricType: string,
|
|
385
|
+
): void {
|
|
386
|
+
if (labelNames.length === 0) {
|
|
387
|
+
throw new Error(`${metricType} was initialized without labels support`);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
for (const key of Object.keys(labels)) {
|
|
391
|
+
if (!labelNames.includes(key as keyof Labels)) {
|
|
392
|
+
throw new Error(`Invalid label key: ${key}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Safely parses label string back to object
|
|
399
|
+
* @param labelStr - Stringified labels object
|
|
400
|
+
* @param logger - Logger instance for error reporting
|
|
401
|
+
* @returns Labels object or null if parsing fails
|
|
402
|
+
*/
|
|
403
|
+
function parseLabelsSafely<Labels extends LabelsGeneric>(labelStr: string, logger: Logger): Labels | null {
|
|
404
|
+
try {
|
|
405
|
+
return JSON.parse(labelStr) as Labels;
|
|
406
|
+
} catch {
|
|
407
|
+
logger.error(`Failed to parse label string: ${labelStr}`);
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
278
410
|
}
|
|
279
411
|
|
|
280
412
|
/**
|
|
@@ -304,7 +436,7 @@ export class OtelMetricsAdapter extends Registry implements MetricsRegister {
|
|
|
304
436
|
}
|
|
305
437
|
|
|
306
438
|
histogram<Labels extends LabelsGeneric = NoLabels>(configuration: HistogramConfig<Labels>): IHistogram<Labels> {
|
|
307
|
-
return new
|
|
439
|
+
return new OtelHistogram<Labels>(
|
|
308
440
|
this.logger,
|
|
309
441
|
this.meter,
|
|
310
442
|
configuration.name as MetricsType,
|
|
@@ -315,7 +447,7 @@ export class OtelMetricsAdapter extends Registry implements MetricsRegister {
|
|
|
315
447
|
}
|
|
316
448
|
|
|
317
449
|
avgMinMax<Labels extends LabelsGeneric = NoLabels>(configuration: AvgMinMaxConfig<Labels>): IAvgMinMax<Labels> {
|
|
318
|
-
return new
|
|
450
|
+
return new OtelAvgMinMax<Labels>(
|
|
319
451
|
this.logger,
|
|
320
452
|
this.meter,
|
|
321
453
|
configuration.name as MetricsType,
|
package/src/start.ts
CHANGED
|
@@ -7,24 +7,24 @@ import type { TelemetryClient } from './telemetry.js';
|
|
|
7
7
|
|
|
8
8
|
export * from './config.js';
|
|
9
9
|
|
|
10
|
-
let
|
|
10
|
+
let initialized = false;
|
|
11
11
|
let telemetry: TelemetryClient = new NoopTelemetryClient();
|
|
12
12
|
|
|
13
13
|
export function initTelemetryClient(config: TelemetryClientConfig): TelemetryClient {
|
|
14
14
|
const log = createLogger('telemetry:client');
|
|
15
|
-
if (
|
|
15
|
+
if (initialized) {
|
|
16
16
|
log.warn('Telemetry client has already been initialized once');
|
|
17
17
|
return telemetry;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
if (config.metricsCollectorUrl) {
|
|
20
|
+
if (config.metricsCollectorUrl || config.publicMetricsCollectorUrl) {
|
|
21
21
|
log.info(`Using OpenTelemetry client with custom collector`);
|
|
22
22
|
telemetry = OpenTelemetryClient.createAndStart(config, log);
|
|
23
23
|
} else {
|
|
24
24
|
log.info('Using NoopTelemetryClient');
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
initialized = true;
|
|
28
28
|
return telemetry;
|
|
29
29
|
}
|
|
30
30
|
|
package/src/telemetry.ts
CHANGED
|
@@ -24,21 +24,49 @@ export { type Span, SpanStatusCode, ValueType } from '@opentelemetry/api';
|
|
|
24
24
|
|
|
25
25
|
type ValuesOf<T> = T extends Record<string, infer U> ? U : never;
|
|
26
26
|
|
|
27
|
+
type AttributeNames = ValuesOf<typeof Attributes>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* This is a set of attributes that could lead to high cardinality in the metrics.
|
|
31
|
+
* If you find yourself wanting to capture this data in a metric consider if it makes sense to capture
|
|
32
|
+
* as the metric value instead of an attribute or consider logging instead.
|
|
33
|
+
*
|
|
34
|
+
* Think twice before removing an attribute from this list.
|
|
35
|
+
*/
|
|
36
|
+
type BannedMetricAttributeNames = (typeof Attributes)[
|
|
37
|
+
| 'BLOCK_NUMBER'
|
|
38
|
+
| 'BLOCK_ARCHIVE'
|
|
39
|
+
| 'SLOT_NUMBER'
|
|
40
|
+
| 'BLOCK_PARENT'
|
|
41
|
+
| 'BLOCK_CANDIDATE_TXS_COUNT'
|
|
42
|
+
| 'BLOCK_TXS_COUNT'
|
|
43
|
+
| 'BLOCK_SIZE'
|
|
44
|
+
| 'EPOCH_SIZE'
|
|
45
|
+
| 'EPOCH_NUMBER'
|
|
46
|
+
| 'TX_HASH'
|
|
47
|
+
| 'PROVING_JOB_ID'
|
|
48
|
+
| 'P2P_ID'
|
|
49
|
+
| 'P2P_REQ_RESP_BATCH_REQUESTS_COUNT'
|
|
50
|
+
| 'TARGET_ADDRESS'
|
|
51
|
+
| 'MANA_USED'
|
|
52
|
+
| 'TOTAL_INSTRUCTIONS'];
|
|
53
|
+
|
|
27
54
|
/** Global registry of attributes */
|
|
28
|
-
type AttributesType = Partial<Record<
|
|
29
|
-
|
|
55
|
+
export type AttributesType = Partial<Record<AttributeNames, AttributeValue>>;
|
|
56
|
+
|
|
57
|
+
/** Subset of attributes allowed to be added to metrics */
|
|
58
|
+
export type MetricAttributesType = Partial<Record<Exclude<AttributeNames, BannedMetricAttributeNames>, AttributeValue>>;
|
|
30
59
|
|
|
31
60
|
/** Global registry of metrics */
|
|
32
|
-
type MetricsType = (typeof Metrics)[keyof typeof Metrics];
|
|
33
|
-
export type { MetricsType };
|
|
61
|
+
export type MetricsType = (typeof Metrics)[keyof typeof Metrics];
|
|
34
62
|
|
|
35
|
-
export type Gauge = OtelGauge<
|
|
36
|
-
export type Histogram = OtelHistogram<
|
|
37
|
-
export type UpDownCounter = OtelUpDownCounter<
|
|
38
|
-
export type ObservableGauge = OtelObservableGauge<
|
|
39
|
-
export type ObservableUpDownCounter = OtelObservableUpDownCounter<
|
|
40
|
-
export type ObservableResult = OtelObservableResult<
|
|
41
|
-
export type BatchObservableResult = OtelBatchObservableResult<
|
|
63
|
+
export type Gauge = OtelGauge<MetricAttributesType>;
|
|
64
|
+
export type Histogram = OtelHistogram<MetricAttributesType>;
|
|
65
|
+
export type UpDownCounter = OtelUpDownCounter<MetricAttributesType>;
|
|
66
|
+
export type ObservableGauge = OtelObservableGauge<MetricAttributesType>;
|
|
67
|
+
export type ObservableUpDownCounter = OtelObservableUpDownCounter<MetricAttributesType>;
|
|
68
|
+
export type ObservableResult = OtelObservableResult<MetricAttributesType>;
|
|
69
|
+
export type BatchObservableResult = OtelBatchObservableResult<MetricAttributesType>;
|
|
42
70
|
|
|
43
71
|
export type { Tracer };
|
|
44
72
|
|
|
@@ -122,6 +150,16 @@ export interface TelemetryClient {
|
|
|
122
150
|
* Flushes the telemetry client.
|
|
123
151
|
*/
|
|
124
152
|
flush(): Promise<void>;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Updates what telemetry is exported to the public collector
|
|
156
|
+
*/
|
|
157
|
+
setExportedPublicTelemetry(prefixes: string[]): void;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Updates the roles that would share telemetry (if enabled)
|
|
161
|
+
*/
|
|
162
|
+
setPublicTelemetryCollectFrom(roles: string[]): void;
|
|
125
163
|
}
|
|
126
164
|
|
|
127
165
|
/** Objects that adhere to this interface can use @trackSpan */
|
|
@@ -165,7 +203,7 @@ export function trackSpan<T extends Traceable, F extends (...args: any[]) => any
|
|
|
165
203
|
// run originalMethod wrapped in an active span
|
|
166
204
|
// "active" means the span will be alive for the duration of the function execution
|
|
167
205
|
// and if any other spans are started during the execution of originalMethod, they will be children of this span
|
|
168
|
-
// behind the scenes this uses AsyncLocalStorage https://nodejs.org/dist/latest-
|
|
206
|
+
// behind the scenes this uses AsyncLocalStorage https://nodejs.org/dist/latest-v22.x/docs/api/async_context.html
|
|
169
207
|
return this.tracer.startActiveSpan(name, async (span: Span) => {
|
|
170
208
|
span.setAttributes(currentAttrs ?? {});
|
|
171
209
|
|
|
@@ -23,9 +23,6 @@ import { Writable } from 'stream';
|
|
|
23
23
|
import { registerOtelLoggerProvider } from '../otel_logger_provider.js';
|
|
24
24
|
import { getOtelResource } from '../otel_resource.js';
|
|
25
25
|
|
|
26
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
27
|
-
/* eslint-disable camelcase */
|
|
28
|
-
|
|
29
26
|
// This block is a copy (modulo code style and TypeScript types) of the Pino
|
|
30
27
|
// code that defines log level value and names. This file is part of
|
|
31
28
|
// *instrumenting* Pino, so we want to avoid a dependency on the library.
|
|
@@ -173,7 +170,7 @@ export class OTelPinoStream extends Writable {
|
|
|
173
170
|
return;
|
|
174
171
|
}
|
|
175
172
|
|
|
176
|
-
// Parse, and handle edge cases similar to how `pino-
|
|
173
|
+
// Parse, and handle edge cases similar to how `pino-abstract-transport` does:
|
|
177
174
|
// https://github.com/pinojs/pino-abstract-transport/blob/v1.2.0/index.js#L28-L45
|
|
178
175
|
// - Emitting an 'unknown' event on parse error mimicks pino-abstract-transport.
|
|
179
176
|
let recObj;
|
package/src/wrappers/fetch.ts
CHANGED
|
@@ -15,38 +15,31 @@ import { ATTR_JSONRPC_METHOD, ATTR_JSONRPC_REQUEST_ID } from '../vendor/attribut
|
|
|
15
15
|
* @returns A fetch function.
|
|
16
16
|
*/
|
|
17
17
|
export function makeTracedFetch(retries: number[], defaultNoRetry: boolean, fetch = defaultFetch, log?: Logger) {
|
|
18
|
-
return (
|
|
19
|
-
host: string,
|
|
20
|
-
rpcMethod: string,
|
|
21
|
-
body: any,
|
|
22
|
-
useApiEndpoints: boolean,
|
|
23
|
-
extraHeaders: Record<string, string> = {},
|
|
24
|
-
noRetry?: boolean,
|
|
25
|
-
) => {
|
|
18
|
+
return (host: string, body: unknown, extraHeaders: Record<string, string> = {}, noRetry?: boolean) => {
|
|
26
19
|
const telemetry = getTelemetryClient();
|
|
27
|
-
return telemetry
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (body && typeof body.id === 'number') {
|
|
32
|
-
span.setAttribute(ATTR_JSONRPC_REQUEST_ID, body.id);
|
|
33
|
-
}
|
|
34
|
-
span.setAttribute(ATTR_JSONRPC_METHOD, rpcMethod);
|
|
35
|
-
const headers = { ...extraHeaders };
|
|
36
|
-
propagation.inject(context.active(), headers);
|
|
37
|
-
return await retry(
|
|
38
|
-
() => fetch(host, rpcMethod, body, useApiEndpoints, headers, noRetry ?? defaultNoRetry),
|
|
39
|
-
`JsonRpcClient request ${rpcMethod} to ${host}`,
|
|
40
|
-
makeBackoff(retries),
|
|
41
|
-
log,
|
|
42
|
-
false,
|
|
43
|
-
);
|
|
44
|
-
} catch (err: any) {
|
|
45
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: err?.message ?? String(err) });
|
|
46
|
-
throw err;
|
|
47
|
-
} finally {
|
|
48
|
-
span.end();
|
|
20
|
+
return telemetry.getTracer('fetch').startActiveSpan(`JsonRpcClient`, { kind: SpanKind.CLIENT }, async span => {
|
|
21
|
+
try {
|
|
22
|
+
if (body && typeof body === 'object' && 'id' in body && typeof body.id === 'number') {
|
|
23
|
+
span.setAttribute(ATTR_JSONRPC_REQUEST_ID, body.id);
|
|
49
24
|
}
|
|
50
|
-
|
|
25
|
+
if (body && typeof body === 'object' && 'method' in body && typeof body.method === 'string') {
|
|
26
|
+
span.setAttribute(ATTR_JSONRPC_METHOD, body.method);
|
|
27
|
+
}
|
|
28
|
+
const headers = { ...extraHeaders };
|
|
29
|
+
propagation.inject(context.active(), headers);
|
|
30
|
+
return await retry(
|
|
31
|
+
() => fetch(host, body, headers, noRetry ?? defaultNoRetry),
|
|
32
|
+
`JsonRpcClient request to ${host}`,
|
|
33
|
+
makeBackoff(retries),
|
|
34
|
+
log,
|
|
35
|
+
false,
|
|
36
|
+
);
|
|
37
|
+
} catch (err: any) {
|
|
38
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: err?.message ?? String(err) });
|
|
39
|
+
throw err;
|
|
40
|
+
} finally {
|
|
41
|
+
span.end();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
51
44
|
};
|
|
52
45
|
}
|
|
@@ -6,7 +6,7 @@ import { getOtelJsonRpcPropagationMiddleware } from '../otel_propagation.js';
|
|
|
6
6
|
export function createTracedJsonRpcServer<T extends object = any>(
|
|
7
7
|
handler: T,
|
|
8
8
|
schema: ApiSchemaFor<T>,
|
|
9
|
-
options:
|
|
9
|
+
options: SafeJsonRpcServerOptions = {},
|
|
10
10
|
) {
|
|
11
11
|
return createSafeJsonRpcServer(handler, schema, {
|
|
12
12
|
...options,
|
|
@@ -10,7 +10,7 @@ import { type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client'
|
|
|
10
10
|
/** Extends an L2BlockStream with a tracer to create a new trace per iteration. */
|
|
11
11
|
export class TraceableL2BlockStream extends L2BlockStream implements Traceable {
|
|
12
12
|
constructor(
|
|
13
|
-
l2BlockSource: Pick<L2BlockSource, '
|
|
13
|
+
l2BlockSource: Pick<L2BlockSource, 'getPublishedBlocks' | 'getBlockHeader' | 'getL2Tips'>,
|
|
14
14
|
localData: L2BlockStreamLocalDataProvider,
|
|
15
15
|
handler: L2BlockStreamEventHandler,
|
|
16
16
|
public readonly tracer: Tracer,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type Meter } from './telemetry.js';
|
|
2
|
-
/**
|
|
3
|
-
* Detector for custom Aztec attributes
|
|
4
|
-
*/
|
|
5
|
-
export declare class EventLoopMonitor {
|
|
6
|
-
private meter;
|
|
7
|
-
private eventLoopDelayGauges;
|
|
8
|
-
private eventLoopUilization;
|
|
9
|
-
private eventLoopTime;
|
|
10
|
-
private started;
|
|
11
|
-
private lastELU;
|
|
12
|
-
private eventLoopDelay;
|
|
13
|
-
constructor(meter: Meter);
|
|
14
|
-
start(): void;
|
|
15
|
-
stop(): void;
|
|
16
|
-
private measure;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=event_loop_monitor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"event_loop_monitor.d.ts","sourceRoot":"","sources":["../src/event_loop_monitor.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,KAAK,EAIX,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,qBAAa,gBAAgB;IAmBf,OAAO,CAAC,KAAK;IAlBzB,OAAO,CAAC,oBAAoB,CAQ1B;IAEF,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,aAAa,CAAgB;IAErC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,cAAc,CAAoB;gBAEtB,KAAK,EAAE,KAAK;IAgChC,KAAK,IAAI,IAAI;IAab,IAAI,IAAI,IAAI;IAaZ,OAAO,CAAC,OAAO,CAyBb;CACH"}
|