@elysia/opentelemetry 1.4.12 → 2.0.0-exp.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/bun.lock +98 -246
- package/dist/index.d.ts +72 -84
- package/dist/index.js +511 -0
- package/dist/index.mjs +489 -663
- package/package.json +8 -12
- package/bunfig.toml +0 -2
- package/dist/cjs/index.d.ts +0 -98
- package/dist/cjs/index.js +0 -701
package/dist/index.mjs
CHANGED
|
@@ -1,676 +1,502 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
1
|
import { Elysia, StatusMap } from "elysia";
|
|
3
|
-
import {
|
|
4
|
-
trace,
|
|
5
|
-
metrics,
|
|
6
|
-
context as otelContext,
|
|
7
|
-
propagation,
|
|
8
|
-
SpanStatusCode,
|
|
9
|
-
SpanKind,
|
|
10
|
-
ProxyTracerProvider
|
|
11
|
-
} from "@opentelemetry/api";
|
|
2
|
+
import { ProxyTracerProvider, SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
|
|
12
3
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
4
|
+
|
|
5
|
+
//#region src/index.ts
|
|
6
|
+
const headerHasToJSON = typeof new Headers().toJSON === "function";
|
|
7
|
+
const toHeaderNameSet = (names) => new Set((names ?? []).map((name) => name.toLowerCase()));
|
|
8
|
+
const SENSITIVE_QUERY_KEYS = /* @__PURE__ */ new Set([
|
|
9
|
+
"token",
|
|
10
|
+
"access_token",
|
|
11
|
+
"refresh_token",
|
|
12
|
+
"id_token",
|
|
13
|
+
"password",
|
|
14
|
+
"passwd",
|
|
15
|
+
"pwd",
|
|
16
|
+
"secret",
|
|
17
|
+
"client_secret",
|
|
18
|
+
"api_key",
|
|
19
|
+
"apikey",
|
|
20
|
+
"api-key",
|
|
21
|
+
"authorization",
|
|
22
|
+
"credential",
|
|
23
|
+
"credentials",
|
|
24
|
+
"code",
|
|
25
|
+
"nonce"
|
|
33
26
|
]);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return null;
|
|
27
|
+
const parseNumericString = (message) => {
|
|
28
|
+
if (message.length < 16) {
|
|
29
|
+
if (message.length === 0) return null;
|
|
30
|
+
const length = Number(message);
|
|
31
|
+
if (Number.isNaN(length)) return null;
|
|
32
|
+
return length;
|
|
33
|
+
}
|
|
34
|
+
if (message.length === 16) {
|
|
35
|
+
const number = Number(message);
|
|
36
|
+
if (number.toString() !== message || message.trim().length === 0 || Number.isNaN(number)) return null;
|
|
37
|
+
return number;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
48
40
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
message: err?.message
|
|
77
|
-
});
|
|
78
|
-
span.recordException(err);
|
|
79
|
-
span.end();
|
|
80
|
-
throw error;
|
|
81
|
-
}
|
|
41
|
+
const createActiveSpanHandler = (fn) => function(span) {
|
|
42
|
+
try {
|
|
43
|
+
const result = fn(span);
|
|
44
|
+
if (result instanceof Promise || typeof result?.then === "function") return Promise.resolve(result).then((value) => {
|
|
45
|
+
span.end();
|
|
46
|
+
return value;
|
|
47
|
+
}, (rejectResult) => {
|
|
48
|
+
span.setStatus({
|
|
49
|
+
code: SpanStatusCode.ERROR,
|
|
50
|
+
message: rejectResult instanceof Error ? rejectResult.message : JSON.stringify(rejectResult ?? "Unknown error")
|
|
51
|
+
});
|
|
52
|
+
span.recordException(rejectResult);
|
|
53
|
+
span.end();
|
|
54
|
+
throw rejectResult;
|
|
55
|
+
});
|
|
56
|
+
span.end();
|
|
57
|
+
return result;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
const err = error;
|
|
60
|
+
span.setStatus({
|
|
61
|
+
code: SpanStatusCode.ERROR,
|
|
62
|
+
message: err?.message
|
|
63
|
+
});
|
|
64
|
+
span.recordException(err);
|
|
65
|
+
span.end();
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
82
68
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
69
|
+
const createContext = (parent) => ({
|
|
70
|
+
getValue() {
|
|
71
|
+
return parent;
|
|
72
|
+
},
|
|
73
|
+
setValue() {
|
|
74
|
+
return context.active();
|
|
75
|
+
},
|
|
76
|
+
deleteValue() {
|
|
77
|
+
return context.active();
|
|
78
|
+
}
|
|
93
79
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
80
|
+
const serializeBody = (body) => {
|
|
81
|
+
if (body instanceof Uint8Array) return {
|
|
82
|
+
text: "",
|
|
83
|
+
size: body.length
|
|
84
|
+
};
|
|
85
|
+
if (body instanceof ArrayBuffer) return {
|
|
86
|
+
text: "",
|
|
87
|
+
size: body.byteLength
|
|
88
|
+
};
|
|
89
|
+
if (body instanceof Blob) return {
|
|
90
|
+
text: "",
|
|
91
|
+
size: body.size
|
|
92
|
+
};
|
|
93
|
+
let text;
|
|
94
|
+
try {
|
|
95
|
+
text = typeof body === "object" ? JSON.stringify(body) : String(body);
|
|
96
|
+
} catch {
|
|
97
|
+
text = "[Unserializable]";
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
text,
|
|
101
|
+
size: text.length
|
|
102
|
+
};
|
|
105
103
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
104
|
+
const redactQueryString = (query, keys) => {
|
|
105
|
+
if (query === "" || keys.size === 0) return query;
|
|
106
|
+
let out = "";
|
|
107
|
+
let partStart = 0;
|
|
108
|
+
let keyEnd = -1;
|
|
109
|
+
for (let i = 0; i <= query.length; i++) {
|
|
110
|
+
const ch = i === query.length ? 38 : query.charCodeAt(i);
|
|
111
|
+
if (ch === 61 && keyEnd === -1) {
|
|
112
|
+
keyEnd = i;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (ch !== 38) continue;
|
|
116
|
+
const partEnd = i;
|
|
117
|
+
const rawKeyEnd = keyEnd === -1 ? partEnd : keyEnd;
|
|
118
|
+
const rawKey = query.slice(partStart, rawKeyEnd);
|
|
119
|
+
if (out) out += "&";
|
|
120
|
+
out += keys.has(rawKey.toLowerCase()) ? rawKey + "=[REDACTED]" : query.slice(partStart, partEnd);
|
|
121
|
+
partStart = i + 1;
|
|
122
|
+
keyEnd = -1;
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
127
125
|
};
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
const shouldStartNodeSDK = (provider) => {
|
|
127
|
+
return provider instanceof ProxyTracerProvider && provider.getDelegateTracer("check") === void 0;
|
|
130
128
|
};
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return tracer.startActiveSpan(
|
|
148
|
-
args[0],
|
|
149
|
-
args[1],
|
|
150
|
-
createActiveSpanHandler(args[2])
|
|
151
|
-
);
|
|
152
|
-
case 4:
|
|
153
|
-
return tracer.startActiveSpan(
|
|
154
|
-
args[0],
|
|
155
|
-
args[1],
|
|
156
|
-
args[2],
|
|
157
|
-
createActiveSpanHandler(args[3])
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
};
|
|
129
|
+
const contextKeySpan = Symbol.for("OpenTelemetry Context Key SPAN");
|
|
130
|
+
const getTracer = () => {
|
|
131
|
+
const tracer = trace.getTracer("Elysia");
|
|
132
|
+
return {
|
|
133
|
+
...tracer,
|
|
134
|
+
startSpan(name, options, context) {
|
|
135
|
+
return tracer.startSpan(name, options, context);
|
|
136
|
+
},
|
|
137
|
+
startActiveSpan(...args) {
|
|
138
|
+
switch (args.length) {
|
|
139
|
+
case 2: return tracer.startActiveSpan(args[0], createActiveSpanHandler(args[1]));
|
|
140
|
+
case 3: return tracer.startActiveSpan(args[0], args[1], createActiveSpanHandler(args[2]));
|
|
141
|
+
case 4: return tracer.startActiveSpan(args[0], args[1], args[2], createActiveSpanHandler(args[3]));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
162
145
|
};
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return tracer.startSpan(name, options, context);
|
|
146
|
+
const startSpan = (name, options, context) => {
|
|
147
|
+
return getTracer().startSpan(name, options, context);
|
|
166
148
|
};
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
);
|
|
175
|
-
case 3:
|
|
176
|
-
return tracer.startActiveSpan(
|
|
177
|
-
args[0],
|
|
178
|
-
args[1],
|
|
179
|
-
createActiveSpanHandler(args[2])
|
|
180
|
-
);
|
|
181
|
-
case 4:
|
|
182
|
-
return tracer.startActiveSpan(
|
|
183
|
-
args[0],
|
|
184
|
-
args[1],
|
|
185
|
-
args[2],
|
|
186
|
-
createActiveSpanHandler(args[3])
|
|
187
|
-
);
|
|
188
|
-
}
|
|
149
|
+
const startActiveSpan = (...args) => {
|
|
150
|
+
const tracer = getTracer();
|
|
151
|
+
switch (args.length) {
|
|
152
|
+
case 2: return tracer.startActiveSpan(args[0], createActiveSpanHandler(args[1]));
|
|
153
|
+
case 3: return tracer.startActiveSpan(args[0], args[1], createActiveSpanHandler(args[2]));
|
|
154
|
+
case 4: return tracer.startActiveSpan(args[0], args[1], args[2], createActiveSpanHandler(args[3]));
|
|
155
|
+
}
|
|
189
156
|
};
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
continue;
|
|
533
|
-
}
|
|
534
|
-
if (typeof value === "object") {
|
|
535
|
-
const serialized = JSON.stringify(value);
|
|
536
|
-
headers[key] = serialized;
|
|
537
|
-
if (requestHeaderWildcard || spanRequestHeaderSet.has(key))
|
|
538
|
-
attributes[`http.request.header.${key}`] = serialized;
|
|
539
|
-
} else if (value !== void 0) {
|
|
540
|
-
headers[key] = value;
|
|
541
|
-
if (requestHeaderWildcard || spanRequestHeaderSet.has(key))
|
|
542
|
-
attributes[`http.request.header.${key}`] = value;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
{
|
|
547
|
-
let headers2;
|
|
548
|
-
if (context.set.headers instanceof Headers) {
|
|
549
|
-
if (headerHasToJSON)
|
|
550
|
-
headers2 = Object.entries(
|
|
551
|
-
// @ts-ignore bun only
|
|
552
|
-
context.set.headers.toJSON()
|
|
553
|
-
);
|
|
554
|
-
else headers2 = context.set.headers.entries();
|
|
555
|
-
} else headers2 = Object.entries(context.set.headers);
|
|
556
|
-
for (let [key, value] of headers2) {
|
|
557
|
-
key = key.toLowerCase();
|
|
558
|
-
if (!responseHeaderWildcard && !spanResponseHeaderSet.has(key))
|
|
559
|
-
continue;
|
|
560
|
-
if (typeof value === "object")
|
|
561
|
-
attributes[`http.response.header.${key}`] = JSON.stringify(value);
|
|
562
|
-
else
|
|
563
|
-
attributes[`http.response.header.${key}`] = value;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
if (context.ip)
|
|
567
|
-
attributes["client.address"] = context.ip;
|
|
568
|
-
else {
|
|
569
|
-
const ip = headers["true-client-ip"] ?? headers["cf-connection-ip"] ?? headers["x-forwarded-for"] ?? headers["x-real-ip"] ?? server?.requestIP(request);
|
|
570
|
-
if (ip)
|
|
571
|
-
attributes["client.address"] = typeof ip === "string" ? ip : ip.address ?? ip.toString();
|
|
572
|
-
}
|
|
573
|
-
if ((requestHeaderWildcard || spanRequestHeaderSet.has("cookie")) && cookie) {
|
|
574
|
-
const _cookie = {};
|
|
575
|
-
for (const [key, { value }] of Object.entries(cookie))
|
|
576
|
-
_cookie[key] = JSON.stringify(value);
|
|
577
|
-
attributes["http.request.cookie"] = JSON.stringify(_cookie);
|
|
578
|
-
}
|
|
579
|
-
rootSpan.setAttributes(attributes);
|
|
580
|
-
});
|
|
581
|
-
onParse(() => {
|
|
582
|
-
const body = context.body;
|
|
583
|
-
if (body === void 0 || body === null || !recordRequestBody)
|
|
584
|
-
return;
|
|
585
|
-
const { text, size } = serializeBody(body);
|
|
586
|
-
if (text) attributes["http.request.body"] = text;
|
|
587
|
-
attributes["http.request.body.size"] = size;
|
|
588
|
-
});
|
|
589
|
-
onMapResponse(() => {
|
|
590
|
-
const body = context.body;
|
|
591
|
-
if (body !== void 0 && body !== null && recordRequestBody) {
|
|
592
|
-
const { text, size } = serializeBody(body);
|
|
593
|
-
if (text) attributes["http.request.body"] = text;
|
|
594
|
-
attributes["http.request.body.size"] = size;
|
|
595
|
-
}
|
|
596
|
-
{
|
|
597
|
-
let status = context.set.status ?? 200;
|
|
598
|
-
if (typeof status === "string")
|
|
599
|
-
status = StatusMap[status] ?? 200;
|
|
600
|
-
attributes["http.response.status_code"] = status;
|
|
601
|
-
}
|
|
602
|
-
const response = context.responseValue;
|
|
603
|
-
if (response !== void 0 && recordResponseBody) {
|
|
604
|
-
const { text, size } = serializeBody(response);
|
|
605
|
-
if (text) attributes["http.response.body"] = text;
|
|
606
|
-
attributes["http.response.body.size"] = size;
|
|
607
|
-
}
|
|
608
|
-
if (!rootSpan.ended) {
|
|
609
|
-
const statusCode = attributes["http.response.status_code"];
|
|
610
|
-
if (typeof statusCode === "number" && statusCode >= 500) {
|
|
611
|
-
rootSpan.setStatus({
|
|
612
|
-
code: SpanStatusCode.ERROR
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
rootSpan.setAttributes(attributes);
|
|
616
|
-
}
|
|
617
|
-
});
|
|
618
|
-
onAfterResponse((event) => {
|
|
619
|
-
inspect("AfterResponse")(event);
|
|
620
|
-
{
|
|
621
|
-
let status = context.set.status ?? 200;
|
|
622
|
-
if (typeof status === "string")
|
|
623
|
-
status = StatusMap[status] ?? 200;
|
|
624
|
-
attributes["http.response.status_code"] = status;
|
|
625
|
-
}
|
|
626
|
-
const body = context.body;
|
|
627
|
-
if (body !== void 0 && body !== null && recordRequestBody) {
|
|
628
|
-
const { text, size } = serializeBody(body);
|
|
629
|
-
if (text) attributes["http.request.body"] = text;
|
|
630
|
-
attributes["http.request.body.size"] = size;
|
|
631
|
-
}
|
|
632
|
-
if (!rootSpan.ended) {
|
|
633
|
-
const statusCode = attributes["http.response.status_code"];
|
|
634
|
-
if (typeof statusCode === "number" && statusCode >= 500)
|
|
635
|
-
rootSpan.setStatus({
|
|
636
|
-
code: SpanStatusCode.ERROR
|
|
637
|
-
});
|
|
638
|
-
rootSpan.setAttributes(attributes);
|
|
639
|
-
}
|
|
640
|
-
event.onStop(() => {
|
|
641
|
-
setParent(rootSpan);
|
|
642
|
-
if (rootSpan.ended) return;
|
|
643
|
-
if (
|
|
644
|
-
// @ts-ignore
|
|
645
|
-
!rootSpan.ended
|
|
646
|
-
) {
|
|
647
|
-
recordDuration();
|
|
648
|
-
rootSpan.end();
|
|
649
|
-
}
|
|
650
|
-
});
|
|
651
|
-
});
|
|
652
|
-
context.request.signal.addEventListener("abort", () => {
|
|
653
|
-
const active = trace.getActiveSpan();
|
|
654
|
-
if (active && !active.ended) active.end();
|
|
655
|
-
if (rootSpan.ended) return;
|
|
656
|
-
rootSpan.setStatus({
|
|
657
|
-
code: SpanStatusCode.ERROR,
|
|
658
|
-
message: "Request aborted"
|
|
659
|
-
});
|
|
660
|
-
recordDuration();
|
|
661
|
-
rootSpan.end();
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
);
|
|
665
|
-
};
|
|
666
|
-
export {
|
|
667
|
-
contextKeySpan,
|
|
668
|
-
getCurrentSpan,
|
|
669
|
-
getTracer,
|
|
670
|
-
opentelemetry,
|
|
671
|
-
record,
|
|
672
|
-
setAttributes,
|
|
673
|
-
shouldStartNodeSDK,
|
|
674
|
-
startActiveSpan,
|
|
675
|
-
startSpan
|
|
157
|
+
const record = startActiveSpan;
|
|
158
|
+
const getCurrentSpan = () => trace.getActiveSpan();
|
|
159
|
+
/**
|
|
160
|
+
* Set attributes to the current span
|
|
161
|
+
*
|
|
162
|
+
* @returns boolean - whether the attributes are set or not
|
|
163
|
+
*/
|
|
164
|
+
const setAttributes = (attributes) => !!getCurrentSpan()?.setAttributes(attributes);
|
|
165
|
+
const opentelemetry = ({ serviceName = "Elysia", instrumentations, contextManager, checkIfShouldTrace, spanUrlRedaction, recordBody, headersToSpanAttributes, ...options } = {}) => {
|
|
166
|
+
const spanRequestHeaderSet = toHeaderNameSet(headersToSpanAttributes?.request);
|
|
167
|
+
const spanResponseHeaderSet = toHeaderNameSet(headersToSpanAttributes?.response);
|
|
168
|
+
const requestHeaderWildcard = spanRequestHeaderSet.has("*");
|
|
169
|
+
const responseHeaderWildcard = spanResponseHeaderSet.has("*");
|
|
170
|
+
const recordRequestBody = recordBody === true || recordBody && recordBody.request || false;
|
|
171
|
+
const recordResponseBody = recordBody === true || recordBody && recordBody.response || false;
|
|
172
|
+
const urlRedactOpts = spanUrlRedaction === false ? null : spanUrlRedaction ?? {};
|
|
173
|
+
const sensitiveKeys = urlRedactOpts ? /* @__PURE__ */ new Set([...SENSITIVE_QUERY_KEYS, ...(urlRedactOpts.sensitiveQueryParams ?? []).map((k) => k.toLowerCase())]) : void 0;
|
|
174
|
+
const stripCreds = urlRedactOpts?.stripCredentials !== false;
|
|
175
|
+
let tracer = trace.getTracer(serviceName);
|
|
176
|
+
if (shouldStartNodeSDK(trace.getTracerProvider())) {
|
|
177
|
+
new NodeSDK({
|
|
178
|
+
...options,
|
|
179
|
+
serviceName,
|
|
180
|
+
instrumentations
|
|
181
|
+
}).start();
|
|
182
|
+
tracer = trace.getTracer(serviceName);
|
|
183
|
+
}
|
|
184
|
+
if (!context._getContextManager?.() && contextManager) try {
|
|
185
|
+
contextManager.enable();
|
|
186
|
+
context.setGlobalContextManager(contextManager);
|
|
187
|
+
} catch {}
|
|
188
|
+
const httpServerDuration = metrics.getMeter(serviceName).createHistogram("http.server.request.duration", {
|
|
189
|
+
description: "Duration of HTTP server requests.",
|
|
190
|
+
unit: "s",
|
|
191
|
+
advice: { explicitBucketBoundaries: [
|
|
192
|
+
.005,
|
|
193
|
+
.01,
|
|
194
|
+
.025,
|
|
195
|
+
.05,
|
|
196
|
+
.075,
|
|
197
|
+
.1,
|
|
198
|
+
.25,
|
|
199
|
+
.5,
|
|
200
|
+
.75,
|
|
201
|
+
1,
|
|
202
|
+
2.5,
|
|
203
|
+
5,
|
|
204
|
+
7.5,
|
|
205
|
+
10,
|
|
206
|
+
30,
|
|
207
|
+
60,
|
|
208
|
+
120,
|
|
209
|
+
300,
|
|
210
|
+
600,
|
|
211
|
+
900,
|
|
212
|
+
1800
|
|
213
|
+
] }
|
|
214
|
+
});
|
|
215
|
+
return new Elysia({ name: "@elysia/opentelemetry" }).wrap((fn) => {
|
|
216
|
+
return (request) => {
|
|
217
|
+
if (!(checkIfShouldTrace ? checkIfShouldTrace(request) : true)) return fn(request);
|
|
218
|
+
const headers = headerHasToJSON ? request.headers.toJSON() : Object.fromEntries(request.headers.entries());
|
|
219
|
+
const ctx = propagation.extract(context.active(), headers);
|
|
220
|
+
return tracer.startActiveSpan("Root", { kind: SpanKind.SERVER }, ctx, (rootSpan) => {
|
|
221
|
+
const spanContext = trace.setSpan(ctx, rootSpan);
|
|
222
|
+
return context.with(spanContext, () => fn(request));
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
}).trace("global", ({ id, onRequest, onParse, onTransform, onBeforeHandle, onHandle, onAfterHandle, onError, onAfterResponse, onMapResponse, context: context$1, context: { path, request: { method } } }) => {
|
|
226
|
+
const rootSpan = trace.getActiveSpan();
|
|
227
|
+
if (!rootSpan) return;
|
|
228
|
+
function setParent(span) {
|
|
229
|
+
if (span.ended) return;
|
|
230
|
+
if (rootSpan.ended) return void span.end();
|
|
231
|
+
const newContext = trace.setSpan(context.active(), span);
|
|
232
|
+
context.active()._currentContext?.set(contextKeySpan, newContext.getValue(contextKeySpan));
|
|
233
|
+
}
|
|
234
|
+
function inspect(name) {
|
|
235
|
+
return function inspect({ onEvent, total, onStop }) {
|
|
236
|
+
if (total === 0 || rootSpan.ended) return;
|
|
237
|
+
tracer.startActiveSpan(name, {}, createContext(rootSpan), (event) => {
|
|
238
|
+
if (rootSpan.ended) return;
|
|
239
|
+
onEvent(({ name, onStop }) => {
|
|
240
|
+
const useChildSpan = total > 1;
|
|
241
|
+
let span;
|
|
242
|
+
if (useChildSpan) {
|
|
243
|
+
span = tracer.startSpan(name, {}, createContext(event));
|
|
244
|
+
setParent(span);
|
|
245
|
+
} else {
|
|
246
|
+
setParent(event);
|
|
247
|
+
span = event;
|
|
248
|
+
}
|
|
249
|
+
onStop(({ error }) => {
|
|
250
|
+
setParent(rootSpan);
|
|
251
|
+
if (span.ended || rootSpan.ended) return;
|
|
252
|
+
if (error) span.setAttributes({
|
|
253
|
+
"error.type": error.constructor?.name ?? error.name,
|
|
254
|
+
"error.stack": error.stack
|
|
255
|
+
});
|
|
256
|
+
if (useChildSpan) span.end();
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
onStop(() => {
|
|
260
|
+
setParent(rootSpan);
|
|
261
|
+
if (event.ended) return;
|
|
262
|
+
event.end();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const rawUrl = context$1.request.url;
|
|
268
|
+
const qi = context$1.qi;
|
|
269
|
+
let urlQuery = qi !== void 0 && qi !== -1 ? rawUrl.slice(qi + 1) : void 0;
|
|
270
|
+
let urlFull = rawUrl;
|
|
271
|
+
if (urlRedactOpts) {
|
|
272
|
+
if (urlQuery !== void 0) {
|
|
273
|
+
urlQuery = redactQueryString(urlQuery, sensitiveKeys);
|
|
274
|
+
urlFull = `${rawUrl.slice(0, qi)}?${urlQuery}`;
|
|
275
|
+
}
|
|
276
|
+
if (stripCreds && urlFull.indexOf("@") > 0) try {
|
|
277
|
+
const u = new URL(urlFull);
|
|
278
|
+
if (u.username || u.password) {
|
|
279
|
+
u.username = "";
|
|
280
|
+
u.password = "";
|
|
281
|
+
urlFull = u.href;
|
|
282
|
+
}
|
|
283
|
+
} catch {}
|
|
284
|
+
}
|
|
285
|
+
const attributes = Object.assign(Object.create(null), {
|
|
286
|
+
"http.request.id": id,
|
|
287
|
+
"http.request.method": method,
|
|
288
|
+
"url.path": path,
|
|
289
|
+
"url.full": urlFull
|
|
290
|
+
});
|
|
291
|
+
if (urlQuery !== void 0) attributes["url.query"] = urlQuery;
|
|
292
|
+
const protocolSeparator = urlFull.indexOf("://");
|
|
293
|
+
if (protocolSeparator > 0) attributes["url.scheme"] = urlFull.slice(0, protocolSeparator);
|
|
294
|
+
const requestStartTime = performance.now();
|
|
295
|
+
let durationRecorded = false;
|
|
296
|
+
const recordDuration = () => {
|
|
297
|
+
if (durationRecorded) return;
|
|
298
|
+
durationRecorded = true;
|
|
299
|
+
const durationS = (performance.now() - requestStartTime) / 1e3;
|
|
300
|
+
const statusCode = attributes["http.response.status_code"];
|
|
301
|
+
const metricAttributes = {
|
|
302
|
+
"http.request.method": attributes["http.request.method"] ?? method,
|
|
303
|
+
"url.scheme": attributes["url.scheme"],
|
|
304
|
+
"http.response.status_code": statusCode,
|
|
305
|
+
"http.route": attributes["http.route"]
|
|
306
|
+
};
|
|
307
|
+
if (typeof statusCode === "number" && statusCode >= 500) metricAttributes["error.type"] = String(statusCode);
|
|
308
|
+
httpServerDuration.record(durationS, metricAttributes);
|
|
309
|
+
};
|
|
310
|
+
onRequest(inspect("Request"));
|
|
311
|
+
onParse(inspect("Parse"));
|
|
312
|
+
onTransform(inspect("Transform"));
|
|
313
|
+
onBeforeHandle(inspect("BeforeHandle"));
|
|
314
|
+
onHandle(({ onStop }) => {
|
|
315
|
+
const span = tracer.startSpan("Handle", {}, createContext(rootSpan));
|
|
316
|
+
setParent(span);
|
|
317
|
+
onStop(({ error }) => {
|
|
318
|
+
setParent(rootSpan);
|
|
319
|
+
if (span.ended || rootSpan.ended) return;
|
|
320
|
+
if (error) {
|
|
321
|
+
span.recordException(error);
|
|
322
|
+
rootSpan.recordException(error);
|
|
323
|
+
}
|
|
324
|
+
span.end();
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
onAfterHandle(inspect("AfterHandle"));
|
|
328
|
+
onError((event) => {
|
|
329
|
+
inspect("Error")(event);
|
|
330
|
+
event.onStop(({ error }) => {
|
|
331
|
+
setParent(rootSpan);
|
|
332
|
+
if (rootSpan.ended) return;
|
|
333
|
+
{
|
|
334
|
+
let status = context$1.set.status;
|
|
335
|
+
if (typeof status === "string") status = StatusMap[status];
|
|
336
|
+
else if (typeof status !== "number" && typeof error?.status === "number") status = error.status;
|
|
337
|
+
if (typeof status === "number") {
|
|
338
|
+
attributes["http.response.status_code"] = status;
|
|
339
|
+
if (status >= 500) rootSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
340
|
+
}
|
|
341
|
+
rootSpan.setAttributes(attributes);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
onMapResponse(inspect("MapResponse"));
|
|
346
|
+
onTransform(() => {
|
|
347
|
+
const { cookie, request, route, path } = context$1;
|
|
348
|
+
const routeName = route ?? path;
|
|
349
|
+
rootSpan.updateName(`${method} ${routeName}`);
|
|
350
|
+
attributes["http.route"] = routeName;
|
|
351
|
+
/**
|
|
352
|
+
* ? Caution: This is not a standard way to get content-length
|
|
353
|
+
*
|
|
354
|
+
* As state in OpenTelemetry specification:
|
|
355
|
+
* The size of the request payload body in bytes.
|
|
356
|
+
* This is the number of bytes transferred excluding headers and is often,
|
|
357
|
+
* but not always, present as the Content-Length header.
|
|
358
|
+
* For requests using transport encoding, this should be the compressed size.
|
|
359
|
+
**/
|
|
360
|
+
const contentLength = request.headers.get("content-length");
|
|
361
|
+
if (contentLength) {
|
|
362
|
+
const number = parseNumericString(contentLength);
|
|
363
|
+
if (number !== null) attributes["http.request_content_length"] = number;
|
|
364
|
+
}
|
|
365
|
+
const userAgent = request.headers.get("User-Agent");
|
|
366
|
+
if (userAgent) attributes["user_agent.original"] = userAgent;
|
|
367
|
+
const server = context$1.server;
|
|
368
|
+
if (server) {
|
|
369
|
+
attributes["server.port"] = server.port ?? 80;
|
|
370
|
+
attributes["server.address"] = server.url.hostname;
|
|
371
|
+
}
|
|
372
|
+
let headers;
|
|
373
|
+
{
|
|
374
|
+
let hasHeaders;
|
|
375
|
+
let _headers;
|
|
376
|
+
if (context$1.headers) {
|
|
377
|
+
hasHeaders = true;
|
|
378
|
+
headers = context$1.headers;
|
|
379
|
+
_headers = Object.entries(context$1.headers);
|
|
380
|
+
} else if (hasHeaders = headerHasToJSON) {
|
|
381
|
+
headers = request.headers.toJSON();
|
|
382
|
+
_headers = Object.entries(headers);
|
|
383
|
+
} else {
|
|
384
|
+
headers = {};
|
|
385
|
+
_headers = request.headers.entries();
|
|
386
|
+
}
|
|
387
|
+
for (let [key, value] of _headers) {
|
|
388
|
+
key = key.toLowerCase();
|
|
389
|
+
if (hasHeaders) {
|
|
390
|
+
if (!requestHeaderWildcard && !spanRequestHeaderSet.has(key)) continue;
|
|
391
|
+
if (typeof value === "object") attributes[`http.request.header.${key}`] = JSON.stringify(value);
|
|
392
|
+
else if (value !== void 0) attributes[`http.request.header.${key}`] = value;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
if (typeof value === "object") {
|
|
396
|
+
const serialized = JSON.stringify(value);
|
|
397
|
+
headers[key] = serialized;
|
|
398
|
+
if (requestHeaderWildcard || spanRequestHeaderSet.has(key)) attributes[`http.request.header.${key}`] = serialized;
|
|
399
|
+
} else if (value !== void 0) {
|
|
400
|
+
headers[key] = value;
|
|
401
|
+
if (requestHeaderWildcard || spanRequestHeaderSet.has(key)) attributes[`http.request.header.${key}`] = value;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
{
|
|
406
|
+
let headers;
|
|
407
|
+
if (context$1.set.headers instanceof Headers) if (headerHasToJSON) headers = Object.entries(context$1.set.headers.toJSON());
|
|
408
|
+
else headers = context$1.set.headers.entries();
|
|
409
|
+
else headers = Object.entries(context$1.set.headers);
|
|
410
|
+
for (let [key, value] of headers) {
|
|
411
|
+
key = key.toLowerCase();
|
|
412
|
+
if (!responseHeaderWildcard && !spanResponseHeaderSet.has(key)) continue;
|
|
413
|
+
if (typeof value === "object") attributes[`http.response.header.${key}`] = JSON.stringify(value);
|
|
414
|
+
else attributes[`http.response.header.${key}`] = value;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (context$1.ip) attributes["client.address"] = context$1.ip;
|
|
418
|
+
else {
|
|
419
|
+
const ip = headers["true-client-ip"] ?? headers["cf-connection-ip"] ?? headers["x-forwarded-for"] ?? headers["x-real-ip"] ?? server?.requestIP(request);
|
|
420
|
+
if (ip) attributes["client.address"] = typeof ip === "string" ? ip : ip.address ?? ip.toString();
|
|
421
|
+
}
|
|
422
|
+
if ((requestHeaderWildcard || spanRequestHeaderSet.has("cookie")) && cookie) {
|
|
423
|
+
const _cookie = {};
|
|
424
|
+
for (const [key, { value }] of Object.entries(cookie)) _cookie[key] = JSON.stringify(value);
|
|
425
|
+
attributes["http.request.cookie"] = JSON.stringify(_cookie);
|
|
426
|
+
}
|
|
427
|
+
rootSpan.setAttributes(attributes);
|
|
428
|
+
});
|
|
429
|
+
onParse(() => {
|
|
430
|
+
const body = context$1.body;
|
|
431
|
+
if (body === void 0 || body === null || !recordRequestBody) return;
|
|
432
|
+
const { text, size } = serializeBody(body);
|
|
433
|
+
if (text) attributes["http.request.body"] = text;
|
|
434
|
+
attributes["http.request.body.size"] = size;
|
|
435
|
+
});
|
|
436
|
+
onMapResponse(() => {
|
|
437
|
+
const body = context$1.body;
|
|
438
|
+
if (body !== void 0 && body !== null && recordRequestBody) {
|
|
439
|
+
const { text, size } = serializeBody(body);
|
|
440
|
+
if (text) attributes["http.request.body"] = text;
|
|
441
|
+
attributes["http.request.body.size"] = size;
|
|
442
|
+
}
|
|
443
|
+
{
|
|
444
|
+
let status = context$1.set.status ?? 200;
|
|
445
|
+
if (typeof status === "string") status = StatusMap[status] ?? 200;
|
|
446
|
+
attributes["http.response.status_code"] = status;
|
|
447
|
+
}
|
|
448
|
+
const response = context$1.responseValue;
|
|
449
|
+
if (response !== void 0 && recordResponseBody) {
|
|
450
|
+
const { text, size } = serializeBody(response);
|
|
451
|
+
if (text) attributes["http.response.body"] = text;
|
|
452
|
+
attributes["http.response.body.size"] = size;
|
|
453
|
+
}
|
|
454
|
+
if (!rootSpan.ended) {
|
|
455
|
+
const statusCode = attributes["http.response.status_code"];
|
|
456
|
+
if (typeof statusCode === "number" && statusCode >= 500) rootSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
457
|
+
rootSpan.setAttributes(attributes);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
onAfterResponse((event) => {
|
|
461
|
+
inspect("AfterResponse")(event);
|
|
462
|
+
{
|
|
463
|
+
let status = context$1.set.status ?? 200;
|
|
464
|
+
if (typeof status === "string") status = StatusMap[status] ?? 200;
|
|
465
|
+
attributes["http.response.status_code"] = status;
|
|
466
|
+
}
|
|
467
|
+
const body = context$1.body;
|
|
468
|
+
if (body !== void 0 && body !== null && recordRequestBody) {
|
|
469
|
+
const { text, size } = serializeBody(body);
|
|
470
|
+
if (text) attributes["http.request.body"] = text;
|
|
471
|
+
attributes["http.request.body.size"] = size;
|
|
472
|
+
}
|
|
473
|
+
if (!rootSpan.ended) {
|
|
474
|
+
const statusCode = attributes["http.response.status_code"];
|
|
475
|
+
if (typeof statusCode === "number" && statusCode >= 500) rootSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
476
|
+
rootSpan.setAttributes(attributes);
|
|
477
|
+
}
|
|
478
|
+
event.onStop(() => {
|
|
479
|
+
setParent(rootSpan);
|
|
480
|
+
if (rootSpan.ended) return;
|
|
481
|
+
if (!rootSpan.ended) {
|
|
482
|
+
recordDuration();
|
|
483
|
+
rootSpan.end();
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
context$1.request.signal.addEventListener("abort", () => {
|
|
488
|
+
const active = trace.getActiveSpan();
|
|
489
|
+
if (active && !active.ended) active.end();
|
|
490
|
+
if (rootSpan.ended) return;
|
|
491
|
+
rootSpan.setStatus({
|
|
492
|
+
code: SpanStatusCode.ERROR,
|
|
493
|
+
message: "Request aborted"
|
|
494
|
+
});
|
|
495
|
+
recordDuration();
|
|
496
|
+
rootSpan.end();
|
|
497
|
+
});
|
|
498
|
+
});
|
|
676
499
|
};
|
|
500
|
+
|
|
501
|
+
//#endregion
|
|
502
|
+
export { contextKeySpan, getCurrentSpan, getTracer, opentelemetry, record, setAttributes, shouldStartNodeSDK, startActiveSpan, startSpan };
|