@aztec-labs/telemetry-client 6.0.0-nightly.20260829
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 +143 -0
- package/dest/attributes.d.ts.map +1 -0
- package/dest/attributes.js +91 -0
- package/dest/bench.d.ts +34 -0
- package/dest/bench.d.ts.map +1 -0
- package/dest/bench.js +115 -0
- package/dest/config.d.ts +21 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +85 -0
- package/dest/index.d.ts +12 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +11 -0
- package/dest/json_rpc_server_metrics.d.ts +27 -0
- package/dest/json_rpc_server_metrics.d.ts.map +1 -0
- package/dest/json_rpc_server_metrics.js +154 -0
- package/dest/l1_metrics.d.ts +17 -0
- package/dest/l1_metrics.d.ts.map +1 -0
- package/dest/l1_metrics.js +54 -0
- package/dest/lmdb_metrics.d.ts +18 -0
- package/dest/lmdb_metrics.d.ts.map +1 -0
- package/dest/lmdb_metrics.js +34 -0
- package/dest/metric-utils.d.ts +24 -0
- package/dest/metric-utils.d.ts.map +1 -0
- package/dest/metric-utils.js +59 -0
- package/dest/metrics.d.ts +338 -0
- package/dest/metrics.d.ts.map +1 -0
- package/dest/metrics.js +1702 -0
- package/dest/monitored_batch_span_processor.d.ts +33 -0
- package/dest/monitored_batch_span_processor.d.ts.map +1 -0
- package/dest/monitored_batch_span_processor.js +111 -0
- package/dest/nodejs_metrics_monitor.d.ts +19 -0
- package/dest/nodejs_metrics_monitor.d.ts.map +1 -0
- package/dest/nodejs_metrics_monitor.js +115 -0
- package/dest/noop.d.ts +19 -0
- package/dest/noop.d.ts.map +1 -0
- package/dest/noop.js +104 -0
- package/dest/otel.d.ts +43 -0
- package/dest/otel.d.ts.map +1 -0
- package/dest/otel.js +537 -0
- package/dest/otel_filter_metric_exporter.d.ts +20 -0
- package/dest/otel_filter_metric_exporter.d.ts.map +1 -0
- package/dest/otel_filter_metric_exporter.js +67 -0
- package/dest/otel_logger_provider.d.ts +4 -0
- package/dest/otel_logger_provider.d.ts.map +1 -0
- package/dest/otel_logger_provider.js +25 -0
- package/dest/otel_propagation.d.ts +6 -0
- package/dest/otel_propagation.d.ts.map +1 -0
- package/dest/otel_propagation.js +102 -0
- package/dest/otel_resource.d.ts +3 -0
- package/dest/otel_resource.d.ts.map +1 -0
- package/dest/otel_resource.js +53 -0
- package/dest/prom_otel_adapter.d.ts +176 -0
- package/dest/prom_otel_adapter.d.ts.map +1 -0
- package/dest/prom_otel_adapter.js +292 -0
- package/dest/start.d.ts +7 -0
- package/dest/start.d.ts.map +1 -0
- package/dest/start.js +25 -0
- package/dest/telemetry.d.ts +149 -0
- package/dest/telemetry.d.ts.map +1 -0
- package/dest/telemetry.js +139 -0
- package/dest/vendor/attributes.d.ts +6 -0
- package/dest/vendor/attributes.d.ts.map +1 -0
- package/dest/vendor/attributes.js +6 -0
- package/dest/vendor/otel-pino-stream.d.ts +40 -0
- package/dest/vendor/otel-pino-stream.d.ts.map +1 -0
- package/dest/vendor/otel-pino-stream.js +229 -0
- package/dest/with_tracer.d.ts +33 -0
- package/dest/with_tracer.d.ts.map +1 -0
- package/dest/with_tracer.js +32 -0
- package/dest/wrappers/fetch.d.ts +16 -0
- package/dest/wrappers/fetch.d.ts.map +1 -0
- package/dest/wrappers/fetch.js +42 -0
- package/dest/wrappers/index.d.ts +3 -0
- package/dest/wrappers/index.d.ts.map +1 -0
- package/dest/wrappers/index.js +2 -0
- package/dest/wrappers/json_rpc_server.d.ts +4 -0
- package/dest/wrappers/json_rpc_server.d.ts.map +1 -0
- package/dest/wrappers/json_rpc_server.js +16 -0
- package/package.json +95 -0
- package/src/attributes.ts +174 -0
- package/src/bench.ts +168 -0
- package/src/config.ts +135 -0
- package/src/index.ts +11 -0
- package/src/json_rpc_server_metrics.ts +150 -0
- package/src/l1_metrics.ts +64 -0
- package/src/lmdb_metrics.ts +45 -0
- package/src/metric-utils.ts +75 -0
- package/src/metrics.ts +1802 -0
- package/src/monitored_batch_span_processor.ts +147 -0
- package/src/nodejs_metrics_monitor.ts +135 -0
- package/src/noop.ts +152 -0
- package/src/otel.ts +482 -0
- package/src/otel_filter_metric_exporter.ts +80 -0
- package/src/otel_logger_provider.ts +31 -0
- package/src/otel_propagation.ts +107 -0
- package/src/otel_resource.ts +71 -0
- package/src/prom_otel_adapter.ts +450 -0
- package/src/start.ts +42 -0
- package/src/telemetry.ts +348 -0
- package/src/vendor/attributes.ts +6 -0
- package/src/vendor/otel-pino-stream.ts +279 -0
- package/src/with_tracer.ts +35 -0
- package/src/wrappers/fetch.ts +50 -0
- package/src/wrappers/index.ts +2 -0
- package/src/wrappers/json_rpc_server.ts +26 -0
package/dest/start.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createLogger } from '@aztec-labs/foundation/log';
|
|
2
|
+
import { NoopTelemetryClient } from './noop.js';
|
|
3
|
+
export * from './config.js';
|
|
4
|
+
let initialized = false;
|
|
5
|
+
let telemetry = new NoopTelemetryClient();
|
|
6
|
+
export async function initTelemetryClient(config, bindings) {
|
|
7
|
+
const log = createLogger('telemetry:client', bindings);
|
|
8
|
+
if (initialized) {
|
|
9
|
+
log.warn('Telemetry client has already been initialized once');
|
|
10
|
+
return telemetry;
|
|
11
|
+
}
|
|
12
|
+
if (config.metricsCollectorUrl || config.publicMetricsCollectorUrl || config.tracesCollectorUrl || config.logsCollectorUrl) {
|
|
13
|
+
log.info(`Using OpenTelemetry client with custom collector`);
|
|
14
|
+
// Lazy load OpenTelemetry to avoid loading heavy deps at startup
|
|
15
|
+
const { OpenTelemetryClient } = await import('./otel.js');
|
|
16
|
+
telemetry = OpenTelemetryClient.createAndStart(config, log);
|
|
17
|
+
} else {
|
|
18
|
+
log.info('Using NoopTelemetryClient');
|
|
19
|
+
}
|
|
20
|
+
initialized = true;
|
|
21
|
+
return telemetry;
|
|
22
|
+
}
|
|
23
|
+
export function getTelemetryClient() {
|
|
24
|
+
return telemetry;
|
|
25
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { type AttributeValue, type BatchObservableCallback, type Context, type MetricOptions, type Observable, type BatchObservableResult as OtelBatchObservableResult, type Gauge as OtelGauge, type Histogram as OtelHistogram, type ObservableGauge as OtelObservableGauge, type ObservableResult as OtelObservableResult, type ObservableUpDownCounter as OtelObservableUpDownCounter, type UpDownCounter as OtelUpDownCounter, type Span, type Tracer } from '@opentelemetry/api';
|
|
2
|
+
import type * as Attributes from './attributes.js';
|
|
3
|
+
import type { MetricDefinition } from './metrics.js';
|
|
4
|
+
import type * as VendorAttributes from './vendor/attributes.js';
|
|
5
|
+
export { toMetricOptions, createUpDownCounterWithDefault } from './metric-utils.js';
|
|
6
|
+
export { type Span, SpanStatusCode, ValueType, type Context } from '@opentelemetry/api';
|
|
7
|
+
type ValuesOf<T> = T extends Record<string, infer U> ? U : never;
|
|
8
|
+
type AttributeNames = ValuesOf<typeof Attributes>;
|
|
9
|
+
type AllowedVendorMetricAttributeNames = (typeof VendorAttributes)['ATTR_JSONRPC_METHOD' | 'ATTR_JSONRPC_SERVICE'];
|
|
10
|
+
/**
|
|
11
|
+
* This is a set of attributes that could lead to high cardinality in the metrics.
|
|
12
|
+
* If you find yourself wanting to capture this data in a metric consider if it makes sense to capture
|
|
13
|
+
* as the metric value instead of an attribute or consider logging instead.
|
|
14
|
+
*
|
|
15
|
+
* Think twice before removing an attribute from this list.
|
|
16
|
+
*/
|
|
17
|
+
type BannedMetricAttributeNames = (typeof Attributes)['BLOCK_NUMBER' | 'BLOCK_ARCHIVE' | 'SLOT_NUMBER' | 'BLOCK_PARENT' | 'BLOCK_CANDIDATE_TXS_COUNT' | 'BLOCK_TXS_COUNT' | 'BLOCK_SIZE' | 'EPOCH_SIZE' | 'EPOCH_NUMBER' | 'TX_HASH' | 'PROVING_JOB_ID' | 'P2P_ID' | 'TARGET_ADDRESS' | 'MANA_USED' | 'TOTAL_INSTRUCTIONS'];
|
|
18
|
+
/** Global registry of attributes */
|
|
19
|
+
export type AttributesType = Partial<Record<AttributeNames, AttributeValue>>;
|
|
20
|
+
export type AllowedAttributeNames = Exclude<AttributeNames, BannedMetricAttributeNames> | AllowedVendorMetricAttributeNames;
|
|
21
|
+
/** Subset of attributes allowed to be added to metrics */
|
|
22
|
+
export type MetricAttributesType = Partial<Record<AllowedAttributeNames, AttributeValue>>;
|
|
23
|
+
/** Re-export MetricDefinition for convenience */
|
|
24
|
+
export type { MetricDefinition } from './metrics.js';
|
|
25
|
+
export type Gauge = OtelGauge<MetricAttributesType>;
|
|
26
|
+
export type Histogram = OtelHistogram<MetricAttributesType>;
|
|
27
|
+
export type UpDownCounter = OtelUpDownCounter<MetricAttributesType>;
|
|
28
|
+
export type ObservableGauge = OtelObservableGauge<MetricAttributesType>;
|
|
29
|
+
export type ObservableUpDownCounter = OtelObservableUpDownCounter<MetricAttributesType>;
|
|
30
|
+
export type ObservableResult = OtelObservableResult<MetricAttributesType>;
|
|
31
|
+
export type BatchObservableResult = OtelBatchObservableResult<MetricAttributesType>;
|
|
32
|
+
export type { Tracer };
|
|
33
|
+
/**
|
|
34
|
+
* A meter that provides instruments for recording metrics.
|
|
35
|
+
*/
|
|
36
|
+
export interface Meter {
|
|
37
|
+
/**
|
|
38
|
+
* Creates a new gauge instrument. A gauge is a metric that represents a single numerical value that can arbitrarily go up and down.
|
|
39
|
+
* @param metric - The metric definition
|
|
40
|
+
*/
|
|
41
|
+
createGauge(metric: MetricDefinition): Gauge;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new observable gauge instrument. A gauge is a metric that represents a single numerical value that can arbitrarily go up and down.
|
|
44
|
+
* @param metric - The metric definition
|
|
45
|
+
*/
|
|
46
|
+
createObservableGauge(metric: MetricDefinition): ObservableGauge;
|
|
47
|
+
addBatchObservableCallback(callback: BatchObservableCallback<AttributesType>, observables: Observable<AttributesType>[]): void;
|
|
48
|
+
removeBatchObservableCallback(callback: BatchObservableCallback<AttributesType>, observables: Observable<AttributesType>[]): void;
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new histogram instrument. A histogram is a metric that samples observations (usually things like request durations or response sizes) and counts them in configurable buckets.
|
|
51
|
+
* @param metric - The metric definition
|
|
52
|
+
* @param extraOptions - Optional extra options (e.g., advice for bucket boundaries)
|
|
53
|
+
*/
|
|
54
|
+
createHistogram(metric: MetricDefinition, extraOptions?: Partial<MetricOptions>): Histogram;
|
|
55
|
+
/**
|
|
56
|
+
* Creates a new counter instrument. A counter can go up or down with a delta from the previous value.
|
|
57
|
+
* @param metric - The metric definition
|
|
58
|
+
*/
|
|
59
|
+
createUpDownCounter(metric: MetricDefinition): UpDownCounter;
|
|
60
|
+
/**
|
|
61
|
+
* Creates a new observable up/down counter instrument.
|
|
62
|
+
* @param metric - The metric definition
|
|
63
|
+
*/
|
|
64
|
+
createObservableUpDownCounter(metric: MetricDefinition): ObservableUpDownCounter;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A telemetry client that provides meters for recording metrics.
|
|
68
|
+
*/
|
|
69
|
+
export interface TelemetryClient {
|
|
70
|
+
/**
|
|
71
|
+
* Whether the client is enabled and reporting metrics.
|
|
72
|
+
**/
|
|
73
|
+
isEnabled(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a new meter
|
|
76
|
+
* @param name - The name of the meter.
|
|
77
|
+
*/
|
|
78
|
+
getMeter(name: string): Meter;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new tracer
|
|
81
|
+
* @param name - The name of the tracer.
|
|
82
|
+
*/
|
|
83
|
+
getTracer(name: string): Tracer;
|
|
84
|
+
/**
|
|
85
|
+
* Stops the telemetry client.
|
|
86
|
+
*/
|
|
87
|
+
stop(): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Flushes the telemetry client.
|
|
90
|
+
*/
|
|
91
|
+
flush(): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Updates what telemetry is exported to the public collector
|
|
94
|
+
*/
|
|
95
|
+
setExportedPublicTelemetry(prefixes: string[]): void;
|
|
96
|
+
/**
|
|
97
|
+
* Updates the roles that would share telemetry (if enabled)
|
|
98
|
+
*/
|
|
99
|
+
setPublicTelemetryCollectFrom(roles: string[]): void;
|
|
100
|
+
/**
|
|
101
|
+
* Get current trace context as an opaque string for propagation.
|
|
102
|
+
* Returns the W3C traceparent header value if a trace is active, undefined otherwise.
|
|
103
|
+
*/
|
|
104
|
+
getTraceContext(): string | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Recreates a context propagated by a remote system
|
|
107
|
+
*/
|
|
108
|
+
extractPropagatedContext(traceContext: string): Context | undefined;
|
|
109
|
+
}
|
|
110
|
+
/** Objects that adhere to this interface can use @trackSpan */
|
|
111
|
+
export interface Traceable {
|
|
112
|
+
tracer: Tracer;
|
|
113
|
+
}
|
|
114
|
+
type SpanDecorator<T extends Traceable, F extends (...args: any[]) => any> = (originalMethod: F, context: ClassMethodDecoratorContext<T>) => F;
|
|
115
|
+
/**
|
|
116
|
+
* Starts a new span whenever the decorated method is called.
|
|
117
|
+
* @param spanName - The name of the span to create. Can be a string or a function that returns a string.
|
|
118
|
+
* @param attributes - Initial attributes to set on the span. If a function is provided, it will be called with the arguments of the method.
|
|
119
|
+
* @param extraAttributes - Extra attributes to set on the span after the method is called. Will be called with the return value of the method. Note: if the function throws then this will not be called.
|
|
120
|
+
* @returns A decorator that wraps the method in a span.
|
|
121
|
+
*
|
|
122
|
+
* @privateRemarks
|
|
123
|
+
* This code looks complex but it's not that difficult:
|
|
124
|
+
* - decorators are functions that _replace_ a method with a different implementation
|
|
125
|
+
* - normal decorators can't take function arguments, but if we write a function that returns a decorator, we can pass arguments to that function
|
|
126
|
+
*
|
|
127
|
+
* The trackSpan function takes a span's name and some attributes and builds a decorator that wraps a method in a span with the given name and props
|
|
128
|
+
* The decorator can currently only be applied to methods on classes that have a `tracer` property. The compiler will enforce this.
|
|
129
|
+
*/
|
|
130
|
+
export declare function trackSpan<T extends Traceable, F extends (...args: any[]) => any>(spanName: string | ((this: T, ...args: Parameters<F>) => string), attributes?: AttributesType | ((this: T, ...args: Parameters<F>) => Promise<AttributesType> | AttributesType), extraAttributes?: (this: T, returnValue: Awaited<ReturnType<F>>) => AttributesType): SpanDecorator<T, F>;
|
|
131
|
+
/**
|
|
132
|
+
* Runs an event callback in a span. The span is started immediately and completes once the callback finishes running.
|
|
133
|
+
* The span will have two events added: 'callbackStart' and 'callbackEnd' to mark the start and end of the callback.
|
|
134
|
+
*
|
|
135
|
+
* @param tracer - The tracer instance to use
|
|
136
|
+
* @param spanName - The name of the span to create
|
|
137
|
+
* @param attributes - Initial attributes to set on the span
|
|
138
|
+
* @param callback - The callback to wrap in a span
|
|
139
|
+
*
|
|
140
|
+
* @returns - A new function that wraps the callback in a span
|
|
141
|
+
*/
|
|
142
|
+
export declare function wrapCallbackInSpan<F extends (...args: any[]) => any>(tracer: Tracer, spanName: string, attributes: AttributesType, callback: F): F;
|
|
143
|
+
export declare function runInSpan<A extends any[], R>(tracer: Tracer | string, spanName: string, callback: (span: Span, ...args: A) => Promise<R>): (...args: A) => Promise<R>;
|
|
144
|
+
/**
|
|
145
|
+
* Execute a callback within a span immediately (for one-off traced calls).
|
|
146
|
+
* Unlike runInSpan which returns a reusable function, this executes right away.
|
|
147
|
+
*/
|
|
148
|
+
export declare function execInSpan<R>(tracer: Tracer | string, spanName: string, callback: (span: Span) => Promise<R>): Promise<R>;
|
|
149
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVsZW1ldHJ5LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdGVsZW1ldHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxLQUFLLGNBQWMsRUFDbkIsS0FBSyx1QkFBdUIsRUFDNUIsS0FBSyxPQUFPLEVBQ1osS0FBSyxhQUFhLEVBQ2xCLEtBQUssVUFBVSxFQUNmLEtBQUsscUJBQXFCLElBQUkseUJBQXlCLEVBQ3ZELEtBQUssS0FBSyxJQUFJLFNBQVMsRUFDdkIsS0FBSyxTQUFTLElBQUksYUFBYSxFQUMvQixLQUFLLGVBQWUsSUFBSSxtQkFBbUIsRUFDM0MsS0FBSyxnQkFBZ0IsSUFBSSxvQkFBb0IsRUFDN0MsS0FBSyx1QkFBdUIsSUFBSSwyQkFBMkIsRUFDM0QsS0FBSyxhQUFhLElBQUksaUJBQWlCLEVBQ3ZDLEtBQUssSUFBSSxFQUVULEtBQUssTUFBTSxFQUNaLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsT0FBTyxLQUFLLEtBQUssVUFBVSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXJELE9BQU8sS0FBSyxLQUFLLGdCQUFnQixNQUFNLHdCQUF3QixDQUFDO0FBRWhFLE9BQU8sRUFBRSxlQUFlLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVwRixPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxLQUFLLE9BQU8sRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXhGLEtBQUssUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7QUFFakUsS0FBSyxjQUFjLEdBQUcsUUFBUSxDQUFDLE9BQU8sVUFBVSxDQUFDLENBQUM7QUFFbEQsS0FBSyxpQ0FBaUMsR0FBRyxD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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { SpanStatusCode } from '@opentelemetry/api';
|
|
2
|
+
import { getTelemetryClient } from './start.js';
|
|
3
|
+
export { toMetricOptions, createUpDownCounterWithDefault } from './metric-utils.js';
|
|
4
|
+
export { SpanStatusCode, ValueType } from '@opentelemetry/api';
|
|
5
|
+
/**
|
|
6
|
+
* Starts a new span whenever the decorated method is called.
|
|
7
|
+
* @param spanName - The name of the span to create. Can be a string or a function that returns a string.
|
|
8
|
+
* @param attributes - Initial attributes to set on the span. If a function is provided, it will be called with the arguments of the method.
|
|
9
|
+
* @param extraAttributes - Extra attributes to set on the span after the method is called. Will be called with the return value of the method. Note: if the function throws then this will not be called.
|
|
10
|
+
* @returns A decorator that wraps the method in a span.
|
|
11
|
+
*
|
|
12
|
+
* @privateRemarks
|
|
13
|
+
* This code looks complex but it's not that difficult:
|
|
14
|
+
* - decorators are functions that _replace_ a method with a different implementation
|
|
15
|
+
* - normal decorators can't take function arguments, but if we write a function that returns a decorator, we can pass arguments to that function
|
|
16
|
+
*
|
|
17
|
+
* The trackSpan function takes a span's name and some attributes and builds a decorator that wraps a method in a span with the given name and props
|
|
18
|
+
* The decorator can currently only be applied to methods on classes that have a `tracer` property. The compiler will enforce this.
|
|
19
|
+
*/ export function trackSpan(spanName, attributes, extraAttributes) {
|
|
20
|
+
// the return value of trackSpan is a decorator
|
|
21
|
+
return (originalMethod, _context)=>{
|
|
22
|
+
// the return value of the decorator replaces the original method
|
|
23
|
+
// in this wrapper method we start a span, call the original method, and then end the span
|
|
24
|
+
return async function replacementMethod(...args) {
|
|
25
|
+
const name = typeof spanName === 'function' ? spanName.call(this, ...args) : spanName;
|
|
26
|
+
const currentAttrs = typeof attributes === 'function' ? await attributes.call(this, ...args) : attributes;
|
|
27
|
+
// run originalMethod wrapped in an active span
|
|
28
|
+
// "active" means the span will be alive for the duration of the function execution
|
|
29
|
+
// and if any other spans are started during the execution of originalMethod, they will be children of this span
|
|
30
|
+
// behind the scenes this uses AsyncLocalStorage https://nodejs.org/dist/latest-v22.x/docs/api/async_context.html
|
|
31
|
+
return this.tracer.startActiveSpan(name, {
|
|
32
|
+
attributes: currentAttrs
|
|
33
|
+
}, async (span)=>{
|
|
34
|
+
try {
|
|
35
|
+
const res = await originalMethod.call(this, ...args);
|
|
36
|
+
const extraAttrs = extraAttributes?.call(this, res);
|
|
37
|
+
span.setAttributes(extraAttrs ?? {});
|
|
38
|
+
span.setStatus({
|
|
39
|
+
code: SpanStatusCode.OK
|
|
40
|
+
});
|
|
41
|
+
return res;
|
|
42
|
+
} catch (err) {
|
|
43
|
+
span.setStatus({
|
|
44
|
+
code: SpanStatusCode.ERROR,
|
|
45
|
+
message: String(err)
|
|
46
|
+
});
|
|
47
|
+
if (typeof err === 'string' || err && err instanceof Error) {
|
|
48
|
+
span.recordException(err);
|
|
49
|
+
}
|
|
50
|
+
throw err;
|
|
51
|
+
} finally{
|
|
52
|
+
span.end();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Runs an event callback in a span. The span is started immediately and completes once the callback finishes running.
|
|
60
|
+
* The span will have two events added: 'callbackStart' and 'callbackEnd' to mark the start and end of the callback.
|
|
61
|
+
*
|
|
62
|
+
* @param tracer - The tracer instance to use
|
|
63
|
+
* @param spanName - The name of the span to create
|
|
64
|
+
* @param attributes - Initial attributes to set on the span
|
|
65
|
+
* @param callback - The callback to wrap in a span
|
|
66
|
+
*
|
|
67
|
+
* @returns - A new function that wraps the callback in a span
|
|
68
|
+
*/ export function wrapCallbackInSpan(tracer, spanName, attributes, callback) {
|
|
69
|
+
const span = tracer.startSpan(spanName, {
|
|
70
|
+
attributes
|
|
71
|
+
});
|
|
72
|
+
return async (...args)=>{
|
|
73
|
+
try {
|
|
74
|
+
span.addEvent('callbackStart');
|
|
75
|
+
const res = await callback(...args);
|
|
76
|
+
return res;
|
|
77
|
+
} catch (err) {
|
|
78
|
+
span.setStatus({
|
|
79
|
+
code: SpanStatusCode.ERROR,
|
|
80
|
+
message: String(err)
|
|
81
|
+
});
|
|
82
|
+
throw err;
|
|
83
|
+
} finally{
|
|
84
|
+
span.addEvent('callbackEnd');
|
|
85
|
+
span.end();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export function runInSpan(tracer, spanName, callback) {
|
|
90
|
+
return (...args)=>{
|
|
91
|
+
const actualTracer = typeof tracer === 'string' ? getTelemetryClient().getTracer(tracer) : tracer;
|
|
92
|
+
return actualTracer.startActiveSpan(spanName, async (span)=>{
|
|
93
|
+
try {
|
|
94
|
+
const res = await callback(span, ...args);
|
|
95
|
+
span.setStatus({
|
|
96
|
+
code: SpanStatusCode.OK
|
|
97
|
+
});
|
|
98
|
+
return res;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
span.setStatus({
|
|
101
|
+
code: SpanStatusCode.ERROR,
|
|
102
|
+
message: String(err)
|
|
103
|
+
});
|
|
104
|
+
if (typeof err === 'string' || err && err instanceof Error) {
|
|
105
|
+
span.recordException(err);
|
|
106
|
+
}
|
|
107
|
+
throw err;
|
|
108
|
+
} finally{
|
|
109
|
+
span.end();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Execute a callback within a span immediately (for one-off traced calls).
|
|
116
|
+
* Unlike runInSpan which returns a reusable function, this executes right away.
|
|
117
|
+
*/ export function execInSpan(tracer, spanName, callback) {
|
|
118
|
+
const actualTracer = typeof tracer === 'string' ? getTelemetryClient().getTracer(tracer) : tracer;
|
|
119
|
+
return actualTracer.startActiveSpan(spanName, async (span)=>{
|
|
120
|
+
try {
|
|
121
|
+
const res = await callback(span);
|
|
122
|
+
span.setStatus({
|
|
123
|
+
code: SpanStatusCode.OK
|
|
124
|
+
});
|
|
125
|
+
return res;
|
|
126
|
+
} catch (err) {
|
|
127
|
+
span.setStatus({
|
|
128
|
+
code: SpanStatusCode.ERROR,
|
|
129
|
+
message: String(err)
|
|
130
|
+
});
|
|
131
|
+
if (typeof err === 'string' || err && err instanceof Error) {
|
|
132
|
+
span.recordException(err);
|
|
133
|
+
}
|
|
134
|
+
throw err;
|
|
135
|
+
} finally{
|
|
136
|
+
span.end();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const ATTR_JSONRPC_METHOD = "rpc.method";
|
|
2
|
+
export declare const ATTR_JSONRPC_SERVICE = "rpc.service";
|
|
3
|
+
export declare const ATTR_JSONRPC_REQUEST_ID = "rpc.jsonrpc.request_id";
|
|
4
|
+
export declare const ATTR_JSONRPC_ERROR_CODE = "rpc.jsonrpc.error_code";
|
|
5
|
+
export declare const ATTR_JSONRPC_ERROR_MSG = "rpc.jsonrpc.error_message";
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0cmlidXRlcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ZlbmRvci9hdHRyaWJ1dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLGVBQU8sTUFBTSxtQkFBbUIsZUFBZSxDQUFDO0FBQ2hELGVBQU8sTUFBTSxvQkFBb0IsZ0JBQWdCLENBQUM7QUFDbEQsZUFBTyxNQUFNLHVCQUF1QiwyQkFBMkIsQ0FBQztBQUNoRSxlQUFPLE1BQU0sdUJBQXVCLDJCQUEyQixDQUFDO0FBQ2hFLGVBQU8sTUFBTSxzQkFBc0IsOEJBQThCLENBQUMifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../src/vendor/attributes.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAChD,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,uBAAuB,2BAA2B,CAAC;AAChE,eAAO,MAAM,uBAAuB,2BAA2B,CAAC;AAChE,eAAO,MAAM,sBAAsB,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// See https://opentelemetry.io/docs/specs/semconv/rpc/json-rpc/
|
|
2
|
+
export const ATTR_JSONRPC_METHOD = 'rpc.method';
|
|
3
|
+
export const ATTR_JSONRPC_SERVICE = 'rpc.service';
|
|
4
|
+
export const ATTR_JSONRPC_REQUEST_ID = 'rpc.jsonrpc.request_id';
|
|
5
|
+
export const ATTR_JSONRPC_ERROR_CODE = 'rpc.jsonrpc.error_code';
|
|
6
|
+
export const ATTR_JSONRPC_ERROR_MSG = 'rpc.jsonrpc.error_message';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Writable } from 'stream';
|
|
2
|
+
/**
|
|
3
|
+
* Return a function that knows how to convert the "time" field value on a
|
|
4
|
+
* Pino log record to an OTel LogRecord timestamp value.
|
|
5
|
+
*
|
|
6
|
+
* How to convert the serialized "time" on a Pino log record
|
|
7
|
+
* depends on the Logger's `Symbol(pino.time)` prop, configurable
|
|
8
|
+
* via https://getpino.io/#/docs/api?id=timestamp-boolean-function
|
|
9
|
+
*
|
|
10
|
+
* For example:
|
|
11
|
+
* const logger = pino({timestamp: pino.stdTimeFunctions.isoTime})
|
|
12
|
+
* results in log record entries of the form:
|
|
13
|
+
* ,"time":"2024-05-17T22:03:25.969Z"
|
|
14
|
+
* `otelTimestampFromTime` will be given the value of the "time" field:
|
|
15
|
+
* "2024-05-17T22:03:25.969Z"
|
|
16
|
+
* which should be parsed to a number of milliseconds since the epoch.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getTimeConverter(pinoLogger: any, pinoMod: any): ((time: number) => number) | ((time: string) => number);
|
|
19
|
+
interface OTelPinoStreamOptions {
|
|
20
|
+
messageKey?: string;
|
|
21
|
+
levels: any;
|
|
22
|
+
otelTimestampFromTime?: (time: any) => number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A Pino stream for sending records to the OpenTelemetry Logs API.
|
|
26
|
+
*
|
|
27
|
+
* - This stream emits an 'unknown' event on an unprocessable pino record.
|
|
28
|
+
* The event arguments are: `logLine: string`, `err: string | Error`.
|
|
29
|
+
*/
|
|
30
|
+
export declare class OTelPinoStream extends Writable {
|
|
31
|
+
private _otelLogger;
|
|
32
|
+
private _messageKey;
|
|
33
|
+
private _levels;
|
|
34
|
+
private _otelTimestampFromTime;
|
|
35
|
+
constructor(options: OTelPinoStreamOptions);
|
|
36
|
+
_write(s: string, _encoding: string, callback: Function): void;
|
|
37
|
+
}
|
|
38
|
+
export default function (options: OTelPinoStreamOptions): OTelPinoStream;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RlbC1waW5vLXN0cmVhbS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ZlbmRvci9vdGVsLXBpbm8tc3RyZWFtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQW9CQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBMkVsQzs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCx3QkFBZ0IsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsR0FBRywyREFlN0Q7QUFFRCxVQUFVLHFCQUFxQjtJQUM3QixVQUFVLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDcEIsTUFBTSxFQUFFLEdBQUcsQ0FBQztJQUNaLHFCQUFxQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxLQUFLLE1BQU0sQ0FBQztDQUMvQztBQUVEOzs7OztHQUtHO0FBQ0gscUJBQWEsY0FBZSxTQUFRLFFBQVE7SUFDMUMsT0FBTyxDQUFDLFdBQVcsQ0FBUztJQUM1QixPQUFPLENBQUMsV0FBVyxDQUFTO0lBQzVCLE9BQU8sQ0FBQyxPQUFPLENBQUM7SUFDaEIsT0FBTyxDQUFDLHNCQUFzQixDQUFDO0lBRS9CLFlBQVksT0FBTyxFQUFFLHFCQUFxQixFQWlCekM7SUFFUSxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLFFBb0cvRDtDQUNGO0FBTUQsTUFBTSxDQUFDLE9BQU8sV0FBVyxPQUFPLEVBQUUscUJBQXFCLEdBQUcsY0FBYyxDQU12RSJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-pino-stream.d.ts","sourceRoot":"","sources":["../../src/vendor/otel-pino-stream.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AA2ElC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,2DAe7D;AAED,UAAU,qBAAqB;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC;IACZ,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,MAAM,CAAC;CAC/C;AAED;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAC;IAChB,OAAO,CAAC,sBAAsB,CAAC;IAE/B,YAAY,OAAO,EAAE,qBAAqB,EAiBzC;IAEQ,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,QAoG/D;CACF;AAMD,MAAM,CAAC,OAAO,WAAW,OAAO,EAAE,qBAAqB,GAAG,cAAc,CAMvE"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Adapted from open-telemetry/opentelemetry-js-contrib
|
|
3
|
+
* All changes are prefixed with [aztec] to make them easy to identify
|
|
4
|
+
*
|
|
5
|
+
* Copyright The OpenTelemetry Authors
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/ import { SeverityNumber, logs } from '@opentelemetry/api-logs';
|
|
19
|
+
import { millisToHrTime } from '@opentelemetry/core';
|
|
20
|
+
import { Writable } from 'stream';
|
|
21
|
+
import { registerOtelLoggerProvider } from '../otel_logger_provider.js';
|
|
22
|
+
import { getOtelResource } from '../otel_resource.js';
|
|
23
|
+
// This block is a copy (modulo code style and TypeScript types) of the Pino
|
|
24
|
+
// code that defines log level value and names. This file is part of
|
|
25
|
+
// *instrumenting* Pino, so we want to avoid a dependency on the library.
|
|
26
|
+
const DEFAULT_LEVELS = {
|
|
27
|
+
trace: 10,
|
|
28
|
+
debug: 20,
|
|
29
|
+
info: 30,
|
|
30
|
+
warn: 40,
|
|
31
|
+
error: 50,
|
|
32
|
+
fatal: 60
|
|
33
|
+
};
|
|
34
|
+
const OTEL_SEV_NUM_FROM_PINO_LEVEL = {
|
|
35
|
+
[DEFAULT_LEVELS.trace]: SeverityNumber.TRACE,
|
|
36
|
+
[DEFAULT_LEVELS.debug]: SeverityNumber.DEBUG,
|
|
37
|
+
[DEFAULT_LEVELS.info]: SeverityNumber.INFO,
|
|
38
|
+
[DEFAULT_LEVELS.warn]: SeverityNumber.WARN,
|
|
39
|
+
[DEFAULT_LEVELS.error]: SeverityNumber.ERROR,
|
|
40
|
+
[DEFAULT_LEVELS.fatal]: SeverityNumber.FATAL
|
|
41
|
+
};
|
|
42
|
+
const EXTRA_SEV_NUMS = [
|
|
43
|
+
SeverityNumber.TRACE2,
|
|
44
|
+
SeverityNumber.TRACE3,
|
|
45
|
+
SeverityNumber.TRACE4,
|
|
46
|
+
SeverityNumber.DEBUG2,
|
|
47
|
+
SeverityNumber.DEBUG3,
|
|
48
|
+
SeverityNumber.DEBUG4,
|
|
49
|
+
SeverityNumber.INFO2,
|
|
50
|
+
SeverityNumber.INFO3,
|
|
51
|
+
SeverityNumber.INFO4,
|
|
52
|
+
SeverityNumber.WARN2,
|
|
53
|
+
SeverityNumber.WARN3,
|
|
54
|
+
SeverityNumber.WARN4,
|
|
55
|
+
SeverityNumber.ERROR2,
|
|
56
|
+
SeverityNumber.ERROR3,
|
|
57
|
+
SeverityNumber.ERROR4,
|
|
58
|
+
SeverityNumber.FATAL2,
|
|
59
|
+
SeverityNumber.FATAL3,
|
|
60
|
+
SeverityNumber.FATAL4
|
|
61
|
+
];
|
|
62
|
+
function severityNumberFromPinoLevel(lvl) {
|
|
63
|
+
// Fast common case: one of the known levels
|
|
64
|
+
const sev = OTEL_SEV_NUM_FROM_PINO_LEVEL[lvl];
|
|
65
|
+
if (sev !== undefined) {
|
|
66
|
+
return sev;
|
|
67
|
+
}
|
|
68
|
+
// Otherwise, scale the Pino level range -- 10 (trace) to 70 (fatal+10)
|
|
69
|
+
// -- onto the extra OTel severity numbers (TRACE2, TRACE3, ..., FATAL4).
|
|
70
|
+
// Values below trace (10) map to SeverityNumber.TRACE2, which may be
|
|
71
|
+
// considered a bit weird, but it means the unnumbered levels are always
|
|
72
|
+
// just for exactly matching values.
|
|
73
|
+
const relativeLevelWeight = (lvl - 10) / (70 - 10);
|
|
74
|
+
const otelSevIdx = Math.floor(relativeLevelWeight * EXTRA_SEV_NUMS.length);
|
|
75
|
+
const cappedOTelIdx = Math.min(EXTRA_SEV_NUMS.length - 1, Math.max(0, otelSevIdx));
|
|
76
|
+
const otelSevValue = EXTRA_SEV_NUMS[cappedOTelIdx];
|
|
77
|
+
return otelSevValue;
|
|
78
|
+
}
|
|
79
|
+
// [aztec] Custom function to map Aztec logging levels to OpenTelemetry severity numbers
|
|
80
|
+
function severityNumberFromAztecPinoLevel(lvl) {
|
|
81
|
+
return OTEL_SEV_NUM_FROM_PINO_LEVEL[lvl] ?? /* verbose */ (lvl === 25 ? SeverityNumber.DEBUG3 : undefined) ?? severityNumberFromPinoLevel(lvl);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Return a function that knows how to convert the "time" field value on a
|
|
85
|
+
* Pino log record to an OTel LogRecord timestamp value.
|
|
86
|
+
*
|
|
87
|
+
* How to convert the serialized "time" on a Pino log record
|
|
88
|
+
* depends on the Logger's `Symbol(pino.time)` prop, configurable
|
|
89
|
+
* via https://getpino.io/#/docs/api?id=timestamp-boolean-function
|
|
90
|
+
*
|
|
91
|
+
* For example:
|
|
92
|
+
* const logger = pino({timestamp: pino.stdTimeFunctions.isoTime})
|
|
93
|
+
* results in log record entries of the form:
|
|
94
|
+
* ,"time":"2024-05-17T22:03:25.969Z"
|
|
95
|
+
* `otelTimestampFromTime` will be given the value of the "time" field:
|
|
96
|
+
* "2024-05-17T22:03:25.969Z"
|
|
97
|
+
* which should be parsed to a number of milliseconds since the epoch.
|
|
98
|
+
*/ export function getTimeConverter(pinoLogger, pinoMod) {
|
|
99
|
+
const stdTimeFns = pinoMod.stdTimeFunctions;
|
|
100
|
+
const loggerTimeFn = pinoLogger[pinoMod.symbols.timeSym];
|
|
101
|
+
if (loggerTimeFn === stdTimeFns.epochTime) {
|
|
102
|
+
return (time)=>time;
|
|
103
|
+
} else if (loggerTimeFn === stdTimeFns.unixTime) {
|
|
104
|
+
return (time)=>time * 1e3;
|
|
105
|
+
} else if (loggerTimeFn === stdTimeFns.isoTime) {
|
|
106
|
+
return (time)=>new Date(time).getTime();
|
|
107
|
+
} else if (loggerTimeFn === stdTimeFns.nullTime) {
|
|
108
|
+
return ()=>Date.now();
|
|
109
|
+
} else {
|
|
110
|
+
// The logger has a custom time function. Don't guess.
|
|
111
|
+
return ()=>NaN;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* A Pino stream for sending records to the OpenTelemetry Logs API.
|
|
116
|
+
*
|
|
117
|
+
* - This stream emits an 'unknown' event on an unprocessable pino record.
|
|
118
|
+
* The event arguments are: `logLine: string`, `err: string | Error`.
|
|
119
|
+
*/ export class OTelPinoStream extends Writable {
|
|
120
|
+
_otelLogger;
|
|
121
|
+
_messageKey;
|
|
122
|
+
_levels;
|
|
123
|
+
_otelTimestampFromTime;
|
|
124
|
+
constructor(options){
|
|
125
|
+
super();
|
|
126
|
+
// Note: A PINO_CONFIG event was added to pino (2024-04-04) to send config
|
|
127
|
+
// to transports. Eventually OTelPinoStream might be able to use this
|
|
128
|
+
// for auto-configuration in newer pino versions. The event currently does
|
|
129
|
+
// not include the `timeSym` value that is needed here, however.
|
|
130
|
+
this._messageKey = options.messageKey ?? 'msg';
|
|
131
|
+
this._levels = options.levels;
|
|
132
|
+
// [aztec] The following will break if we set up a custom time function in our logger
|
|
133
|
+
this._otelTimestampFromTime = options.otelTimestampFromTime ?? ((time)=>time);
|
|
134
|
+
// Cannot use `instrumentation.logger` until have delegating LoggerProvider:
|
|
135
|
+
// https://github.com/open-telemetry/opentelemetry-js/issues/4399
|
|
136
|
+
// [aztec] Use the name of this package
|
|
137
|
+
this._otelLogger = logs.getLogger('@aztec-labs/telemetry-client/otel-pino-stream', '0.1.0');
|
|
138
|
+
}
|
|
139
|
+
_write(s, _encoding, callback) {
|
|
140
|
+
try {
|
|
141
|
+
/* istanbul ignore if */ if (!s) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// Parse, and handle edge cases similar to how `pino-abstract-transport` does:
|
|
145
|
+
// https://github.com/pinojs/pino-abstract-transport/blob/v1.2.0/index.js#L28-L45
|
|
146
|
+
// - Emitting an 'unknown' event on parse error mimicks pino-abstract-transport.
|
|
147
|
+
let recObj;
|
|
148
|
+
try {
|
|
149
|
+
recObj = JSON.parse(s);
|
|
150
|
+
} catch (parseErr) {
|
|
151
|
+
// Invalid JSON suggests a bug in Pino, or a logger configuration bug
|
|
152
|
+
// (a bogus `options.timestamp` or serializer).
|
|
153
|
+
this.emit('unknown', s.toString(), parseErr);
|
|
154
|
+
callback();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
/* istanbul ignore if */ if (recObj === null) {
|
|
158
|
+
this.emit('unknown', s.toString(), 'Null value ignored');
|
|
159
|
+
callback();
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
/* istanbul ignore if */ if (typeof recObj !== 'object') {
|
|
163
|
+
recObj = {
|
|
164
|
+
data: recObj
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const { time, [this._messageKey]: body, level, // The typical Pino `hostname` and `pid` fields are removed because they
|
|
168
|
+
// are redundant with the OpenTelemetry `host.name` and `process.pid`
|
|
169
|
+
// Resource attributes, respectively. This code cannot change the
|
|
170
|
+
// LoggerProvider's `resource`, so getting the OpenTelemetry equivalents
|
|
171
|
+
// depends on the user using the OpenTelemetry HostDetector and
|
|
172
|
+
// ProcessDetector.
|
|
173
|
+
// https://getpino.io/#/docs/api?id=opt-base
|
|
174
|
+
hostname, pid, // The `trace_id` et al fields that may have been added by the
|
|
175
|
+
// "log correlation" feature are stripped, because they are redundant.
|
|
176
|
+
// trace_id, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
177
|
+
// span_id, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
178
|
+
// trace_flags, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
179
|
+
// [aztec] They are not redundant, we depend on them for correlation.
|
|
180
|
+
// The instrumentation package seems to be adding these fields via a custom hook.
|
|
181
|
+
// We push them from the logger module in foundation, so we don't want to clear them here.
|
|
182
|
+
...attributes } = recObj;
|
|
183
|
+
let timestamp = this._otelTimestampFromTime(time);
|
|
184
|
+
if (isNaN(timestamp)) {
|
|
185
|
+
attributes['time'] = time; // save the unexpected "time" field to attributes
|
|
186
|
+
timestamp = Date.now();
|
|
187
|
+
}
|
|
188
|
+
// This avoids a possible subtle bug when a Pino logger uses
|
|
189
|
+
// `time: pino.stdTimeFunctions.unixTime` and logs in the first half-second
|
|
190
|
+
// since process start. The rounding involved results in:
|
|
191
|
+
// timestamp < performance.timeOrigin
|
|
192
|
+
// If that is passed to Logger.emit() it will be misinterpreted by
|
|
193
|
+
// `timeInputToHrTime` as a `performance.now()` value.
|
|
194
|
+
const timestampHrTime = millisToHrTime(timestamp);
|
|
195
|
+
// Prefer using `stream.lastLevel`, because `recObj.level` can be customized
|
|
196
|
+
// to anything via `formatters.level`
|
|
197
|
+
// (https://getpino.io/#/docs/api?id=formatters-object).
|
|
198
|
+
// const lastLevel = (this as any).lastLevel;
|
|
199
|
+
// [aztec] We do not prefer stream.lastLevel since it's undefined here, as we are running
|
|
200
|
+
// on a worker thread, so we use recObj.level because we know that we won't customize it.
|
|
201
|
+
const lastLevel = recObj.level;
|
|
202
|
+
const otelRec = {
|
|
203
|
+
timestamp: timestampHrTime,
|
|
204
|
+
observedTimestamp: timestampHrTime,
|
|
205
|
+
severityNumber: severityNumberFromAztecPinoLevel(lastLevel),
|
|
206
|
+
severityText: this._levels.labels[lastLevel],
|
|
207
|
+
body,
|
|
208
|
+
attributes
|
|
209
|
+
};
|
|
210
|
+
this._otelLogger.emit(otelRec);
|
|
211
|
+
} catch (err) {
|
|
212
|
+
// [aztec] Log errors to stderr
|
|
213
|
+
// eslint-disable-next-line no-console
|
|
214
|
+
console.error(`Error in OTelPinoStream: ${err}`);
|
|
215
|
+
}
|
|
216
|
+
callback();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// [aztec] Default export that loads the resource information and creates a new otel pino stream.
|
|
220
|
+
// Invoked by pino when creating a transport in a worker thread out of this stream.
|
|
221
|
+
// Note that the original open-telemetry/opentelemetry-js-contrib was set up to run on the main
|
|
222
|
+
// nodejs loop, as opposed to in a worker as pino recommends.
|
|
223
|
+
export default function(options) {
|
|
224
|
+
const url = process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT;
|
|
225
|
+
const resource = getOtelResource();
|
|
226
|
+
// We re-register here because this runs on a worker thread
|
|
227
|
+
registerOtelLoggerProvider(resource, url ? new URL(url) : undefined);
|
|
228
|
+
return new OTelPinoStream(options);
|
|
229
|
+
}
|