@davidilie/telemetry-node 0.0.0-bootstrap.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/LICENSE +201 -0
- package/README.md +224 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/UPSTREAM.yml +56 -0
- package/dist/client-BzoFCwmQ.d.cts +85 -0
- package/dist/client-BzoFCwmQ.d.mts +85 -0
- package/dist/index.cjs +15 -0
- package/dist/index.d.cts +34 -0
- package/dist/index.d.mts +34 -0
- package/dist/index.mjs +2 -0
- package/dist/register.cjs +53 -0
- package/dist/register.d.cts +10 -0
- package/dist/register.d.mts +10 -0
- package/dist/register.mjs +51 -0
- package/dist/sampler-BnXptsJ8.cjs +513 -0
- package/dist/sampler-fxBt_DLP.mjs +436 -0
- package/package.json +85 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
let _opentelemetry_api = require("@opentelemetry/api");
|
|
2
|
+
let _opentelemetry_api_logs = require("@opentelemetry/api-logs");
|
|
3
|
+
let _davidilie_telemetry_core = require("@davidilie/telemetry-core");
|
|
4
|
+
let _opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
5
|
+
//#region src/attributes.ts
|
|
6
|
+
function toOtelAttributeValue(value) {
|
|
7
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
|
|
8
|
+
if (value.every((entry) => typeof entry === "string")) return [...value];
|
|
9
|
+
if (value.every((entry) => typeof entry === "number")) return [...value];
|
|
10
|
+
if (value.every((entry) => typeof entry === "boolean")) return [...value];
|
|
11
|
+
return value.map(String);
|
|
12
|
+
}
|
|
13
|
+
function toOtelAttributes(attributes = {}) {
|
|
14
|
+
const result = {};
|
|
15
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
16
|
+
if (value == null) continue;
|
|
17
|
+
result[key] = toOtelAttributeValue(value);
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
function telemetryResourceAttributes(resource) {
|
|
22
|
+
return {
|
|
23
|
+
...toOtelAttributes(resource.attributes),
|
|
24
|
+
"service.name": resource.serviceName,
|
|
25
|
+
...resource.serviceVersion ? { "service.version": resource.serviceVersion } : {},
|
|
26
|
+
...resource.environment ? { "deployment.environment.name": resource.environment } : {},
|
|
27
|
+
...resource.namespace ? { "service.namespace": resource.namespace } : {},
|
|
28
|
+
...resource.repositoryUrl ? {
|
|
29
|
+
"app.repository.url": resource.repositoryUrl,
|
|
30
|
+
"vcs.repository.url.full": resource.repositoryUrl
|
|
31
|
+
} : {},
|
|
32
|
+
...resource.commitSha ? { "vcs.ref.head.revision": resource.commitSha } : {},
|
|
33
|
+
...resource.platform ? {
|
|
34
|
+
"app.platform": resource.platform,
|
|
35
|
+
"deployment.platform": resource.platform
|
|
36
|
+
} : {}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/adapter.ts
|
|
41
|
+
const severityNumbers = {
|
|
42
|
+
debug: _opentelemetry_api_logs.SeverityNumber.DEBUG,
|
|
43
|
+
info: _opentelemetry_api_logs.SeverityNumber.INFO,
|
|
44
|
+
warn: _opentelemetry_api_logs.SeverityNumber.WARN,
|
|
45
|
+
error: _opentelemetry_api_logs.SeverityNumber.ERROR
|
|
46
|
+
};
|
|
47
|
+
function exceptionForOtel(error) {
|
|
48
|
+
if (error instanceof Error) {
|
|
49
|
+
const safe = new Error((0, _davidilie_telemetry_core.redactText)(error.message), { ...error.cause !== void 0 ? { cause: (0, _davidilie_telemetry_core.redactText)(String(error.cause)) } : {} });
|
|
50
|
+
safe.name = (0, _davidilie_telemetry_core.redactText)(error.name, 256);
|
|
51
|
+
if (error.stack) safe.stack = (0, _davidilie_telemetry_core.redactText)(error.stack, 16384);
|
|
52
|
+
return safe;
|
|
53
|
+
}
|
|
54
|
+
return (0, _davidilie_telemetry_core.redactText)(typeof error === "string" ? error : String(error));
|
|
55
|
+
}
|
|
56
|
+
function signalAttributes(signal) {
|
|
57
|
+
return {
|
|
58
|
+
...toOtelAttributes(signal.attributes),
|
|
59
|
+
...telemetryResourceAttributes(signal.resource),
|
|
60
|
+
"telemetry.signal.id": signal.id,
|
|
61
|
+
"telemetry.signal.type": signal.type
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const spanKinds = {
|
|
65
|
+
internal: _opentelemetry_api.SpanKind.INTERNAL,
|
|
66
|
+
server: _opentelemetry_api.SpanKind.SERVER,
|
|
67
|
+
client: _opentelemetry_api.SpanKind.CLIENT,
|
|
68
|
+
producer: _opentelemetry_api.SpanKind.PRODUCER,
|
|
69
|
+
consumer: _opentelemetry_api.SpanKind.CONSUMER
|
|
70
|
+
};
|
|
71
|
+
const spanStatuses = {
|
|
72
|
+
unset: _opentelemetry_api.SpanStatusCode.UNSET,
|
|
73
|
+
ok: _opentelemetry_api.SpanStatusCode.OK,
|
|
74
|
+
error: _opentelemetry_api.SpanStatusCode.ERROR
|
|
75
|
+
};
|
|
76
|
+
const VALID_INSTRUMENT_NAME = /^[A-Za-z][A-Za-z0-9_.\-/]{0,254}$/;
|
|
77
|
+
var OpenTelemetrySpan = class {
|
|
78
|
+
#span;
|
|
79
|
+
constructor(span) {
|
|
80
|
+
this.#span = span;
|
|
81
|
+
}
|
|
82
|
+
setAttribute(name, value) {
|
|
83
|
+
const safe = (0, _davidilie_telemetry_core.sanitizeAttributes)({ [name]: value });
|
|
84
|
+
if (safe[name] !== void 0) this.#span.setAttribute(name, toOtelAttributeValue(safe[name]));
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
recordException(error, attributes = {}) {
|
|
88
|
+
this.#span.setAttributes(toOtelAttributes((0, _davidilie_telemetry_core.sanitizeAttributes)(attributes)));
|
|
89
|
+
this.#span.recordException(exceptionForOtel(error));
|
|
90
|
+
this.#span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
91
|
+
}
|
|
92
|
+
setStatus(status, message) {
|
|
93
|
+
this.#span.setStatus({
|
|
94
|
+
code: spanStatuses[status],
|
|
95
|
+
...message ? { message: (0, _davidilie_telemetry_core.redactText)(message) } : {}
|
|
96
|
+
});
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
end() {
|
|
100
|
+
this.#span.end();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var OpenTelemetryAdapter = class {
|
|
104
|
+
#instrumentationName;
|
|
105
|
+
#instrumentationVersion;
|
|
106
|
+
#resource;
|
|
107
|
+
#structuredConsole;
|
|
108
|
+
#measurementMode;
|
|
109
|
+
#metricAttributeAllowlist;
|
|
110
|
+
#maxMetricInstruments;
|
|
111
|
+
#logSampleRate;
|
|
112
|
+
#shutdown;
|
|
113
|
+
#histograms = /* @__PURE__ */ new Map();
|
|
114
|
+
constructor(config) {
|
|
115
|
+
this.#resource = (0, _davidilie_telemetry_core.sanitizeResource)(config.resource);
|
|
116
|
+
this.#instrumentationName = config.instrumentationName ?? this.#resource.serviceName;
|
|
117
|
+
this.#instrumentationVersion = config.instrumentationVersion;
|
|
118
|
+
this.#structuredConsole = config.structuredConsole ?? true;
|
|
119
|
+
this.#measurementMode = config.measurementMode ?? "spans";
|
|
120
|
+
this.#metricAttributeAllowlist = new Set(config.metricAttributeAllowlist ?? []);
|
|
121
|
+
this.#maxMetricInstruments = Math.max(0, Math.floor(Number.isFinite(config.maxMetricInstruments) ? config.maxMetricInstruments ?? 64 : 64));
|
|
122
|
+
this.#logSampleRate = Number.isFinite(config.logSampleRate) ? Math.min(1, Math.max(0, config.logSampleRate ?? 1)) : 1;
|
|
123
|
+
this.#shutdown = config.shutdown;
|
|
124
|
+
}
|
|
125
|
+
send(signal) {
|
|
126
|
+
signal = (0, _davidilie_telemetry_core.sanitizeSignal)(signal);
|
|
127
|
+
const attributes = signalAttributes(signal);
|
|
128
|
+
switch (signal.type) {
|
|
129
|
+
case "event": {
|
|
130
|
+
const activeSpan = _opentelemetry_api.trace.getActiveSpan();
|
|
131
|
+
if (activeSpan) {
|
|
132
|
+
activeSpan.addEvent(signal.name, attributes, new Date(signal.timestamp));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const span = this.#tracer().startSpan(signal.name, {
|
|
136
|
+
kind: _opentelemetry_api.SpanKind.INTERNAL,
|
|
137
|
+
attributes,
|
|
138
|
+
startTime: new Date(signal.timestamp)
|
|
139
|
+
});
|
|
140
|
+
span.addEvent(signal.name, attributes, new Date(signal.timestamp));
|
|
141
|
+
span.end(new Date(signal.timestamp));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
case "exception": {
|
|
145
|
+
const activeSpan = _opentelemetry_api.trace.getActiveSpan();
|
|
146
|
+
const span = activeSpan ?? this.#tracer().startSpan("exception", {
|
|
147
|
+
kind: _opentelemetry_api.SpanKind.INTERNAL,
|
|
148
|
+
attributes,
|
|
149
|
+
startTime: new Date(signal.timestamp)
|
|
150
|
+
});
|
|
151
|
+
span.setAttributes(attributes);
|
|
152
|
+
span.recordException({
|
|
153
|
+
name: signal.exception.name,
|
|
154
|
+
message: signal.exception.message,
|
|
155
|
+
...signal.exception.stack ? { stack: signal.exception.stack } : {}
|
|
156
|
+
});
|
|
157
|
+
span.setStatus({
|
|
158
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
159
|
+
message: signal.exception.message
|
|
160
|
+
});
|
|
161
|
+
if (!activeSpan) span.end(new Date(signal.timestamp));
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
case "log":
|
|
165
|
+
if (Math.random() >= this.#logSampleRate) return;
|
|
166
|
+
_opentelemetry_api_logs.logs.getLogger(this.#instrumentationName, this.#instrumentationVersion).emit({
|
|
167
|
+
body: signal.message,
|
|
168
|
+
severityText: signal.level.toUpperCase(),
|
|
169
|
+
severityNumber: severityNumbers[signal.level],
|
|
170
|
+
attributes,
|
|
171
|
+
timestamp: new Date(signal.timestamp)
|
|
172
|
+
});
|
|
173
|
+
if (this.#structuredConsole) {
|
|
174
|
+
const activeTrace = currentTraceContext();
|
|
175
|
+
const record = JSON.stringify({
|
|
176
|
+
...attributes,
|
|
177
|
+
timestamp: signal.timestamp,
|
|
178
|
+
level: signal.level,
|
|
179
|
+
message: signal.message,
|
|
180
|
+
service_name: signal.resource.serviceName,
|
|
181
|
+
...signal.resource.serviceVersion ? { service_version: signal.resource.serviceVersion } : {},
|
|
182
|
+
...activeTrace ? {
|
|
183
|
+
trace_id: activeTrace.traceId,
|
|
184
|
+
span_id: activeTrace.spanId
|
|
185
|
+
} : {}
|
|
186
|
+
});
|
|
187
|
+
console[signal.level](record);
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
case "measurement": {
|
|
191
|
+
if (this.#measurementMode === "spans" || this.#measurementMode === "both") this.#tracer().startSpan(`measurement:${signal.name}`, {
|
|
192
|
+
kind: _opentelemetry_api.SpanKind.INTERNAL,
|
|
193
|
+
attributes: {
|
|
194
|
+
...attributes,
|
|
195
|
+
"telemetry.measurement.value": signal.value,
|
|
196
|
+
...signal.unit ? { "telemetry.measurement.unit": signal.unit } : {}
|
|
197
|
+
},
|
|
198
|
+
startTime: new Date(signal.timestamp)
|
|
199
|
+
}).end(new Date(signal.timestamp));
|
|
200
|
+
if (this.#measurementMode === "spans") return;
|
|
201
|
+
if (!VALID_INSTRUMENT_NAME.test(signal.name)) return;
|
|
202
|
+
const key = `${signal.name}\u0000${signal.unit ?? ""}`;
|
|
203
|
+
let histogram = this.#histograms.get(key);
|
|
204
|
+
if (!histogram) {
|
|
205
|
+
if (this.#histograms.size >= this.#maxMetricInstruments) return;
|
|
206
|
+
histogram = _opentelemetry_api.metrics.getMeter(this.#instrumentationName, this.#instrumentationVersion).createHistogram(signal.name, { ...signal.unit ? { unit: signal.unit } : {} });
|
|
207
|
+
this.#histograms.set(key, histogram);
|
|
208
|
+
}
|
|
209
|
+
const metricAttributes = Object.fromEntries(Object.entries(signal.attributes).filter(([name]) => this.#metricAttributeAllowlist.has(name)));
|
|
210
|
+
histogram.record(signal.value, toOtelAttributes(metricAttributes));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
startSpan(name, attributes = {}, options = {}) {
|
|
215
|
+
return new OpenTelemetrySpan(this.#tracer().startSpan((0, _davidilie_telemetry_core.redactText)(name, 256), {
|
|
216
|
+
kind: spanKinds[options.kind ?? "internal"],
|
|
217
|
+
attributes: {
|
|
218
|
+
...toOtelAttributes((0, _davidilie_telemetry_core.sanitizeAttributes)(attributes)),
|
|
219
|
+
...telemetryResourceAttributes(this.#resource)
|
|
220
|
+
}
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
currentTraceContext() {
|
|
224
|
+
return currentTraceContext();
|
|
225
|
+
}
|
|
226
|
+
async withActiveSpan(name, operation, attributes = {}, options = {}) {
|
|
227
|
+
let operationRan = false;
|
|
228
|
+
let operationSucceeded = false;
|
|
229
|
+
let operationResult;
|
|
230
|
+
let operationError;
|
|
231
|
+
try {
|
|
232
|
+
await this.#tracer().startActiveSpan((0, _davidilie_telemetry_core.redactText)(name, 256), {
|
|
233
|
+
kind: spanKinds[options.kind ?? "internal"],
|
|
234
|
+
attributes: {
|
|
235
|
+
...toOtelAttributes((0, _davidilie_telemetry_core.sanitizeAttributes)(attributes)),
|
|
236
|
+
...telemetryResourceAttributes(this.#resource)
|
|
237
|
+
}
|
|
238
|
+
}, async (span) => {
|
|
239
|
+
operationRan = true;
|
|
240
|
+
try {
|
|
241
|
+
operationResult = await operation();
|
|
242
|
+
operationSucceeded = true;
|
|
243
|
+
} catch (error) {
|
|
244
|
+
operationError = error;
|
|
245
|
+
try {
|
|
246
|
+
span.recordException(exceptionForOtel(error));
|
|
247
|
+
span.setStatus({
|
|
248
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
249
|
+
...error instanceof Error ? { message: (0, _davidilie_telemetry_core.redactText)(error.message) } : {}
|
|
250
|
+
});
|
|
251
|
+
} catch {}
|
|
252
|
+
} finally {
|
|
253
|
+
try {
|
|
254
|
+
span.end();
|
|
255
|
+
} catch {}
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
} catch (telemetryError) {
|
|
259
|
+
if (!operationRan) throw telemetryError;
|
|
260
|
+
}
|
|
261
|
+
if (operationSucceeded) return operationResult;
|
|
262
|
+
if (operationRan) throw operationError;
|
|
263
|
+
return operation();
|
|
264
|
+
}
|
|
265
|
+
async shutdown() {
|
|
266
|
+
await this.#shutdown?.();
|
|
267
|
+
}
|
|
268
|
+
#tracer() {
|
|
269
|
+
return _opentelemetry_api.trace.getTracer(this.#instrumentationName, this.#instrumentationVersion);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
function createOpenTelemetryAdapter(config) {
|
|
273
|
+
return new OpenTelemetryAdapter(config);
|
|
274
|
+
}
|
|
275
|
+
function currentTraceContext() {
|
|
276
|
+
const spanContext = _opentelemetry_api.trace.getSpan(_opentelemetry_api.context.active())?.spanContext();
|
|
277
|
+
if (!spanContext) return void 0;
|
|
278
|
+
return {
|
|
279
|
+
traceId: spanContext.traceId,
|
|
280
|
+
spanId: spanContext.spanId,
|
|
281
|
+
traceFlags: spanContext.traceFlags
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
function startSpan(name, attributes = {}, options = {}) {
|
|
285
|
+
return new OpenTelemetrySpan(_opentelemetry_api.trace.getTracer("@davidilie/telemetry-node").startSpan((0, _davidilie_telemetry_core.redactText)(name, 256), {
|
|
286
|
+
kind: spanKinds[options.kind ?? "internal"],
|
|
287
|
+
attributes: toOtelAttributes((0, _davidilie_telemetry_core.sanitizeAttributes)(attributes))
|
|
288
|
+
}));
|
|
289
|
+
}
|
|
290
|
+
async function withSpan(name, operation, attributes = {}, options = {}) {
|
|
291
|
+
return _opentelemetry_api.trace.getTracer("@davidilie/telemetry-node").startActiveSpan((0, _davidilie_telemetry_core.redactText)(name, 256), {
|
|
292
|
+
kind: spanKinds[options.kind ?? "internal"],
|
|
293
|
+
attributes: toOtelAttributes((0, _davidilie_telemetry_core.sanitizeAttributes)(attributes))
|
|
294
|
+
}, async (span) => {
|
|
295
|
+
try {
|
|
296
|
+
return await operation();
|
|
297
|
+
} catch (error) {
|
|
298
|
+
try {
|
|
299
|
+
span.recordException(exceptionForOtel(error));
|
|
300
|
+
span.setStatus({
|
|
301
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
302
|
+
...error instanceof Error ? { message: (0, _davidilie_telemetry_core.redactText)(error.message) } : {}
|
|
303
|
+
});
|
|
304
|
+
} catch {}
|
|
305
|
+
throw error;
|
|
306
|
+
} finally {
|
|
307
|
+
try {
|
|
308
|
+
span.end();
|
|
309
|
+
} catch {}
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
function recordException(error, attributes = {}) {
|
|
314
|
+
const activeSpan = _opentelemetry_api.trace.getActiveSpan();
|
|
315
|
+
const span = activeSpan ?? _opentelemetry_api.trace.getTracer("@davidilie/telemetry-node").startSpan("exception");
|
|
316
|
+
span.setAttributes(toOtelAttributes((0, _davidilie_telemetry_core.sanitizeAttributes)(attributes)));
|
|
317
|
+
span.recordException(exceptionForOtel(error));
|
|
318
|
+
span.setStatus({
|
|
319
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
320
|
+
...error instanceof Error ? { message: (0, _davidilie_telemetry_core.redactText)(error.message) } : {}
|
|
321
|
+
});
|
|
322
|
+
if (!activeSpan) span.end();
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/client.ts
|
|
326
|
+
var NodeTelemetryClient = class extends _davidilie_telemetry_core.TelemetryClient {
|
|
327
|
+
#adapter;
|
|
328
|
+
#sampleRate;
|
|
329
|
+
#onError;
|
|
330
|
+
#onCollectionStateChange;
|
|
331
|
+
#enabled;
|
|
332
|
+
#consent;
|
|
333
|
+
constructor(config) {
|
|
334
|
+
const adapter = new OpenTelemetryAdapter({
|
|
335
|
+
resource: config.resource,
|
|
336
|
+
...config.instrumentationName ? { instrumentationName: config.instrumentationName } : {},
|
|
337
|
+
...config.instrumentationVersion ? { instrumentationVersion: config.instrumentationVersion } : {},
|
|
338
|
+
...config.structuredConsole !== void 0 ? { structuredConsole: config.structuredConsole } : {},
|
|
339
|
+
...config.measurementMode ? { measurementMode: config.measurementMode } : {},
|
|
340
|
+
...config.metricAttributeAllowlist ? { metricAttributeAllowlist: config.metricAttributeAllowlist } : {},
|
|
341
|
+
...config.maxMetricInstruments !== void 0 ? { maxMetricInstruments: config.maxMetricInstruments } : {},
|
|
342
|
+
...config.providerManagedSampling ? { logSampleRate: config.sampleRate } : {},
|
|
343
|
+
...config.shutdown ? { shutdown: config.shutdown } : {}
|
|
344
|
+
});
|
|
345
|
+
super({
|
|
346
|
+
adapter,
|
|
347
|
+
resource: config.resource,
|
|
348
|
+
...config.beforeSend ? { beforeSend: config.beforeSend } : {},
|
|
349
|
+
...config.enabled !== void 0 ? { enabled: config.enabled } : {},
|
|
350
|
+
...config.sampleRate !== void 0 ? { sampleRate: config.providerManagedSampling ? 1 : config.sampleRate } : {},
|
|
351
|
+
...config.consent ? { consent: config.consent } : {},
|
|
352
|
+
...config.debug !== void 0 ? { debug: config.debug } : {},
|
|
353
|
+
...config.onError ? { onError: config.onError } : {}
|
|
354
|
+
});
|
|
355
|
+
this.#adapter = adapter;
|
|
356
|
+
this.#sampleRate = config.providerManagedSampling ? 1 : Number.isFinite(config.sampleRate) ? Math.min(1, Math.max(0, config.sampleRate ?? 1)) : 1;
|
|
357
|
+
this.#onError = config.onError;
|
|
358
|
+
this.#onCollectionStateChange = config.onCollectionStateChange;
|
|
359
|
+
this.#enabled = config.enabled ?? true;
|
|
360
|
+
this.#consent = config.consent ?? "granted";
|
|
361
|
+
}
|
|
362
|
+
setEnabled(enabled) {
|
|
363
|
+
this.#enabled = enabled;
|
|
364
|
+
super.setEnabled(enabled);
|
|
365
|
+
this.#onCollectionStateChange?.({
|
|
366
|
+
enabled: this.#enabled,
|
|
367
|
+
consent: this.#consent
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
setConsent(consent) {
|
|
371
|
+
this.#consent = consent;
|
|
372
|
+
super.setConsent(consent);
|
|
373
|
+
this.#onCollectionStateChange?.({
|
|
374
|
+
enabled: this.#enabled,
|
|
375
|
+
consent: this.#consent
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
async withSpan(name, operation, attributes = {}, options = {}) {
|
|
379
|
+
if (!this.#enabled || this.#consent !== "granted" || Math.random() >= this.#sampleRate) return operation();
|
|
380
|
+
let operationStarted = false;
|
|
381
|
+
try {
|
|
382
|
+
return await this.#adapter.withActiveSpan((0, _davidilie_telemetry_core.redactText)(name, 256), () => {
|
|
383
|
+
operationStarted = true;
|
|
384
|
+
return operation();
|
|
385
|
+
}, (0, _davidilie_telemetry_core.sanitizeAttributes)(attributes), options);
|
|
386
|
+
} catch (error) {
|
|
387
|
+
if (operationStarted) throw error;
|
|
388
|
+
this.#reportAdapterError(error, { operation: "startSpan" });
|
|
389
|
+
return operation();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
#reportAdapterError(error, context) {
|
|
393
|
+
if (!this.#onError) return;
|
|
394
|
+
try {
|
|
395
|
+
Promise.resolve(this.#onError(error, context)).catch(() => void 0);
|
|
396
|
+
} catch {}
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
function createNodeTelemetry(config) {
|
|
400
|
+
return new NodeTelemetryClient(config);
|
|
401
|
+
}
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region src/sampler.ts
|
|
404
|
+
/**
|
|
405
|
+
* A mutable gate around an ordinary OpenTelemetry sampler.
|
|
406
|
+
*
|
|
407
|
+
* OpenTelemetry providers are registered once, but consent and operational
|
|
408
|
+
* switches can change later. This wrapper drops every span—including children
|
|
409
|
+
* of sampled remote parents—while collection is disabled, then delegates to
|
|
410
|
+
* the configured sampler immediately after collection is re-enabled.
|
|
411
|
+
*/
|
|
412
|
+
var DynamicTelemetrySampler = class {
|
|
413
|
+
delegate;
|
|
414
|
+
#enabled;
|
|
415
|
+
#consent;
|
|
416
|
+
constructor(delegate, state) {
|
|
417
|
+
this.delegate = delegate;
|
|
418
|
+
this.#enabled = state.enabled;
|
|
419
|
+
this.#consent = state.consent;
|
|
420
|
+
}
|
|
421
|
+
setEnabled(enabled) {
|
|
422
|
+
this.#enabled = enabled;
|
|
423
|
+
}
|
|
424
|
+
setConsent(consent) {
|
|
425
|
+
this.#consent = consent;
|
|
426
|
+
}
|
|
427
|
+
shouldSample(parentContext, traceId, spanName, spanKind, attributes, links) {
|
|
428
|
+
if (!this.#enabled || this.#consent !== "granted") return { decision: _opentelemetry_sdk_trace_base.SamplingDecision.NOT_RECORD };
|
|
429
|
+
return this.delegate.shouldSample(parentContext, traceId, spanName, spanKind, attributes, links);
|
|
430
|
+
}
|
|
431
|
+
toString() {
|
|
432
|
+
return `DynamicTelemetrySampler{${this.delegate.toString()}}`;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
//#endregion
|
|
436
|
+
Object.defineProperty(exports, "DynamicTelemetrySampler", {
|
|
437
|
+
enumerable: true,
|
|
438
|
+
get: function() {
|
|
439
|
+
return DynamicTelemetrySampler;
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
Object.defineProperty(exports, "NodeTelemetryClient", {
|
|
443
|
+
enumerable: true,
|
|
444
|
+
get: function() {
|
|
445
|
+
return NodeTelemetryClient;
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
Object.defineProperty(exports, "OpenTelemetryAdapter", {
|
|
449
|
+
enumerable: true,
|
|
450
|
+
get: function() {
|
|
451
|
+
return OpenTelemetryAdapter;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
Object.defineProperty(exports, "OpenTelemetrySpan", {
|
|
455
|
+
enumerable: true,
|
|
456
|
+
get: function() {
|
|
457
|
+
return OpenTelemetrySpan;
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
Object.defineProperty(exports, "createNodeTelemetry", {
|
|
461
|
+
enumerable: true,
|
|
462
|
+
get: function() {
|
|
463
|
+
return createNodeTelemetry;
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
Object.defineProperty(exports, "createOpenTelemetryAdapter", {
|
|
467
|
+
enumerable: true,
|
|
468
|
+
get: function() {
|
|
469
|
+
return createOpenTelemetryAdapter;
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
Object.defineProperty(exports, "currentTraceContext", {
|
|
473
|
+
enumerable: true,
|
|
474
|
+
get: function() {
|
|
475
|
+
return currentTraceContext;
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
Object.defineProperty(exports, "recordException", {
|
|
479
|
+
enumerable: true,
|
|
480
|
+
get: function() {
|
|
481
|
+
return recordException;
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
Object.defineProperty(exports, "startSpan", {
|
|
485
|
+
enumerable: true,
|
|
486
|
+
get: function() {
|
|
487
|
+
return startSpan;
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
Object.defineProperty(exports, "telemetryResourceAttributes", {
|
|
491
|
+
enumerable: true,
|
|
492
|
+
get: function() {
|
|
493
|
+
return telemetryResourceAttributes;
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
Object.defineProperty(exports, "toOtelAttributeValue", {
|
|
497
|
+
enumerable: true,
|
|
498
|
+
get: function() {
|
|
499
|
+
return toOtelAttributeValue;
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
Object.defineProperty(exports, "toOtelAttributes", {
|
|
503
|
+
enumerable: true,
|
|
504
|
+
get: function() {
|
|
505
|
+
return toOtelAttributes;
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
Object.defineProperty(exports, "withSpan", {
|
|
509
|
+
enumerable: true,
|
|
510
|
+
get: function() {
|
|
511
|
+
return withSpan;
|
|
512
|
+
}
|
|
513
|
+
});
|