@glasstrace/sdk 0.19.0 → 0.20.1

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.
Files changed (63) hide show
  1. package/README.md +79 -0
  2. package/dist/chunk-BT2OCXCG.js +178 -0
  3. package/dist/chunk-BT2OCXCG.js.map +1 -0
  4. package/dist/{chunk-F2TZRBEH.js → chunk-DO2YPMQ5.js} +9 -181
  5. package/dist/chunk-DO2YPMQ5.js.map +1 -0
  6. package/dist/{chunk-YPXW2TN3.js → chunk-IP4NMDJK.js} +2 -2
  7. package/dist/{chunk-VN3GZDV6.js → chunk-IQN6TRMQ.js} +2 -2
  8. package/dist/{chunk-XNDHQN4S.js → chunk-LU3PPAOQ.js} +288 -54
  9. package/dist/chunk-LU3PPAOQ.js.map +1 -0
  10. package/dist/chunk-R4DAIPXD.js +4461 -0
  11. package/dist/chunk-R4DAIPXD.js.map +1 -0
  12. package/dist/{chunk-5N2IR4EO.js → chunk-TQ54WLCZ.js} +1 -1
  13. package/dist/{chunk-5N2IR4EO.js.map → chunk-TQ54WLCZ.js.map} +1 -1
  14. package/dist/chunk-Z2EGETTT.js +204 -0
  15. package/dist/chunk-Z2EGETTT.js.map +1 -0
  16. package/dist/cli/init.cjs +483 -152
  17. package/dist/cli/init.cjs.map +1 -1
  18. package/dist/cli/init.d.cts +48 -2
  19. package/dist/cli/init.d.ts +48 -2
  20. package/dist/cli/init.js +109 -7
  21. package/dist/cli/init.js.map +1 -1
  22. package/dist/cli/mcp-add.cjs.map +1 -1
  23. package/dist/cli/mcp-add.js +2 -2
  24. package/dist/cli/uninit.cjs +174 -54
  25. package/dist/cli/uninit.cjs.map +1 -1
  26. package/dist/cli/uninit.d.cts +2 -0
  27. package/dist/cli/uninit.d.ts +2 -0
  28. package/dist/cli/uninit.js +2 -1
  29. package/dist/edge-entry-Ds2fNOeh.d.ts +157 -0
  30. package/dist/edge-entry-FJFKkeFF.d.cts +157 -0
  31. package/dist/edge-entry.cjs +14939 -0
  32. package/dist/edge-entry.cjs.map +1 -0
  33. package/dist/edge-entry.d.cts +6 -0
  34. package/dist/edge-entry.d.ts +6 -0
  35. package/dist/edge-entry.js +16 -0
  36. package/dist/index.cjs +13 -4
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d-DgeH-pNJ.d.cts +191 -0
  39. package/dist/index.d-DgeH-pNJ.d.ts +191 -0
  40. package/dist/index.d.cts +9 -461
  41. package/dist/index.d.ts +9 -461
  42. package/dist/index.js +32 -4609
  43. package/dist/index.js.map +1 -1
  44. package/dist/node-entry.cjs +22492 -0
  45. package/dist/node-entry.cjs.map +1 -0
  46. package/dist/node-entry.d.cts +10 -0
  47. package/dist/node-entry.d.ts +10 -0
  48. package/dist/node-entry.js +101 -0
  49. package/dist/node-entry.js.map +1 -0
  50. package/dist/node-subpath.cjs +14506 -0
  51. package/dist/node-subpath.cjs.map +1 -0
  52. package/dist/node-subpath.d.cts +132 -0
  53. package/dist/node-subpath.d.ts +132 -0
  54. package/dist/node-subpath.js +30 -0
  55. package/dist/node-subpath.js.map +1 -0
  56. package/dist/{source-map-uploader-VPDZWWM2.js → source-map-uploader-YXWO6JLN.js} +3 -3
  57. package/dist/source-map-uploader-YXWO6JLN.js.map +1 -0
  58. package/package.json +4 -1
  59. package/dist/chunk-F2TZRBEH.js.map +0 -1
  60. package/dist/chunk-XNDHQN4S.js.map +0 -1
  61. /package/dist/{chunk-YPXW2TN3.js.map → chunk-IP4NMDJK.js.map} +0 -0
  62. /package/dist/{chunk-VN3GZDV6.js.map → chunk-IQN6TRMQ.js.map} +0 -0
  63. /package/dist/{source-map-uploader-VPDZWWM2.js.map → edge-entry.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,34 +1,47 @@
1
+ import {
2
+ GlasstraceExporter,
3
+ SessionManager,
4
+ captureError,
5
+ classifyFetchTarget,
6
+ createGlasstraceSpanProcessor,
7
+ getDateString,
8
+ getDiscoveryHandler,
9
+ getOrigin,
10
+ getStatus,
11
+ isReady,
12
+ registerGlasstrace,
13
+ waitForReady,
14
+ withGlasstraceConfig
15
+ } from "./chunk-R4DAIPXD.js";
16
+ import {
17
+ GlasstraceSpanProcessor,
18
+ SdkError,
19
+ captureCorrelationId,
20
+ createDiscoveryHandler
21
+ } from "./chunk-Z2EGETTT.js";
22
+ import "./chunk-DQ25VOKK.js";
1
23
  import {
2
24
  PRESIGNED_THRESHOLD_BYTES,
3
25
  collectSourceMaps,
4
26
  computeBuildHash,
5
27
  discoverSourceMapFiles,
6
- installConsoleCapture,
7
- maybeShowMcpNudge,
8
- maybeShowServerActionNudge,
9
- sdkLog,
10
28
  uploadSourceMaps,
11
29
  uploadSourceMapsAuto,
12
30
  uploadSourceMapsPresigned
13
- } from "./chunk-VN3GZDV6.js";
31
+ } from "./chunk-IQN6TRMQ.js";
14
32
  import {
15
- _setCurrentConfig,
16
- buildImportGraph,
17
- collectHealthReport,
18
- consumeRateLimitFlag,
19
- didLastInitSucceed,
20
- discoverTestFiles,
21
- extractImports,
22
33
  getActiveConfig,
23
- getClaimResult,
24
34
  getLinkedAccountId,
25
35
  loadCachedConfig,
26
36
  performInit,
27
- recordSpansDropped,
28
- recordSpansExported,
29
37
  saveCachedConfig,
30
38
  sendInitRequest
31
- } from "./chunk-F2TZRBEH.js";
39
+ } from "./chunk-DO2YPMQ5.js";
40
+ import {
41
+ buildImportGraph,
42
+ discoverTestFiles,
43
+ extractImports
44
+ } from "./chunk-BT2OCXCG.js";
32
45
  import {
33
46
  isAnonymousMode,
34
47
  isProductionDisabled,
@@ -38,4601 +51,11 @@ import {
38
51
  import {
39
52
  getOrCreateAnonKey,
40
53
  readAnonKey
41
- } from "./chunk-YPXW2TN3.js";
54
+ } from "./chunk-IP4NMDJK.js";
42
55
  import {
43
- GLASSTRACE_ATTRIBUTE_NAMES,
44
56
  deriveSessionId
45
- } from "./chunk-5N2IR4EO.js";
46
- import {
47
- DiagLogLevel,
48
- INVALID_SPAN_CONTEXT,
49
- ROOT_CONTEXT,
50
- SamplingDecision,
51
- SpanKind,
52
- SpanStatusCode,
53
- TraceFlags,
54
- baggageEntryMetadataFromString,
55
- context,
56
- createContextKey,
57
- createNoopMeter,
58
- diag,
59
- isSpanContextValid,
60
- isValidTraceId,
61
- trace
62
- } from "./chunk-DQ25VOKK.js";
63
- import {
64
- __require
65
- } from "./chunk-NSBPE2FW.js";
66
-
67
- // src/errors.ts
68
- var SdkError = class extends Error {
69
- code;
70
- constructor(code, message, cause) {
71
- super(message, { cause });
72
- this.name = "SdkError";
73
- this.code = code;
74
- }
75
- };
76
-
77
- // src/session.ts
78
- var FOUR_HOURS_MS = 4 * 60 * 60 * 1e3;
79
- var cachedGlasstraceEnv = process.env.GLASSTRACE_ENV;
80
- var cachedPort = process.env.PORT ?? "3000";
81
- function getOrigin() {
82
- if (cachedGlasstraceEnv) {
83
- return cachedGlasstraceEnv;
84
- }
85
- return `localhost:${cachedPort}`;
86
- }
87
- function getDateString() {
88
- const now = /* @__PURE__ */ new Date();
89
- const year = now.getUTCFullYear();
90
- const month = String(now.getUTCMonth() + 1).padStart(2, "0");
91
- const day = String(now.getUTCDate()).padStart(2, "0");
92
- return `${year}-${month}-${day}`;
93
- }
94
- var SessionManager = class {
95
- windowIndex = 0;
96
- lastActivityTimestamp = 0;
97
- lastDate = "";
98
- lastApiKey = "";
99
- currentSessionId = null;
100
- /**
101
- * Returns the current session ID, deriving a new one if:
102
- * - More than 4 hours have elapsed since last activity
103
- * - The UTC date has changed (resets window index to 0)
104
- * - The API key has changed (e.g., deferred anonymous key swap)
105
- * - This is the first call
106
- *
107
- * @param apiKey - The project's API key used in session derivation.
108
- * @returns The current or newly derived SessionId.
109
- */
110
- getSessionId(apiKey) {
111
- const now = Date.now();
112
- const currentDate = getDateString();
113
- const origin = getOrigin();
114
- const elapsed = now - this.lastActivityTimestamp;
115
- const dateChanged = currentDate !== this.lastDate;
116
- const apiKeyChanged = apiKey !== this.lastApiKey;
117
- if (dateChanged) {
118
- this.windowIndex = 0;
119
- this.lastDate = currentDate;
120
- this.lastApiKey = apiKey;
121
- this.currentSessionId = deriveSessionId(apiKey, origin, currentDate, this.windowIndex);
122
- } else if (apiKeyChanged) {
123
- this.lastApiKey = apiKey;
124
- this.currentSessionId = deriveSessionId(apiKey, origin, currentDate, this.windowIndex);
125
- } else if (this.currentSessionId === null || elapsed > FOUR_HOURS_MS) {
126
- if (this.currentSessionId !== null) {
127
- this.windowIndex++;
128
- }
129
- this.lastApiKey = apiKey;
130
- this.currentSessionId = deriveSessionId(apiKey, origin, currentDate, this.windowIndex);
131
- this.lastDate = currentDate;
132
- }
133
- this.lastActivityTimestamp = now;
134
- return this.currentSessionId;
135
- }
136
- };
137
-
138
- // src/fetch-classifier.ts
139
- var cachedPort2 = process.env.PORT ?? "3000";
140
- function classifyFetchTarget(url) {
141
- let parsed;
142
- try {
143
- parsed = new URL(url);
144
- } catch {
145
- return "unknown";
146
- }
147
- const hostname = parsed.hostname.toLowerCase();
148
- if (hostname === "supabase.co" || hostname.endsWith(".supabase.co") || hostname === "supabase.in" || hostname.endsWith(".supabase.in")) {
149
- return "supabase";
150
- }
151
- if (hostname === "stripe.com" || hostname.endsWith(".stripe.com")) {
152
- return "stripe";
153
- }
154
- const internalOrigin = `localhost:${cachedPort2}`;
155
- const parsedPort = parsed.port || (parsed.protocol === "https:" ? "443" : "80");
156
- const urlOrigin = `${hostname}:${parsedPort}`;
157
- if (urlOrigin === internalOrigin) {
158
- return "internal";
159
- }
160
- return "unknown";
161
- }
162
-
163
- // src/span-processor.ts
164
- var GlasstraceSpanProcessor = class {
165
- wrappedProcessor;
166
- /* eslint-disable @typescript-eslint/no-unused-vars -- backward compat signature */
167
- constructor(wrappedProcessor, _sessionManager2, _apiKey, _getConfig, _environment) {
168
- this.wrappedProcessor = wrappedProcessor;
169
- }
170
- onStart(span, parentContext) {
171
- this.wrappedProcessor.onStart(span, parentContext);
172
- }
173
- onEnd(readableSpan) {
174
- this.wrappedProcessor.onEnd(readableSpan);
175
- }
176
- async shutdown() {
177
- return this.wrappedProcessor.shutdown();
178
- }
179
- async forceFlush() {
180
- return this.wrappedProcessor.forceFlush();
181
- }
182
- };
183
-
184
- // src/enriching-exporter.ts
185
- var ATTR = GLASSTRACE_ATTRIBUTE_NAMES;
186
- var API_KEY_PENDING = "pending";
187
- var MAX_PENDING_SPANS = 1024;
188
- var GlasstraceExporter = class {
189
- getApiKey;
190
- sessionManager;
191
- getConfig;
192
- environment;
193
- endpointUrl;
194
- createDelegateFn;
195
- verbose;
196
- delegate = null;
197
- delegateKey = null;
198
- pendingBatches = [];
199
- pendingSpanCount = 0;
200
- overflowLogged = false;
201
- constructor(options) {
202
- this.getApiKey = options.getApiKey;
203
- this.sessionManager = options.sessionManager;
204
- this.getConfig = options.getConfig;
205
- this.environment = options.environment;
206
- this.endpointUrl = options.endpointUrl;
207
- this.createDelegateFn = options.createDelegate;
208
- this.verbose = options.verbose ?? false;
209
- this[/* @__PURE__ */ Symbol.for("glasstrace.exporter")] = true;
210
- }
211
- export(spans, resultCallback) {
212
- const currentKey = this.getApiKey();
213
- if (currentKey === API_KEY_PENDING) {
214
- this.bufferSpans(spans, resultCallback);
215
- return;
216
- }
217
- const enrichedSpans = spans.map((span) => this.enrichSpan(span));
218
- const exporter = this.ensureDelegate();
219
- if (exporter) {
220
- exporter.export(enrichedSpans, (result) => {
221
- if (result.code !== 0) {
222
- sdkLog("warn", `[glasstrace] Span export failed: ${result.error?.message ?? "unknown error"}`);
223
- }
224
- resultCallback(result);
225
- });
226
- recordSpansExported(enrichedSpans.length);
227
- } else {
228
- recordSpansDropped(enrichedSpans.length);
229
- resultCallback({ code: 0 });
230
- }
231
- }
232
- /**
233
- * Called when the API key transitions from "pending" to a resolved value.
234
- * Creates the delegate exporter and flushes all buffered spans.
235
- */
236
- notifyKeyResolved() {
237
- this.flushPending();
238
- }
239
- async shutdown() {
240
- const currentKey = this.getApiKey();
241
- if (currentKey !== API_KEY_PENDING && this.pendingBatches.length > 0) {
242
- this.flushPending();
243
- } else if (this.pendingBatches.length > 0) {
244
- console.warn(
245
- `[glasstrace] Shutdown with ${this.pendingSpanCount} buffered spans \u2014 API key never resolved, spans lost.`
246
- );
247
- recordSpansDropped(this.pendingSpanCount);
248
- for (const batch of this.pendingBatches) {
249
- batch.resultCallback({ code: 0 });
250
- }
251
- this.pendingBatches = [];
252
- this.pendingSpanCount = 0;
253
- }
254
- if (this.delegate) {
255
- return this.delegate.shutdown();
256
- }
257
- }
258
- /**
259
- * Flushes any pending buffered spans (if the API key has resolved) and
260
- * delegates to the underlying exporter's forceFlush to drain its queue.
261
- */
262
- forceFlush() {
263
- if (this.getApiKey() !== API_KEY_PENDING && this.pendingBatches.length > 0) {
264
- this.flushPending();
265
- }
266
- if (this.delegate?.forceFlush) {
267
- return this.delegate.forceFlush();
268
- }
269
- return Promise.resolve();
270
- }
271
- /**
272
- * Enriches a ReadableSpan with all glasstrace.* attributes.
273
- * Returns a new ReadableSpan wrapper; the original span is not mutated.
274
- *
275
- * Only {@link SessionManager.getSessionId} is individually guarded because
276
- * it calls into crypto and schema validation — a session ID failure should
277
- * not prevent the rest of enrichment. The other helper calls
278
- * ({@link deriveErrorCategory}, {@link deriveOrmProvider},
279
- * {@link classifyFetchTarget}) are pure functions on typed string inputs
280
- * and rely on the outer catch for any unexpected failure.
281
- *
282
- * On total failure, returns the original span unchanged.
283
- */
284
- enrichSpan(span) {
285
- try {
286
- const attrs = span.attributes ?? {};
287
- const name = span.name ?? "";
288
- const extra = {};
289
- extra[ATTR.TRACE_TYPE] = "server";
290
- try {
291
- const sessionId = this.sessionManager.getSessionId(this.getApiKey());
292
- extra[ATTR.SESSION_ID] = sessionId;
293
- } catch {
294
- }
295
- const env = this.environment ?? process.env.GLASSTRACE_ENV;
296
- if (env) {
297
- extra[ATTR.ENVIRONMENT] = env;
298
- }
299
- const existingCid = attrs["glasstrace.correlation.id"];
300
- if (typeof existingCid === "string") {
301
- extra[ATTR.CORRELATION_ID] = existingCid;
302
- }
303
- const rawRoute = attrs["http.route"];
304
- const route = typeof rawRoute === "string" ? rawRoute : name;
305
- if (route) {
306
- extra[ATTR.ROUTE] = route;
307
- }
308
- const rawUrl = attrs["http.url"] ?? attrs["url.full"] ?? attrs["http.target"];
309
- const trpcUrl = typeof rawUrl === "string" ? rawUrl : void 0;
310
- if (trpcUrl) {
311
- const trpcMatch = trpcUrl.match(/\/api\/trpc\/([^/?#]+)/);
312
- if (trpcMatch) {
313
- let procedure;
314
- try {
315
- procedure = decodeURIComponent(trpcMatch[1]);
316
- } catch {
317
- procedure = trpcMatch[1];
318
- }
319
- if (procedure) {
320
- extra[ATTR.TRPC_PROCEDURE] = procedure;
321
- }
322
- }
323
- }
324
- const method = attrs["http.method"] ?? attrs["http.request.method"];
325
- if (method) {
326
- extra[ATTR.HTTP_METHOD] = method;
327
- }
328
- const actionRoute = extractLeadingPath(route);
329
- if (method === "POST" && actionRoute) {
330
- const isApiRoute = actionRoute === "/api" || actionRoute.startsWith("/api/");
331
- const isInternalRoute = actionRoute.startsWith("/_next/");
332
- if (!isApiRoute && !isInternalRoute) {
333
- extra[ATTR.NEXT_ACTION_DETECTED] = true;
334
- if (typeof extra[ATTR.CORRELATION_ID] !== "string") {
335
- maybeShowServerActionNudge();
336
- }
337
- }
338
- }
339
- const statusCode = attrs["http.status_code"] ?? attrs["http.response.status_code"];
340
- if (statusCode !== void 0) {
341
- extra[ATTR.HTTP_STATUS_CODE] = statusCode;
342
- }
343
- const isErrorByStatus = span.status?.code === SpanStatusCode.ERROR;
344
- const isErrorByEvent = hasExceptionEvent(span);
345
- const isErrorByAttrs = typeof attrs["exception.type"] === "string" || typeof attrs["exception.message"] === "string";
346
- const statusNotExplicitlyOK = span.status?.code !== SpanStatusCode.OK;
347
- if (this.verbose && method) {
348
- sdkLog(
349
- "info",
350
- `[glasstrace] enrichSpan "${name}": status.code=${span.status?.code}, http.status_code=${statusCode}, isErrorByStatus=${isErrorByStatus}, isErrorByEvent=${isErrorByEvent}, isErrorByAttrs=${isErrorByAttrs}`
351
- );
352
- }
353
- if (method && statusNotExplicitlyOK && (isErrorByStatus || isErrorByEvent || isErrorByAttrs)) {
354
- if (statusCode === void 0 || statusCode === 0 || statusCode === 200) {
355
- const httpErrorType = attrs["error.type"];
356
- if (typeof httpErrorType === "string") {
357
- const parsed = parseInt(httpErrorType, 10);
358
- if (!isNaN(parsed) && parsed >= 400 && parsed <= 599) {
359
- extra[ATTR.HTTP_STATUS_CODE] = parsed;
360
- } else {
361
- extra[ATTR.HTTP_STATUS_CODE] = 500;
362
- }
363
- } else {
364
- extra[ATTR.HTTP_STATUS_CODE] = 500;
365
- }
366
- if (this.verbose) {
367
- sdkLog(
368
- "info",
369
- `[glasstrace] enrichSpan "${name}": inferred status_code=${extra[ATTR.HTTP_STATUS_CODE]} (was ${statusCode}), error.type=${attrs["error.type"]}`
370
- );
371
- }
372
- }
373
- }
374
- if (span.startTime && span.endTime) {
375
- const [startSec, startNano] = span.startTime;
376
- const [endSec, endNano] = span.endTime;
377
- const durationMs = (endSec - startSec) * 1e3 + (endNano - startNano) / 1e6;
378
- if (durationMs >= 0) {
379
- extra[ATTR.HTTP_DURATION_MS] = durationMs;
380
- }
381
- }
382
- const eventDetails = statusNotExplicitlyOK ? getExceptionEventDetails(span) : { type: void 0, message: void 0 };
383
- const errorMessage = attrs["exception.message"];
384
- if (typeof errorMessage === "string") {
385
- extra[ATTR.ERROR_MESSAGE] = errorMessage;
386
- } else if (eventDetails.message) {
387
- extra[ATTR.ERROR_MESSAGE] = eventDetails.message;
388
- }
389
- const errorType = attrs["exception.type"];
390
- if (typeof errorType === "string") {
391
- extra[ATTR.ERROR_CODE] = errorType;
392
- extra[ATTR.ERROR_CATEGORY] = deriveErrorCategory(errorType);
393
- } else if (eventDetails.type) {
394
- extra[ATTR.ERROR_CODE] = eventDetails.type;
395
- extra[ATTR.ERROR_CATEGORY] = deriveErrorCategory(eventDetails.type);
396
- }
397
- if (this.verbose && (extra[ATTR.ERROR_MESSAGE] || extra[ATTR.ERROR_CODE])) {
398
- const msgSource = typeof errorMessage === "string" ? "attrs" : eventDetails.message ? "event" : "none";
399
- const typeSource = typeof errorType === "string" ? "attrs" : eventDetails.type ? "event" : "none";
400
- sdkLog(
401
- "info",
402
- `[glasstrace] enrichSpan "${name}": error.message source=${msgSource}, error.code source=${typeSource}`
403
- );
404
- }
405
- const errorField = attrs["error.field"];
406
- if (typeof errorField === "string") {
407
- extra[ATTR.ERROR_FIELD] = errorField;
408
- }
409
- if (this.getConfig().errorResponseBodies) {
410
- const responseBody = attrs["glasstrace.internal.response_body"];
411
- if (typeof responseBody === "string") {
412
- extra[ATTR.ERROR_RESPONSE_BODY] = responseBody.slice(0, 500);
413
- }
414
- }
415
- const spanAny = span;
416
- const instrumentationName = spanAny.instrumentationScope?.name ?? spanAny.instrumentationLibrary?.name ?? "";
417
- const ormProvider = deriveOrmProvider(instrumentationName);
418
- if (ormProvider) {
419
- extra[ATTR.ORM_PROVIDER] = ormProvider;
420
- const table = attrs["db.sql.table"];
421
- const prismaModel = attrs["db.prisma.model"];
422
- const model = typeof table === "string" ? table : typeof prismaModel === "string" ? prismaModel : void 0;
423
- if (model) {
424
- extra[ATTR.ORM_MODEL] = model;
425
- }
426
- const operation = attrs["db.operation"];
427
- if (typeof operation === "string") {
428
- extra[ATTR.ORM_OPERATION] = operation;
429
- }
430
- }
431
- const httpUrl = attrs["http.url"];
432
- const fullUrl = attrs["url.full"];
433
- const url = typeof httpUrl === "string" ? httpUrl : typeof fullUrl === "string" ? fullUrl : void 0;
434
- if (url && span.kind === SpanKind.CLIENT) {
435
- extra[ATTR.FETCH_TARGET] = classifyFetchTarget(url);
436
- }
437
- return createEnrichedSpan(span, extra);
438
- } catch {
439
- return span;
440
- }
441
- }
442
- /**
443
- * Lazily creates the delegate OTLP exporter once the API key is resolved.
444
- * Recreates the delegate if the key has changed (e.g., after key rotation)
445
- * so the Authorization header stays current.
446
- */
447
- ensureDelegate() {
448
- if (!this.createDelegateFn) return null;
449
- const currentKey = this.getApiKey();
450
- if (currentKey === API_KEY_PENDING) return null;
451
- if (this.delegate && this.delegateKey === currentKey) {
452
- return this.delegate;
453
- }
454
- if (this.delegate) {
455
- void this.delegate.shutdown?.().catch(() => {
456
- });
457
- }
458
- this.delegate = this.createDelegateFn(this.endpointUrl, {
459
- Authorization: `Bearer ${currentKey}`
460
- });
461
- this.delegateKey = currentKey;
462
- return this.delegate;
463
- }
464
- /**
465
- * Buffers raw (unenriched) spans while the API key is pending.
466
- * Evicts oldest batches if the buffer exceeds MAX_PENDING_SPANS.
467
- * Re-checks the key after buffering to close the race window where
468
- * the key resolves between the caller's check and this buffer call.
469
- */
470
- bufferSpans(spans, resultCallback) {
471
- this.pendingBatches.push({ spans, resultCallback });
472
- this.pendingSpanCount += spans.length;
473
- while (this.pendingSpanCount > MAX_PENDING_SPANS && this.pendingBatches.length > 1) {
474
- const evicted = this.pendingBatches.shift();
475
- this.pendingSpanCount -= evicted.spans.length;
476
- recordSpansDropped(evicted.spans.length);
477
- evicted.resultCallback({ code: 0 });
478
- if (!this.overflowLogged) {
479
- this.overflowLogged = true;
480
- console.warn(
481
- "[glasstrace] Pending span buffer overflow \u2014 oldest spans evicted. This usually means the API key is taking too long to resolve."
482
- );
483
- }
484
- }
485
- if (this.getApiKey() !== API_KEY_PENDING) {
486
- this.flushPending();
487
- }
488
- }
489
- /**
490
- * Flushes all buffered spans through the delegate exporter.
491
- * Enriches spans at flush time (not buffer time) so that session IDs
492
- * are computed with the resolved API key instead of the "pending" sentinel.
493
- */
494
- flushPending() {
495
- if (this.pendingBatches.length === 0) return;
496
- const exporter = this.ensureDelegate();
497
- if (!exporter) {
498
- let discardedCount = 0;
499
- for (const batch of this.pendingBatches) {
500
- discardedCount += batch.spans.length;
501
- batch.resultCallback({ code: 0 });
502
- }
503
- recordSpansDropped(discardedCount);
504
- this.pendingBatches = [];
505
- this.pendingSpanCount = 0;
506
- return;
507
- }
508
- const batches = this.pendingBatches;
509
- this.pendingBatches = [];
510
- this.pendingSpanCount = 0;
511
- for (const batch of batches) {
512
- const enriched = batch.spans.map((span) => this.enrichSpan(span));
513
- exporter.export(enriched, (result) => {
514
- if (result.code !== 0) {
515
- sdkLog("warn", `[glasstrace] Span export failed: ${result.error?.message ?? "unknown error"}`);
516
- }
517
- batch.resultCallback(result);
518
- });
519
- recordSpansExported(enriched.length);
520
- }
521
- }
522
- };
523
- function createEnrichedSpan(span, extra) {
524
- const enrichedAttributes = { ...span.attributes, ...extra };
525
- return Object.create(span, {
526
- attributes: {
527
- value: enrichedAttributes,
528
- enumerable: true
529
- }
530
- });
531
- }
532
- function hasExceptionEvent(span) {
533
- return span.events?.some((e) => e.name === "exception") ?? false;
534
- }
535
- function getExceptionEventDetails(span) {
536
- const event = span.events?.find((e) => e.name === "exception");
537
- if (!event?.attributes) {
538
- return { type: void 0, message: void 0 };
539
- }
540
- const type = event.attributes["exception.type"];
541
- const message = event.attributes["exception.message"];
542
- return {
543
- type: typeof type === "string" ? type : void 0,
544
- message: typeof message === "string" ? message : void 0
545
- };
546
- }
547
- function extractLeadingPath(raw) {
548
- if (!raw) return void 0;
549
- const trimmed = raw.trim();
550
- if (trimmed.length === 0) return void 0;
551
- if (trimmed.startsWith("/")) {
552
- const firstSpace = trimmed.indexOf(" ");
553
- return firstSpace === -1 ? trimmed : trimmed.slice(0, firstSpace);
554
- }
555
- for (const token of trimmed.split(/\s+/)) {
556
- if (token.startsWith("/")) {
557
- return token;
558
- }
559
- }
560
- return void 0;
561
- }
562
- function deriveOrmProvider(instrumentationName) {
563
- const lower = instrumentationName.toLowerCase();
564
- if (lower.includes("prisma")) {
565
- return "prisma";
566
- }
567
- if (lower.includes("drizzle")) {
568
- return "drizzle";
569
- }
570
- return null;
571
- }
572
- function deriveErrorCategory(errorType) {
573
- const lower = errorType.toLowerCase();
574
- if (lower.includes("validation") || lower.includes("zod")) {
575
- return "validation";
576
- }
577
- if (lower.includes("network") || lower.includes("econnrefused") || lower.includes("fetch") || lower.includes("timeout")) {
578
- return "network";
579
- }
580
- if (lower.includes("auth") || lower.includes("unauthorized") || lower.includes("forbidden")) {
581
- return "auth";
582
- }
583
- if (lower.includes("notfound") || lower.includes("not_found")) {
584
- return "not-found";
585
- }
586
- return "internal";
587
- }
588
-
589
- // src/discovery-endpoint.ts
590
- function isAllowedOrigin(origin) {
591
- if (origin === null) return true;
592
- if (origin.startsWith("chrome-extension://")) return true;
593
- if (origin.startsWith("moz-extension://")) return true;
594
- if (origin.startsWith("safari-web-extension://")) return true;
595
- return false;
596
- }
597
- function buildCorsHeaders(origin) {
598
- const headers = {
599
- "Content-Type": "application/json",
600
- Vary: "Origin"
601
- };
602
- if (origin && isAllowedOrigin(origin)) {
603
- headers["Access-Control-Allow-Origin"] = origin;
604
- }
605
- return headers;
606
- }
607
- function createDiscoveryHandler(getAnonKey, getSessionId, getClaimState) {
608
- return async (request) => {
609
- let url;
610
- try {
611
- url = new URL(request.url);
612
- } catch {
613
- return null;
614
- }
615
- if (url.pathname !== "/__glasstrace/config") {
616
- return null;
617
- }
618
- const origin = request.headers.get("Origin");
619
- const corsHeaders = buildCorsHeaders(origin);
620
- if (request.method === "OPTIONS") {
621
- return new Response(null, {
622
- status: 204,
623
- headers: {
624
- ...corsHeaders,
625
- "Access-Control-Allow-Methods": "GET, OPTIONS",
626
- "Access-Control-Allow-Headers": "Content-Type"
627
- }
628
- });
629
- }
630
- if (request.method !== "GET") {
631
- return new Response(
632
- JSON.stringify({ error: "method_not_allowed" }),
633
- {
634
- status: 405,
635
- headers: corsHeaders
636
- }
637
- );
638
- }
639
- try {
640
- const anonKey = await getAnonKey();
641
- if (anonKey === null) {
642
- return new Response(
643
- JSON.stringify({ error: "not_ready" }),
644
- {
645
- status: 503,
646
- headers: corsHeaders
647
- }
648
- );
649
- }
650
- const sessionId = getSessionId();
651
- const responseBody = { key: anonKey, sessionId };
652
- const claimState = getClaimState?.();
653
- if (claimState?.claimed) {
654
- responseBody.claimed = true;
655
- if (claimState.accountHint) {
656
- responseBody.accountHint = claimState.accountHint;
657
- }
658
- }
659
- return new Response(
660
- JSON.stringify(responseBody),
661
- {
662
- status: 200,
663
- headers: corsHeaders
664
- }
665
- );
666
- } catch {
667
- return new Response(
668
- JSON.stringify({ error: "internal_error" }),
669
- {
670
- status: 500,
671
- headers: corsHeaders
672
- }
673
- );
674
- }
675
- };
676
- }
677
-
678
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/OTLPExporterBase.js
679
- var OTLPExporterBase = class {
680
- _delegate;
681
- constructor(delegate) {
682
- this._delegate = delegate;
683
- }
684
- /**
685
- * Export items.
686
- * @param items
687
- * @param resultCallback
688
- */
689
- export(items, resultCallback) {
690
- this._delegate.export(items, resultCallback);
691
- }
692
- forceFlush() {
693
- return this._delegate.forceFlush();
694
- }
695
- shutdown() {
696
- return this._delegate.shutdown();
697
- }
698
- };
699
-
700
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/types.js
701
- var OTLPExporterError = class extends Error {
702
- code;
703
- name = "OTLPExporterError";
704
- data;
705
- constructor(message, code, data) {
706
- super(message);
707
- this.data = data;
708
- this.code = code;
709
- }
710
- };
711
-
712
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/shared-configuration.js
713
- function validateTimeoutMillis(timeoutMillis) {
714
- if (Number.isFinite(timeoutMillis) && timeoutMillis > 0) {
715
- return timeoutMillis;
716
- }
717
- throw new Error(`Configuration: timeoutMillis is invalid, expected number greater than 0 (actual: '${timeoutMillis}')`);
718
- }
719
- function wrapStaticHeadersInFunction(headers) {
720
- if (headers == null) {
721
- return void 0;
722
- }
723
- return async () => headers;
724
- }
725
- function mergeOtlpSharedConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration) {
726
- return {
727
- timeoutMillis: validateTimeoutMillis(userProvidedConfiguration.timeoutMillis ?? fallbackConfiguration.timeoutMillis ?? defaultConfiguration.timeoutMillis),
728
- concurrencyLimit: userProvidedConfiguration.concurrencyLimit ?? fallbackConfiguration.concurrencyLimit ?? defaultConfiguration.concurrencyLimit,
729
- compression: userProvidedConfiguration.compression ?? fallbackConfiguration.compression ?? defaultConfiguration.compression
730
- };
731
- }
732
- function getSharedConfigurationDefaults() {
733
- return {
734
- timeoutMillis: 1e4,
735
- concurrencyLimit: 30,
736
- compression: "none"
737
- };
738
- }
739
-
740
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/bounded-queue-export-promise-handler.js
741
- var BoundedQueueExportPromiseHandler = class {
742
- _concurrencyLimit;
743
- _sendingPromises = [];
744
- /**
745
- * @param concurrencyLimit maximum promises allowed in a queue at the same time.
746
- */
747
- constructor(concurrencyLimit) {
748
- this._concurrencyLimit = concurrencyLimit;
749
- }
750
- pushPromise(promise) {
751
- if (this.hasReachedLimit()) {
752
- throw new Error("Concurrency Limit reached");
753
- }
754
- this._sendingPromises.push(promise);
755
- const popPromise = () => {
756
- const index = this._sendingPromises.indexOf(promise);
757
- void this._sendingPromises.splice(index, 1);
758
- };
759
- promise.then(popPromise, popPromise);
760
- }
761
- hasReachedLimit() {
762
- return this._sendingPromises.length >= this._concurrencyLimit;
763
- }
764
- async awaitAll() {
765
- await Promise.all(this._sendingPromises);
766
- }
767
- };
768
- function createBoundedQueueExportPromiseHandler(options) {
769
- return new BoundedQueueExportPromiseHandler(options.concurrencyLimit);
770
- }
771
-
772
- // ../../node_modules/@opentelemetry/core/build/esm/trace/suppress-tracing.js
773
- var SUPPRESS_TRACING_KEY = createContextKey("OpenTelemetry SDK Context Key SUPPRESS_TRACING");
774
- function suppressTracing(context2) {
775
- return context2.setValue(SUPPRESS_TRACING_KEY, true);
776
- }
777
- function isTracingSuppressed(context2) {
778
- return context2.getValue(SUPPRESS_TRACING_KEY) === true;
779
- }
780
-
781
- // ../../node_modules/@opentelemetry/core/build/esm/baggage/constants.js
782
- var BAGGAGE_KEY_PAIR_SEPARATOR = "=";
783
- var BAGGAGE_PROPERTIES_SEPARATOR = ";";
784
- var BAGGAGE_ITEMS_SEPARATOR = ",";
785
-
786
- // ../../node_modules/@opentelemetry/core/build/esm/baggage/utils.js
787
- function parsePairKeyValue(entry) {
788
- if (!entry)
789
- return;
790
- const metadataSeparatorIndex = entry.indexOf(BAGGAGE_PROPERTIES_SEPARATOR);
791
- const keyPairPart = metadataSeparatorIndex === -1 ? entry : entry.substring(0, metadataSeparatorIndex);
792
- const separatorIndex = keyPairPart.indexOf(BAGGAGE_KEY_PAIR_SEPARATOR);
793
- if (separatorIndex <= 0)
794
- return;
795
- const rawKey = keyPairPart.substring(0, separatorIndex).trim();
796
- const rawValue = keyPairPart.substring(separatorIndex + 1).trim();
797
- if (!rawKey || !rawValue)
798
- return;
799
- let key;
800
- let value;
801
- try {
802
- key = decodeURIComponent(rawKey);
803
- value = decodeURIComponent(rawValue);
804
- } catch {
805
- return;
806
- }
807
- let metadata;
808
- if (metadataSeparatorIndex !== -1 && metadataSeparatorIndex < entry.length - 1) {
809
- const metadataString = entry.substring(metadataSeparatorIndex + 1);
810
- metadata = baggageEntryMetadataFromString(metadataString);
811
- }
812
- return { key, value, metadata };
813
- }
814
- function parseKeyPairsIntoRecord(value) {
815
- const result = {};
816
- if (typeof value === "string" && value.length > 0) {
817
- value.split(BAGGAGE_ITEMS_SEPARATOR).forEach((entry) => {
818
- const keyPair = parsePairKeyValue(entry);
819
- if (keyPair !== void 0 && keyPair.value.length > 0) {
820
- result[keyPair.key] = keyPair.value;
821
- }
822
- });
823
- }
824
- return result;
825
- }
826
-
827
- // ../../node_modules/@opentelemetry/core/build/esm/common/attributes.js
828
- function sanitizeAttributes(attributes) {
829
- const out = {};
830
- if (typeof attributes !== "object" || attributes == null) {
831
- return out;
832
- }
833
- for (const key in attributes) {
834
- if (!Object.prototype.hasOwnProperty.call(attributes, key)) {
835
- continue;
836
- }
837
- if (!isAttributeKey(key)) {
838
- diag.warn(`Invalid attribute key: ${key}`);
839
- continue;
840
- }
841
- const val = attributes[key];
842
- if (!isAttributeValue(val)) {
843
- diag.warn(`Invalid attribute value set for key: ${key}`);
844
- continue;
845
- }
846
- if (Array.isArray(val)) {
847
- out[key] = val.slice();
848
- } else {
849
- out[key] = val;
850
- }
851
- }
852
- return out;
853
- }
854
- function isAttributeKey(key) {
855
- return typeof key === "string" && key !== "";
856
- }
857
- function isAttributeValue(val) {
858
- if (val == null) {
859
- return true;
860
- }
861
- if (Array.isArray(val)) {
862
- return isHomogeneousAttributeValueArray(val);
863
- }
864
- return isValidPrimitiveAttributeValueType(typeof val);
865
- }
866
- function isHomogeneousAttributeValueArray(arr) {
867
- let type;
868
- for (const element of arr) {
869
- if (element == null)
870
- continue;
871
- const elementType = typeof element;
872
- if (elementType === type) {
873
- continue;
874
- }
875
- if (!type) {
876
- if (isValidPrimitiveAttributeValueType(elementType)) {
877
- type = elementType;
878
- continue;
879
- }
880
- return false;
881
- }
882
- return false;
883
- }
884
- return true;
885
- }
886
- function isValidPrimitiveAttributeValueType(valType) {
887
- switch (valType) {
888
- case "number":
889
- case "boolean":
890
- case "string":
891
- return true;
892
- }
893
- return false;
894
- }
895
-
896
- // ../../node_modules/@opentelemetry/core/build/esm/common/logging-error-handler.js
897
- function loggingErrorHandler() {
898
- return (ex) => {
899
- diag.error(stringifyException(ex));
900
- };
901
- }
902
- function stringifyException(ex) {
903
- if (typeof ex === "string") {
904
- return ex;
905
- } else {
906
- return JSON.stringify(flattenException(ex));
907
- }
908
- }
909
- function flattenException(ex) {
910
- const result = {};
911
- let current = ex;
912
- while (current !== null) {
913
- Object.getOwnPropertyNames(current).forEach((propertyName) => {
914
- if (result[propertyName])
915
- return;
916
- const value = current[propertyName];
917
- if (value) {
918
- result[propertyName] = String(value);
919
- }
920
- });
921
- current = Object.getPrototypeOf(current);
922
- }
923
- return result;
924
- }
925
-
926
- // ../../node_modules/@opentelemetry/core/build/esm/common/global-error-handler.js
927
- var delegateHandler = loggingErrorHandler();
928
- function globalErrorHandler(ex) {
929
- try {
930
- delegateHandler(ex);
931
- } catch {
932
- }
933
- }
934
-
935
- // ../../node_modules/@opentelemetry/core/build/esm/platform/node/environment.js
936
- import { inspect } from "util";
937
- function getNumberFromEnv(key) {
938
- const raw = process.env[key];
939
- if (raw == null || raw.trim() === "") {
940
- return void 0;
941
- }
942
- const value = Number(raw);
943
- if (isNaN(value)) {
944
- diag.warn(`Unknown value ${inspect(raw)} for ${key}, expected a number, using defaults`);
945
- return void 0;
946
- }
947
- return value;
948
- }
949
- function getStringFromEnv(key) {
950
- const raw = process.env[key];
951
- if (raw == null || raw.trim() === "") {
952
- return void 0;
953
- }
954
- return raw;
955
- }
956
-
957
- // ../../node_modules/@opentelemetry/core/build/esm/version.js
958
- var VERSION = "2.6.1";
959
-
960
- // ../../node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js
961
- var ATTR_EXCEPTION_MESSAGE = "exception.message";
962
- var ATTR_EXCEPTION_STACKTRACE = "exception.stacktrace";
963
- var ATTR_EXCEPTION_TYPE = "exception.type";
964
- var ATTR_SERVICE_NAME = "service.name";
965
- var ATTR_TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language";
966
- var TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS = "nodejs";
967
- var ATTR_TELEMETRY_SDK_NAME = "telemetry.sdk.name";
968
- var ATTR_TELEMETRY_SDK_VERSION = "telemetry.sdk.version";
969
-
970
- // ../../node_modules/@opentelemetry/core/build/esm/semconv.js
971
- var ATTR_PROCESS_RUNTIME_NAME = "process.runtime.name";
972
-
973
- // ../../node_modules/@opentelemetry/core/build/esm/platform/node/sdk-info.js
974
- var SDK_INFO = {
975
- [ATTR_TELEMETRY_SDK_NAME]: "opentelemetry",
976
- [ATTR_PROCESS_RUNTIME_NAME]: "node",
977
- [ATTR_TELEMETRY_SDK_LANGUAGE]: TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
978
- [ATTR_TELEMETRY_SDK_VERSION]: VERSION
979
- };
980
-
981
- // ../../node_modules/@opentelemetry/core/build/esm/platform/node/index.js
982
- var otperformance = performance;
983
-
984
- // ../../node_modules/@opentelemetry/core/build/esm/common/time.js
985
- var NANOSECOND_DIGITS = 9;
986
- var NANOSECOND_DIGITS_IN_MILLIS = 6;
987
- var MILLISECONDS_TO_NANOSECONDS = Math.pow(10, NANOSECOND_DIGITS_IN_MILLIS);
988
- var SECOND_TO_NANOSECONDS = Math.pow(10, NANOSECOND_DIGITS);
989
- function millisToHrTime(epochMillis) {
990
- const epochSeconds = epochMillis / 1e3;
991
- const seconds = Math.trunc(epochSeconds);
992
- const nanos = Math.round(epochMillis % 1e3 * MILLISECONDS_TO_NANOSECONDS);
993
- return [seconds, nanos];
994
- }
995
- function hrTime(performanceNow) {
996
- const timeOrigin = millisToHrTime(otperformance.timeOrigin);
997
- const now = millisToHrTime(typeof performanceNow === "number" ? performanceNow : otperformance.now());
998
- return addHrTimes(timeOrigin, now);
999
- }
1000
- function hrTimeDuration(startTime, endTime) {
1001
- let seconds = endTime[0] - startTime[0];
1002
- let nanos = endTime[1] - startTime[1];
1003
- if (nanos < 0) {
1004
- seconds -= 1;
1005
- nanos += SECOND_TO_NANOSECONDS;
1006
- }
1007
- return [seconds, nanos];
1008
- }
1009
- function hrTimeToNanoseconds(time) {
1010
- return time[0] * SECOND_TO_NANOSECONDS + time[1];
1011
- }
1012
- function isTimeInputHrTime(value) {
1013
- return Array.isArray(value) && value.length === 2 && typeof value[0] === "number" && typeof value[1] === "number";
1014
- }
1015
- function isTimeInput(value) {
1016
- return isTimeInputHrTime(value) || typeof value === "number" || value instanceof Date;
1017
- }
1018
- function addHrTimes(time1, time2) {
1019
- const out = [time1[0] + time2[0], time1[1] + time2[1]];
1020
- if (out[1] >= SECOND_TO_NANOSECONDS) {
1021
- out[1] -= SECOND_TO_NANOSECONDS;
1022
- out[0] += 1;
1023
- }
1024
- return out;
1025
- }
1026
-
1027
- // ../../node_modules/@opentelemetry/core/build/esm/ExportResult.js
1028
- var ExportResultCode;
1029
- (function(ExportResultCode2) {
1030
- ExportResultCode2[ExportResultCode2["SUCCESS"] = 0] = "SUCCESS";
1031
- ExportResultCode2[ExportResultCode2["FAILED"] = 1] = "FAILED";
1032
- })(ExportResultCode || (ExportResultCode = {}));
1033
-
1034
- // ../../node_modules/@opentelemetry/core/build/esm/utils/lodash.merge.js
1035
- var objectTag = "[object Object]";
1036
- var nullTag = "[object Null]";
1037
- var undefinedTag = "[object Undefined]";
1038
- var funcProto = Function.prototype;
1039
- var funcToString = funcProto.toString;
1040
- var objectCtorString = funcToString.call(Object);
1041
- var getPrototypeOf = Object.getPrototypeOf;
1042
- var objectProto = Object.prototype;
1043
- var hasOwnProperty = objectProto.hasOwnProperty;
1044
- var symToStringTag = Symbol ? Symbol.toStringTag : void 0;
1045
- var nativeObjectToString = objectProto.toString;
1046
- function isPlainObject(value) {
1047
- if (!isObjectLike(value) || baseGetTag(value) !== objectTag) {
1048
- return false;
1049
- }
1050
- const proto = getPrototypeOf(value);
1051
- if (proto === null) {
1052
- return true;
1053
- }
1054
- const Ctor = hasOwnProperty.call(proto, "constructor") && proto.constructor;
1055
- return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) === objectCtorString;
1056
- }
1057
- function isObjectLike(value) {
1058
- return value != null && typeof value == "object";
1059
- }
1060
- function baseGetTag(value) {
1061
- if (value == null) {
1062
- return value === void 0 ? undefinedTag : nullTag;
1063
- }
1064
- return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
1065
- }
1066
- function getRawTag(value) {
1067
- const isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag];
1068
- let unmasked = false;
1069
- try {
1070
- value[symToStringTag] = void 0;
1071
- unmasked = true;
1072
- } catch {
1073
- }
1074
- const result = nativeObjectToString.call(value);
1075
- if (unmasked) {
1076
- if (isOwn) {
1077
- value[symToStringTag] = tag;
1078
- } else {
1079
- delete value[symToStringTag];
1080
- }
1081
- }
1082
- return result;
1083
- }
1084
- function objectToString(value) {
1085
- return nativeObjectToString.call(value);
1086
- }
1087
-
1088
- // ../../node_modules/@opentelemetry/core/build/esm/utils/merge.js
1089
- var MAX_LEVEL = 20;
1090
- function merge(...args) {
1091
- let result = args.shift();
1092
- const objects = /* @__PURE__ */ new WeakMap();
1093
- while (args.length > 0) {
1094
- result = mergeTwoObjects(result, args.shift(), 0, objects);
1095
- }
1096
- return result;
1097
- }
1098
- function takeValue(value) {
1099
- if (isArray(value)) {
1100
- return value.slice();
1101
- }
1102
- return value;
1103
- }
1104
- function mergeTwoObjects(one, two, level = 0, objects) {
1105
- let result;
1106
- if (level > MAX_LEVEL) {
1107
- return void 0;
1108
- }
1109
- level++;
1110
- if (isPrimitive(one) || isPrimitive(two) || isFunction(two)) {
1111
- result = takeValue(two);
1112
- } else if (isArray(one)) {
1113
- result = one.slice();
1114
- if (isArray(two)) {
1115
- for (let i = 0, j = two.length; i < j; i++) {
1116
- result.push(takeValue(two[i]));
1117
- }
1118
- } else if (isObject(two)) {
1119
- const keys = Object.keys(two);
1120
- for (let i = 0, j = keys.length; i < j; i++) {
1121
- const key = keys[i];
1122
- result[key] = takeValue(two[key]);
1123
- }
1124
- }
1125
- } else if (isObject(one)) {
1126
- if (isObject(two)) {
1127
- if (!shouldMerge(one, two)) {
1128
- return two;
1129
- }
1130
- result = Object.assign({}, one);
1131
- const keys = Object.keys(two);
1132
- for (let i = 0, j = keys.length; i < j; i++) {
1133
- const key = keys[i];
1134
- const twoValue = two[key];
1135
- if (isPrimitive(twoValue)) {
1136
- if (typeof twoValue === "undefined") {
1137
- delete result[key];
1138
- } else {
1139
- result[key] = twoValue;
1140
- }
1141
- } else {
1142
- const obj1 = result[key];
1143
- const obj2 = twoValue;
1144
- if (wasObjectReferenced(one, key, objects) || wasObjectReferenced(two, key, objects)) {
1145
- delete result[key];
1146
- } else {
1147
- if (isObject(obj1) && isObject(obj2)) {
1148
- const arr1 = objects.get(obj1) || [];
1149
- const arr2 = objects.get(obj2) || [];
1150
- arr1.push({ obj: one, key });
1151
- arr2.push({ obj: two, key });
1152
- objects.set(obj1, arr1);
1153
- objects.set(obj2, arr2);
1154
- }
1155
- result[key] = mergeTwoObjects(result[key], twoValue, level, objects);
1156
- }
1157
- }
1158
- }
1159
- } else {
1160
- result = two;
1161
- }
1162
- }
1163
- return result;
1164
- }
1165
- function wasObjectReferenced(obj, key, objects) {
1166
- const arr = objects.get(obj[key]) || [];
1167
- for (let i = 0, j = arr.length; i < j; i++) {
1168
- const info = arr[i];
1169
- if (info.key === key && info.obj === obj) {
1170
- return true;
1171
- }
1172
- }
1173
- return false;
1174
- }
1175
- function isArray(value) {
1176
- return Array.isArray(value);
1177
- }
1178
- function isFunction(value) {
1179
- return typeof value === "function";
1180
- }
1181
- function isObject(value) {
1182
- return !isPrimitive(value) && !isArray(value) && !isFunction(value) && typeof value === "object";
1183
- }
1184
- function isPrimitive(value) {
1185
- return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "undefined" || value instanceof Date || value instanceof RegExp || value === null;
1186
- }
1187
- function shouldMerge(one, two) {
1188
- if (!isPlainObject(one) || !isPlainObject(two)) {
1189
- return false;
1190
- }
1191
- return true;
1192
- }
1193
-
1194
- // ../../node_modules/@opentelemetry/core/build/esm/utils/promise.js
1195
- var Deferred = class {
1196
- _promise;
1197
- _resolve;
1198
- _reject;
1199
- constructor() {
1200
- this._promise = new Promise((resolve2, reject) => {
1201
- this._resolve = resolve2;
1202
- this._reject = reject;
1203
- });
1204
- }
1205
- get promise() {
1206
- return this._promise;
1207
- }
1208
- resolve(val) {
1209
- this._resolve(val);
1210
- }
1211
- reject(err) {
1212
- this._reject(err);
1213
- }
1214
- };
1215
-
1216
- // ../../node_modules/@opentelemetry/core/build/esm/utils/callback.js
1217
- var BindOnceFuture = class {
1218
- _isCalled = false;
1219
- _deferred = new Deferred();
1220
- _callback;
1221
- _that;
1222
- constructor(callback, that) {
1223
- this._callback = callback;
1224
- this._that = that;
1225
- }
1226
- get isCalled() {
1227
- return this._isCalled;
1228
- }
1229
- get promise() {
1230
- return this._deferred.promise;
1231
- }
1232
- call(...args) {
1233
- if (!this._isCalled) {
1234
- this._isCalled = true;
1235
- try {
1236
- Promise.resolve(this._callback.call(this._that, ...args)).then((val) => this._deferred.resolve(val), (err) => this._deferred.reject(err));
1237
- } catch (err) {
1238
- this._deferred.reject(err);
1239
- }
1240
- }
1241
- return this._deferred.promise;
1242
- }
1243
- };
1244
-
1245
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/logging-response-handler.js
1246
- function isPartialSuccessResponse(response) {
1247
- return Object.prototype.hasOwnProperty.call(response, "partialSuccess");
1248
- }
1249
- function createLoggingPartialSuccessResponseHandler() {
1250
- return {
1251
- handleResponse(response) {
1252
- if (response == null || !isPartialSuccessResponse(response) || response.partialSuccess == null || Object.keys(response.partialSuccess).length === 0) {
1253
- return;
1254
- }
1255
- diag.warn("Received Partial Success response:", JSON.stringify(response.partialSuccess));
1256
- }
1257
- };
1258
- }
1259
-
1260
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/otlp-export-delegate.js
1261
- var OTLPExportDelegate = class {
1262
- _diagLogger;
1263
- _transport;
1264
- _serializer;
1265
- _responseHandler;
1266
- _promiseQueue;
1267
- _timeout;
1268
- constructor(transport, serializer, responseHandler, promiseQueue, timeout) {
1269
- this._transport = transport;
1270
- this._serializer = serializer;
1271
- this._responseHandler = responseHandler;
1272
- this._promiseQueue = promiseQueue;
1273
- this._timeout = timeout;
1274
- this._diagLogger = diag.createComponentLogger({
1275
- namespace: "OTLPExportDelegate"
1276
- });
1277
- }
1278
- export(internalRepresentation, resultCallback) {
1279
- this._diagLogger.debug("items to be sent", internalRepresentation);
1280
- if (this._promiseQueue.hasReachedLimit()) {
1281
- resultCallback({
1282
- code: ExportResultCode.FAILED,
1283
- error: new Error("Concurrent export limit reached")
1284
- });
1285
- return;
1286
- }
1287
- const serializedRequest = this._serializer.serializeRequest(internalRepresentation);
1288
- if (serializedRequest == null) {
1289
- resultCallback({
1290
- code: ExportResultCode.FAILED,
1291
- error: new Error("Nothing to send")
1292
- });
1293
- return;
1294
- }
1295
- this._promiseQueue.pushPromise(this._transport.send(serializedRequest, this._timeout).then((response) => {
1296
- if (response.status === "success") {
1297
- if (response.data != null) {
1298
- try {
1299
- this._responseHandler.handleResponse(this._serializer.deserializeResponse(response.data));
1300
- } catch (e) {
1301
- this._diagLogger.warn("Export succeeded but could not deserialize response - is the response specification compliant?", e, response.data);
1302
- }
1303
- }
1304
- resultCallback({
1305
- code: ExportResultCode.SUCCESS
1306
- });
1307
- return;
1308
- } else if (response.status === "failure" && response.error) {
1309
- resultCallback({
1310
- code: ExportResultCode.FAILED,
1311
- error: response.error
1312
- });
1313
- return;
1314
- } else if (response.status === "retryable") {
1315
- resultCallback({
1316
- code: ExportResultCode.FAILED,
1317
- error: response.error ?? new OTLPExporterError("Export failed with retryable status")
1318
- });
1319
- } else {
1320
- resultCallback({
1321
- code: ExportResultCode.FAILED,
1322
- error: new OTLPExporterError("Export failed with unknown error")
1323
- });
1324
- }
1325
- }, (reason) => resultCallback({
1326
- code: ExportResultCode.FAILED,
1327
- error: reason
1328
- })));
1329
- }
1330
- forceFlush() {
1331
- return this._promiseQueue.awaitAll();
1332
- }
1333
- async shutdown() {
1334
- this._diagLogger.debug("shutdown started");
1335
- await this.forceFlush();
1336
- this._transport.shutdown();
1337
- }
1338
- };
1339
- function createOtlpExportDelegate(components, settings) {
1340
- return new OTLPExportDelegate(components.transport, components.serializer, createLoggingPartialSuccessResponseHandler(), components.promiseHandler, settings.timeout);
1341
- }
1342
-
1343
- // ../../node_modules/@opentelemetry/otlp-transformer/build/esm/common/internal.js
1344
- function createResource(resource, encoder) {
1345
- const result = {
1346
- attributes: toAttributes(resource.attributes, encoder),
1347
- droppedAttributesCount: 0
1348
- };
1349
- const schemaUrl = resource.schemaUrl;
1350
- if (schemaUrl && schemaUrl !== "")
1351
- result.schemaUrl = schemaUrl;
1352
- return result;
1353
- }
1354
- function createInstrumentationScope(scope) {
1355
- return {
1356
- name: scope.name,
1357
- version: scope.version
1358
- };
1359
- }
1360
- function toAttributes(attributes, encoder) {
1361
- return Object.keys(attributes).map((key) => toKeyValue(key, attributes[key], encoder));
1362
- }
1363
- function toKeyValue(key, value, encoder) {
1364
- return {
1365
- key,
1366
- value: toAnyValue(value, encoder)
1367
- };
1368
- }
1369
- function toAnyValue(value, encoder) {
1370
- const t = typeof value;
1371
- if (t === "string")
1372
- return { stringValue: value };
1373
- if (t === "number") {
1374
- if (!Number.isInteger(value))
1375
- return { doubleValue: value };
1376
- return { intValue: value };
1377
- }
1378
- if (t === "boolean")
1379
- return { boolValue: value };
1380
- if (value instanceof Uint8Array)
1381
- return { bytesValue: encoder.encodeUint8Array(value) };
1382
- if (Array.isArray(value)) {
1383
- const values = new Array(value.length);
1384
- for (let i = 0; i < value.length; i++) {
1385
- values[i] = toAnyValue(value[i], encoder);
1386
- }
1387
- return { arrayValue: { values } };
1388
- }
1389
- if (t === "object" && value != null) {
1390
- const keys = Object.keys(value);
1391
- const values = new Array(keys.length);
1392
- for (let i = 0; i < keys.length; i++) {
1393
- values[i] = {
1394
- key: keys[i],
1395
- value: toAnyValue(value[keys[i]], encoder)
1396
- };
1397
- }
1398
- return { kvlistValue: { values } };
1399
- }
1400
- return {};
1401
- }
1402
-
1403
- // ../../node_modules/@opentelemetry/otlp-transformer/build/esm/common/utils.js
1404
- function hrTimeToNanos(hrTime2) {
1405
- const NANOSECONDS = BigInt(1e9);
1406
- return BigInt(Math.trunc(hrTime2[0])) * NANOSECONDS + BigInt(Math.trunc(hrTime2[1]));
1407
- }
1408
- function encodeAsString(hrTime2) {
1409
- const nanos = hrTimeToNanos(hrTime2);
1410
- return nanos.toString();
1411
- }
1412
- var encodeTimestamp = typeof BigInt !== "undefined" ? encodeAsString : hrTimeToNanoseconds;
1413
- function identity(value) {
1414
- return value;
1415
- }
1416
- var JSON_ENCODER = {
1417
- encodeHrTime: encodeTimestamp,
1418
- encodeSpanContext: identity,
1419
- encodeOptionalSpanContext: identity,
1420
- encodeUint8Array: (bytes) => {
1421
- if (typeof Buffer !== "undefined") {
1422
- return Buffer.from(bytes).toString("base64");
1423
- }
1424
- const chars = new Array(bytes.length);
1425
- for (let i = 0; i < bytes.length; i++) {
1426
- chars[i] = String.fromCharCode(bytes[i]);
1427
- }
1428
- return btoa(chars.join(""));
1429
- }
1430
- };
1431
-
1432
- // ../../node_modules/@opentelemetry/resources/build/esm/default-service-name.js
1433
- var serviceName;
1434
- function defaultServiceName() {
1435
- if (serviceName === void 0) {
1436
- try {
1437
- const argv0 = globalThis.process.argv0;
1438
- serviceName = argv0 ? `unknown_service:${argv0}` : "unknown_service";
1439
- } catch {
1440
- serviceName = "unknown_service";
1441
- }
1442
- }
1443
- return serviceName;
1444
- }
1445
-
1446
- // ../../node_modules/@opentelemetry/resources/build/esm/utils.js
1447
- var isPromiseLike = (val) => {
1448
- return val !== null && typeof val === "object" && typeof val.then === "function";
1449
- };
1450
-
1451
- // ../../node_modules/@opentelemetry/resources/build/esm/ResourceImpl.js
1452
- var ResourceImpl = class _ResourceImpl {
1453
- _rawAttributes;
1454
- _asyncAttributesPending = false;
1455
- _schemaUrl;
1456
- _memoizedAttributes;
1457
- static FromAttributeList(attributes, options) {
1458
- const res = new _ResourceImpl({}, options);
1459
- res._rawAttributes = guardedRawAttributes(attributes);
1460
- res._asyncAttributesPending = attributes.filter(([_, val]) => isPromiseLike(val)).length > 0;
1461
- return res;
1462
- }
1463
- constructor(resource, options) {
1464
- const attributes = resource.attributes ?? {};
1465
- this._rawAttributes = Object.entries(attributes).map(([k, v]) => {
1466
- if (isPromiseLike(v)) {
1467
- this._asyncAttributesPending = true;
1468
- }
1469
- return [k, v];
1470
- });
1471
- this._rawAttributes = guardedRawAttributes(this._rawAttributes);
1472
- this._schemaUrl = validateSchemaUrl(options?.schemaUrl);
1473
- }
1474
- get asyncAttributesPending() {
1475
- return this._asyncAttributesPending;
1476
- }
1477
- async waitForAsyncAttributes() {
1478
- if (!this.asyncAttributesPending) {
1479
- return;
1480
- }
1481
- for (let i = 0; i < this._rawAttributes.length; i++) {
1482
- const [k, v] = this._rawAttributes[i];
1483
- this._rawAttributes[i] = [k, isPromiseLike(v) ? await v : v];
1484
- }
1485
- this._asyncAttributesPending = false;
1486
- }
1487
- get attributes() {
1488
- if (this.asyncAttributesPending) {
1489
- diag.error("Accessing resource attributes before async attributes settled");
1490
- }
1491
- if (this._memoizedAttributes) {
1492
- return this._memoizedAttributes;
1493
- }
1494
- const attrs = {};
1495
- for (const [k, v] of this._rawAttributes) {
1496
- if (isPromiseLike(v)) {
1497
- diag.debug(`Unsettled resource attribute ${k} skipped`);
1498
- continue;
1499
- }
1500
- if (v != null) {
1501
- attrs[k] ??= v;
1502
- }
1503
- }
1504
- if (!this._asyncAttributesPending) {
1505
- this._memoizedAttributes = attrs;
1506
- }
1507
- return attrs;
1508
- }
1509
- getRawAttributes() {
1510
- return this._rawAttributes;
1511
- }
1512
- get schemaUrl() {
1513
- return this._schemaUrl;
1514
- }
1515
- merge(resource) {
1516
- if (resource == null)
1517
- return this;
1518
- const mergedSchemaUrl = mergeSchemaUrl(this, resource);
1519
- const mergedOptions = mergedSchemaUrl ? { schemaUrl: mergedSchemaUrl } : void 0;
1520
- return _ResourceImpl.FromAttributeList([...resource.getRawAttributes(), ...this.getRawAttributes()], mergedOptions);
1521
- }
1522
- };
1523
- function resourceFromAttributes(attributes, options) {
1524
- return ResourceImpl.FromAttributeList(Object.entries(attributes), options);
1525
- }
1526
- function defaultResource() {
1527
- return resourceFromAttributes({
1528
- [ATTR_SERVICE_NAME]: defaultServiceName(),
1529
- [ATTR_TELEMETRY_SDK_LANGUAGE]: SDK_INFO[ATTR_TELEMETRY_SDK_LANGUAGE],
1530
- [ATTR_TELEMETRY_SDK_NAME]: SDK_INFO[ATTR_TELEMETRY_SDK_NAME],
1531
- [ATTR_TELEMETRY_SDK_VERSION]: SDK_INFO[ATTR_TELEMETRY_SDK_VERSION]
1532
- });
1533
- }
1534
- function guardedRawAttributes(attributes) {
1535
- return attributes.map(([k, v]) => {
1536
- if (isPromiseLike(v)) {
1537
- return [
1538
- k,
1539
- v.catch((err) => {
1540
- diag.debug("promise rejection for resource attribute: %s - %s", k, err);
1541
- return void 0;
1542
- })
1543
- ];
1544
- }
1545
- return [k, v];
1546
- });
1547
- }
1548
- function validateSchemaUrl(schemaUrl) {
1549
- if (typeof schemaUrl === "string" || schemaUrl === void 0) {
1550
- return schemaUrl;
1551
- }
1552
- diag.warn("Schema URL must be string or undefined, got %s. Schema URL will be ignored.", schemaUrl);
1553
- return void 0;
1554
- }
1555
- function mergeSchemaUrl(old, updating) {
1556
- const oldSchemaUrl = old?.schemaUrl;
1557
- const updatingSchemaUrl = updating?.schemaUrl;
1558
- const isOldEmpty = oldSchemaUrl === void 0 || oldSchemaUrl === "";
1559
- const isUpdatingEmpty = updatingSchemaUrl === void 0 || updatingSchemaUrl === "";
1560
- if (isOldEmpty) {
1561
- return updatingSchemaUrl;
1562
- }
1563
- if (isUpdatingEmpty) {
1564
- return oldSchemaUrl;
1565
- }
1566
- if (oldSchemaUrl === updatingSchemaUrl) {
1567
- return oldSchemaUrl;
1568
- }
1569
- diag.warn('Schema URL merge conflict: old resource has "%s", updating resource has "%s". Resulting resource will have undefined Schema URL.', oldSchemaUrl, updatingSchemaUrl);
1570
- return void 0;
1571
- }
1572
-
1573
- // ../../node_modules/@opentelemetry/otlp-transformer/build/esm/trace/internal.js
1574
- var SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK = 256;
1575
- var SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 512;
1576
- function buildSpanFlagsFrom(traceFlags, isRemote) {
1577
- let flags = traceFlags & 255 | SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK;
1578
- if (isRemote) {
1579
- flags |= SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK;
1580
- }
1581
- return flags;
1582
- }
1583
- function sdkSpanToOtlpSpan(span, encoder) {
1584
- const ctx = span.spanContext();
1585
- const status = span.status;
1586
- const parentSpanId = span.parentSpanContext?.spanId ? encoder.encodeSpanContext(span.parentSpanContext?.spanId) : void 0;
1587
- return {
1588
- traceId: encoder.encodeSpanContext(ctx.traceId),
1589
- spanId: encoder.encodeSpanContext(ctx.spanId),
1590
- parentSpanId,
1591
- traceState: ctx.traceState?.serialize(),
1592
- name: span.name,
1593
- // Span kind is offset by 1 because the API does not define a value for unset
1594
- kind: span.kind == null ? 0 : span.kind + 1,
1595
- startTimeUnixNano: encoder.encodeHrTime(span.startTime),
1596
- endTimeUnixNano: encoder.encodeHrTime(span.endTime),
1597
- attributes: toAttributes(span.attributes, encoder),
1598
- droppedAttributesCount: span.droppedAttributesCount,
1599
- events: span.events.map((event) => toOtlpSpanEvent(event, encoder)),
1600
- droppedEventsCount: span.droppedEventsCount,
1601
- status: {
1602
- // API and proto enums share the same values
1603
- code: status.code,
1604
- message: status.message
1605
- },
1606
- links: span.links.map((link) => toOtlpLink(link, encoder)),
1607
- droppedLinksCount: span.droppedLinksCount,
1608
- flags: buildSpanFlagsFrom(ctx.traceFlags, span.parentSpanContext?.isRemote)
1609
- };
1610
- }
1611
- function toOtlpLink(link, encoder) {
1612
- return {
1613
- attributes: link.attributes ? toAttributes(link.attributes, encoder) : [],
1614
- spanId: encoder.encodeSpanContext(link.context.spanId),
1615
- traceId: encoder.encodeSpanContext(link.context.traceId),
1616
- traceState: link.context.traceState?.serialize(),
1617
- droppedAttributesCount: link.droppedAttributesCount || 0,
1618
- flags: buildSpanFlagsFrom(link.context.traceFlags, link.context.isRemote)
1619
- };
1620
- }
1621
- function toOtlpSpanEvent(timedEvent, encoder) {
1622
- return {
1623
- attributes: timedEvent.attributes ? toAttributes(timedEvent.attributes, encoder) : [],
1624
- name: timedEvent.name,
1625
- timeUnixNano: encoder.encodeHrTime(timedEvent.time),
1626
- droppedAttributesCount: timedEvent.droppedAttributesCount || 0
1627
- };
1628
- }
1629
- function createExportTraceServiceRequest(spans, encoder) {
1630
- return {
1631
- resourceSpans: spanRecordsToResourceSpans(spans, encoder)
1632
- };
1633
- }
1634
- function createResourceMap(readableSpans) {
1635
- const resourceMap = /* @__PURE__ */ new Map();
1636
- for (const record of readableSpans) {
1637
- let ilsMap = resourceMap.get(record.resource);
1638
- if (!ilsMap) {
1639
- ilsMap = /* @__PURE__ */ new Map();
1640
- resourceMap.set(record.resource, ilsMap);
1641
- }
1642
- const instrumentationScopeKey = `${record.instrumentationScope.name}@${record.instrumentationScope.version || ""}:${record.instrumentationScope.schemaUrl || ""}`;
1643
- let records = ilsMap.get(instrumentationScopeKey);
1644
- if (!records) {
1645
- records = [];
1646
- ilsMap.set(instrumentationScopeKey, records);
1647
- }
1648
- records.push(record);
1649
- }
1650
- return resourceMap;
1651
- }
1652
- function spanRecordsToResourceSpans(readableSpans, encoder) {
1653
- const resourceMap = createResourceMap(readableSpans);
1654
- const out = [];
1655
- const entryIterator = resourceMap.entries();
1656
- let entry = entryIterator.next();
1657
- while (!entry.done) {
1658
- const [resource, ilmMap] = entry.value;
1659
- const scopeResourceSpans = [];
1660
- const ilmIterator = ilmMap.values();
1661
- let ilmEntry = ilmIterator.next();
1662
- while (!ilmEntry.done) {
1663
- const scopeSpans = ilmEntry.value;
1664
- if (scopeSpans.length > 0) {
1665
- const spans = scopeSpans.map((readableSpan) => sdkSpanToOtlpSpan(readableSpan, encoder));
1666
- scopeResourceSpans.push({
1667
- scope: createInstrumentationScope(scopeSpans[0].instrumentationScope),
1668
- spans,
1669
- schemaUrl: scopeSpans[0].instrumentationScope.schemaUrl
1670
- });
1671
- }
1672
- ilmEntry = ilmIterator.next();
1673
- }
1674
- const processedResource = createResource(resource, encoder);
1675
- const transformedSpans = {
1676
- resource: processedResource,
1677
- scopeSpans: scopeResourceSpans,
1678
- schemaUrl: processedResource.schemaUrl
1679
- };
1680
- out.push(transformedSpans);
1681
- entry = entryIterator.next();
1682
- }
1683
- return out;
1684
- }
1685
-
1686
- // ../../node_modules/@opentelemetry/otlp-transformer/build/esm/trace/json/trace.js
1687
- var JsonTraceSerializer = {
1688
- serializeRequest: (arg) => {
1689
- const request = createExportTraceServiceRequest(arg, JSON_ENCODER);
1690
- const encoder = new TextEncoder();
1691
- return encoder.encode(JSON.stringify(request));
1692
- },
1693
- deserializeResponse: (arg) => {
1694
- if (arg.length === 0) {
1695
- return {};
1696
- }
1697
- const decoder = new TextDecoder();
1698
- return JSON.parse(decoder.decode(arg));
1699
- }
1700
- };
1701
-
1702
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/util.js
1703
- function validateAndNormalizeHeaders(partialHeaders) {
1704
- const headers = {};
1705
- Object.entries(partialHeaders ?? {}).forEach(([key, value]) => {
1706
- if (typeof value !== "undefined") {
1707
- headers[key] = String(value);
1708
- } else {
1709
- diag.warn(`Header "${key}" has invalid value (${value}) and will be ignored`);
1710
- }
1711
- });
1712
- return headers;
1713
- }
1714
-
1715
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/otlp-http-configuration.js
1716
- function mergeHeaders(userProvidedHeaders, fallbackHeaders, defaultHeaders) {
1717
- return async () => {
1718
- const requiredHeaders = {
1719
- ...await defaultHeaders()
1720
- };
1721
- const headers = {};
1722
- if (fallbackHeaders != null) {
1723
- Object.assign(headers, await fallbackHeaders());
1724
- }
1725
- if (userProvidedHeaders != null) {
1726
- Object.assign(headers, validateAndNormalizeHeaders(await userProvidedHeaders()));
1727
- }
1728
- return Object.assign(headers, requiredHeaders);
1729
- };
1730
- }
1731
- function validateUserProvidedUrl(url) {
1732
- if (url == null) {
1733
- return void 0;
1734
- }
1735
- try {
1736
- const base = globalThis.location?.href;
1737
- return new URL(url, base).href;
1738
- } catch {
1739
- throw new Error(`Configuration: Could not parse user-provided export URL: '${url}'`);
1740
- }
1741
- }
1742
- function mergeOtlpHttpConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration) {
1743
- return {
1744
- ...mergeOtlpSharedConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration),
1745
- headers: mergeHeaders(userProvidedConfiguration.headers, fallbackConfiguration.headers, defaultConfiguration.headers),
1746
- url: validateUserProvidedUrl(userProvidedConfiguration.url) ?? fallbackConfiguration.url ?? defaultConfiguration.url
1747
- };
1748
- }
1749
- function getHttpConfigurationDefaults(requiredHeaders, signalResourcePath) {
1750
- return {
1751
- ...getSharedConfigurationDefaults(),
1752
- headers: async () => requiredHeaders,
1753
- url: "http://localhost:4318/" + signalResourcePath
1754
- };
1755
- }
1756
-
1757
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/otlp-node-http-configuration.js
1758
- function httpAgentFactoryFromOptions(options) {
1759
- return async (protocol) => {
1760
- const isInsecure = protocol === "http:";
1761
- const module = isInsecure ? import("http") : import("https");
1762
- const { Agent } = await module;
1763
- if (isInsecure) {
1764
- const { ca, cert, key, ...insecureOptions } = options;
1765
- return new Agent(insecureOptions);
1766
- }
1767
- return new Agent(options);
1768
- };
1769
- }
1770
- function mergeOtlpNodeHttpConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration) {
1771
- return {
1772
- ...mergeOtlpHttpConfigurationWithDefaults(userProvidedConfiguration, fallbackConfiguration, defaultConfiguration),
1773
- agentFactory: userProvidedConfiguration.agentFactory ?? fallbackConfiguration.agentFactory ?? defaultConfiguration.agentFactory,
1774
- userAgent: userProvidedConfiguration.userAgent
1775
- };
1776
- }
1777
- function getNodeHttpConfigurationDefaults(requiredHeaders, signalResourcePath) {
1778
- return {
1779
- ...getHttpConfigurationDefaults(requiredHeaders, signalResourcePath),
1780
- agentFactory: httpAgentFactoryFromOptions({ keepAlive: true })
1781
- };
1782
- }
1783
-
1784
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/transport/http-transport-utils.js
1785
- import * as zlib from "zlib";
1786
- import { Readable } from "stream";
1787
-
1788
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/is-export-retryable.js
1789
- function isExportHTTPErrorRetryable(statusCode) {
1790
- return statusCode === 429 || statusCode === 502 || statusCode === 503 || statusCode === 504;
1791
- }
1792
- function parseRetryAfterToMills(retryAfter) {
1793
- if (retryAfter == null) {
1794
- return void 0;
1795
- }
1796
- const seconds = Number.parseInt(retryAfter, 10);
1797
- if (Number.isInteger(seconds)) {
1798
- return seconds > 0 ? seconds * 1e3 : -1;
1799
- }
1800
- const delay = new Date(retryAfter).getTime() - Date.now();
1801
- if (delay >= 0) {
1802
- return delay;
1803
- }
1804
- return 0;
1805
- }
1806
-
1807
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/version.js
1808
- var VERSION2 = "0.214.0";
1809
-
1810
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/transport/http-transport-utils.js
1811
- var DEFAULT_USER_AGENT = `OTel-OTLP-Exporter-JavaScript/${VERSION2}`;
1812
- function sendWithHttp(request, url, headers, compression, userAgent, agent, data, timeoutMillis) {
1813
- return new Promise((resolve2) => {
1814
- const parsedUrl = new URL(url);
1815
- if (userAgent) {
1816
- headers["User-Agent"] = `${userAgent} ${DEFAULT_USER_AGENT}`;
1817
- } else {
1818
- headers["User-Agent"] = DEFAULT_USER_AGENT;
1819
- }
1820
- const options = {
1821
- hostname: parsedUrl.hostname,
1822
- port: parsedUrl.port,
1823
- path: parsedUrl.pathname,
1824
- method: "POST",
1825
- headers,
1826
- agent
1827
- };
1828
- const req = request(options, (res) => {
1829
- const responseData = [];
1830
- res.on("data", (chunk) => responseData.push(chunk));
1831
- res.on("end", () => {
1832
- if (res.statusCode && res.statusCode <= 299) {
1833
- resolve2({
1834
- status: "success",
1835
- data: Buffer.concat(responseData)
1836
- });
1837
- } else if (res.statusCode && isExportHTTPErrorRetryable(res.statusCode)) {
1838
- resolve2({
1839
- status: "retryable",
1840
- retryInMillis: parseRetryAfterToMills(res.headers["retry-after"])
1841
- });
1842
- } else {
1843
- const error = new OTLPExporterError(res.statusMessage, res.statusCode, Buffer.concat(responseData).toString());
1844
- resolve2({
1845
- status: "failure",
1846
- error
1847
- });
1848
- }
1849
- });
1850
- res.on("error", (error) => {
1851
- if (res.statusCode && res.statusCode <= 299) {
1852
- resolve2({
1853
- status: "success"
1854
- });
1855
- } else if (res.statusCode && isExportHTTPErrorRetryable(res.statusCode)) {
1856
- resolve2({
1857
- status: "retryable",
1858
- error,
1859
- retryInMillis: parseRetryAfterToMills(res.headers["retry-after"])
1860
- });
1861
- } else {
1862
- resolve2({
1863
- status: "failure",
1864
- error
1865
- });
1866
- }
1867
- });
1868
- });
1869
- req.setTimeout(timeoutMillis, () => {
1870
- req.destroy();
1871
- resolve2({
1872
- status: "retryable",
1873
- error: new Error("Request timed out")
1874
- });
1875
- });
1876
- req.on("error", (error) => {
1877
- if (isHttpTransportNetworkErrorRetryable(error)) {
1878
- resolve2({
1879
- status: "retryable",
1880
- error
1881
- });
1882
- } else {
1883
- resolve2({
1884
- status: "failure",
1885
- error
1886
- });
1887
- }
1888
- });
1889
- compressAndSend(req, compression, data, (error) => {
1890
- resolve2({
1891
- status: "failure",
1892
- error
1893
- });
1894
- });
1895
- });
1896
- }
1897
- function compressAndSend(req, compression, data, onError) {
1898
- let dataStream = readableFromUint8Array(data);
1899
- if (compression === "gzip") {
1900
- req.setHeader("Content-Encoding", "gzip");
1901
- dataStream = dataStream.on("error", onError).pipe(zlib.createGzip()).on("error", onError);
1902
- }
1903
- dataStream.pipe(req).on("error", onError);
1904
- }
1905
- function readableFromUint8Array(buff) {
1906
- const readable = new Readable();
1907
- readable.push(buff);
1908
- readable.push(null);
1909
- return readable;
1910
- }
1911
- function isHttpTransportNetworkErrorRetryable(error) {
1912
- const RETRYABLE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
1913
- "ECONNRESET",
1914
- "ECONNREFUSED",
1915
- "EPIPE",
1916
- "ETIMEDOUT",
1917
- "EAI_AGAIN",
1918
- "ENOTFOUND",
1919
- "ENETUNREACH",
1920
- "EHOSTUNREACH"
1921
- ]);
1922
- if ("code" in error && typeof error.code === "string") {
1923
- return RETRYABLE_NETWORK_ERROR_CODES.has(error.code);
1924
- }
1925
- return false;
1926
- }
1927
-
1928
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/transport/http-exporter-transport.js
1929
- var HttpExporterTransport = class {
1930
- _utils = null;
1931
- _parameters;
1932
- constructor(parameters) {
1933
- this._parameters = parameters;
1934
- }
1935
- async send(data, timeoutMillis) {
1936
- const { agent, request } = await this._loadUtils();
1937
- const headers = await this._parameters.headers();
1938
- return sendWithHttp(request, this._parameters.url, headers, this._parameters.compression, this._parameters.userAgent, agent, data, timeoutMillis);
1939
- }
1940
- shutdown() {
1941
- }
1942
- async _loadUtils() {
1943
- let utils = this._utils;
1944
- if (utils === null) {
1945
- const protocol = new URL(this._parameters.url).protocol;
1946
- const [agent, request] = await Promise.all([
1947
- this._parameters.agentFactory(protocol),
1948
- requestFunctionFactory(protocol)
1949
- ]);
1950
- utils = this._utils = { agent, request };
1951
- }
1952
- return utils;
1953
- }
1954
- };
1955
- async function requestFunctionFactory(protocol) {
1956
- const module = protocol === "http:" ? import("http") : import("https");
1957
- const { request } = await module;
1958
- return request;
1959
- }
1960
- function createHttpExporterTransport(parameters) {
1961
- return new HttpExporterTransport(parameters);
1962
- }
1963
-
1964
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/retrying-transport.js
1965
- var MAX_ATTEMPTS = 5;
1966
- var INITIAL_BACKOFF = 1e3;
1967
- var MAX_BACKOFF = 5e3;
1968
- var BACKOFF_MULTIPLIER = 1.5;
1969
- var JITTER = 0.2;
1970
- function getJitter() {
1971
- return Math.random() * (2 * JITTER) - JITTER;
1972
- }
1973
- var RetryingTransport = class {
1974
- _transport;
1975
- constructor(transport) {
1976
- this._transport = transport;
1977
- }
1978
- retry(data, timeoutMillis, inMillis) {
1979
- return new Promise((resolve2, reject) => {
1980
- setTimeout(() => {
1981
- this._transport.send(data, timeoutMillis).then(resolve2, reject);
1982
- }, inMillis);
1983
- });
1984
- }
1985
- async send(data, timeoutMillis) {
1986
- let attempts = MAX_ATTEMPTS;
1987
- let nextBackoff = INITIAL_BACKOFF;
1988
- const deadline = Date.now() + timeoutMillis;
1989
- let result = await this._transport.send(data, timeoutMillis);
1990
- while (result.status === "retryable" && attempts > 0) {
1991
- attempts--;
1992
- const backoff = Math.max(Math.min(nextBackoff * (1 + getJitter()), MAX_BACKOFF), 0);
1993
- nextBackoff = nextBackoff * BACKOFF_MULTIPLIER;
1994
- const retryInMillis = result.retryInMillis ?? backoff;
1995
- const remainingTimeoutMillis = deadline - Date.now();
1996
- if (retryInMillis > remainingTimeoutMillis) {
1997
- diag.info(`Export retry time ${Math.round(retryInMillis)}ms exceeds remaining timeout ${Math.round(remainingTimeoutMillis)}ms, not retrying further.`);
1998
- return result;
1999
- }
2000
- diag.verbose(`Scheduling export retry in ${Math.round(retryInMillis)}ms`);
2001
- result = await this.retry(data, remainingTimeoutMillis, retryInMillis);
2002
- }
2003
- if (result.status === "success") {
2004
- diag.verbose(`Export succeeded after ${MAX_ATTEMPTS - attempts} retry attempts.`);
2005
- } else if (result.status === "retryable") {
2006
- diag.info(`Export failed after maximum retry attempts (${MAX_ATTEMPTS}).`);
2007
- } else {
2008
- diag.info(`Export failed with non-retryable error: ${result.error}`);
2009
- }
2010
- return result;
2011
- }
2012
- shutdown() {
2013
- return this._transport.shutdown();
2014
- }
2015
- };
2016
- function createRetryingTransport(options) {
2017
- return new RetryingTransport(options.transport);
2018
- }
2019
-
2020
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/otlp-http-export-delegate.js
2021
- function createOtlpHttpExportDelegate(options, serializer) {
2022
- return createOtlpExportDelegate({
2023
- transport: createRetryingTransport({
2024
- transport: createHttpExporterTransport(options)
2025
- }),
2026
- serializer,
2027
- promiseHandler: createBoundedQueueExportPromiseHandler(options)
2028
- }, { timeout: options.timeoutMillis });
2029
- }
2030
-
2031
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/shared-env-configuration.js
2032
- function parseAndValidateTimeoutFromEnv(timeoutEnvVar) {
2033
- const envTimeout = getNumberFromEnv(timeoutEnvVar);
2034
- if (envTimeout != null) {
2035
- if (Number.isFinite(envTimeout) && envTimeout > 0) {
2036
- return envTimeout;
2037
- }
2038
- diag.warn(`Configuration: ${timeoutEnvVar} is invalid, expected number greater than 0 (actual: ${envTimeout})`);
2039
- }
2040
- return void 0;
2041
- }
2042
- function getTimeoutFromEnv(signalIdentifier) {
2043
- const specificTimeout = parseAndValidateTimeoutFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_TIMEOUT`);
2044
- const nonSpecificTimeout = parseAndValidateTimeoutFromEnv("OTEL_EXPORTER_OTLP_TIMEOUT");
2045
- return specificTimeout ?? nonSpecificTimeout;
2046
- }
2047
- function parseAndValidateCompressionFromEnv(compressionEnvVar) {
2048
- const compression = getStringFromEnv(compressionEnvVar)?.trim();
2049
- if (compression == null || compression === "none" || compression === "gzip") {
2050
- return compression;
2051
- }
2052
- diag.warn(`Configuration: ${compressionEnvVar} is invalid, expected 'none' or 'gzip' (actual: '${compression}')`);
2053
- return void 0;
2054
- }
2055
- function getCompressionFromEnv(signalIdentifier) {
2056
- const specificCompression = parseAndValidateCompressionFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_COMPRESSION`);
2057
- const nonSpecificCompression = parseAndValidateCompressionFromEnv("OTEL_EXPORTER_OTLP_COMPRESSION");
2058
- return specificCompression ?? nonSpecificCompression;
2059
- }
2060
- function getSharedConfigurationFromEnvironment(signalIdentifier) {
2061
- return {
2062
- timeoutMillis: getTimeoutFromEnv(signalIdentifier),
2063
- compression: getCompressionFromEnv(signalIdentifier)
2064
- };
2065
- }
2066
-
2067
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/otlp-node-http-env-configuration.js
2068
- import * as fs from "fs";
2069
- import * as path from "path";
2070
- function getStaticHeadersFromEnv(signalIdentifier) {
2071
- const signalSpecificRawHeaders = getStringFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_HEADERS`);
2072
- const nonSignalSpecificRawHeaders = getStringFromEnv("OTEL_EXPORTER_OTLP_HEADERS");
2073
- const signalSpecificHeaders = parseKeyPairsIntoRecord(signalSpecificRawHeaders);
2074
- const nonSignalSpecificHeaders = parseKeyPairsIntoRecord(nonSignalSpecificRawHeaders);
2075
- if (Object.keys(signalSpecificHeaders).length === 0 && Object.keys(nonSignalSpecificHeaders).length === 0) {
2076
- return void 0;
2077
- }
2078
- return Object.assign({}, parseKeyPairsIntoRecord(nonSignalSpecificRawHeaders), parseKeyPairsIntoRecord(signalSpecificRawHeaders));
2079
- }
2080
- function appendRootPathToUrlIfNeeded(url) {
2081
- try {
2082
- const parsedUrl = new URL(url);
2083
- return parsedUrl.toString();
2084
- } catch {
2085
- diag.warn(`Configuration: Could not parse environment-provided export URL: '${url}', falling back to undefined`);
2086
- return void 0;
2087
- }
2088
- }
2089
- function appendResourcePathToUrl(url, path2) {
2090
- try {
2091
- new URL(url);
2092
- } catch {
2093
- diag.warn(`Configuration: Could not parse environment-provided export URL: '${url}', falling back to undefined`);
2094
- return void 0;
2095
- }
2096
- if (!url.endsWith("/")) {
2097
- url = url + "/";
2098
- }
2099
- url += path2;
2100
- try {
2101
- new URL(url);
2102
- } catch {
2103
- diag.warn(`Configuration: Provided URL appended with '${path2}' is not a valid URL, using 'undefined' instead of '${url}'`);
2104
- return void 0;
2105
- }
2106
- return url;
2107
- }
2108
- function getNonSpecificUrlFromEnv(signalResourcePath) {
2109
- const envUrl = getStringFromEnv("OTEL_EXPORTER_OTLP_ENDPOINT");
2110
- if (envUrl === void 0) {
2111
- return void 0;
2112
- }
2113
- return appendResourcePathToUrl(envUrl, signalResourcePath);
2114
- }
2115
- function getSpecificUrlFromEnv(signalIdentifier) {
2116
- const envUrl = getStringFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_ENDPOINT`);
2117
- if (envUrl === void 0) {
2118
- return void 0;
2119
- }
2120
- return appendRootPathToUrlIfNeeded(envUrl);
2121
- }
2122
- function readFileFromEnv(signalSpecificEnvVar, nonSignalSpecificEnvVar, warningMessage) {
2123
- const signalSpecificPath = getStringFromEnv(signalSpecificEnvVar);
2124
- const nonSignalSpecificPath = getStringFromEnv(nonSignalSpecificEnvVar);
2125
- const filePath = signalSpecificPath ?? nonSignalSpecificPath;
2126
- if (filePath != null) {
2127
- try {
2128
- return fs.readFileSync(path.resolve(process.cwd(), filePath));
2129
- } catch {
2130
- diag.warn(warningMessage);
2131
- return void 0;
2132
- }
2133
- } else {
2134
- return void 0;
2135
- }
2136
- }
2137
- function getClientCertificateFromEnv(signalIdentifier) {
2138
- return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CLIENT_CERTIFICATE`, "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE", "Failed to read client certificate chain file");
2139
- }
2140
- function getClientKeyFromEnv(signalIdentifier) {
2141
- return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CLIENT_KEY`, "OTEL_EXPORTER_OTLP_CLIENT_KEY", "Failed to read client certificate private key file");
2142
- }
2143
- function getRootCertificateFromEnv(signalIdentifier) {
2144
- return readFileFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_CERTIFICATE`, "OTEL_EXPORTER_OTLP_CERTIFICATE", "Failed to read root certificate file");
2145
- }
2146
- function getNodeHttpConfigurationFromEnvironment(signalIdentifier, signalResourcePath) {
2147
- return {
2148
- ...getSharedConfigurationFromEnvironment(signalIdentifier),
2149
- url: getSpecificUrlFromEnv(signalIdentifier) ?? getNonSpecificUrlFromEnv(signalResourcePath),
2150
- headers: wrapStaticHeadersInFunction(getStaticHeadersFromEnv(signalIdentifier)),
2151
- agentFactory: httpAgentFactoryFromOptions({
2152
- keepAlive: true,
2153
- ca: getRootCertificateFromEnv(signalIdentifier),
2154
- cert: getClientCertificateFromEnv(signalIdentifier),
2155
- key: getClientKeyFromEnv(signalIdentifier)
2156
- })
2157
- };
2158
- }
2159
-
2160
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/convert-legacy-http-options.js
2161
- function convertLegacyHeaders(config) {
2162
- if (typeof config.headers === "function") {
2163
- return config.headers;
2164
- }
2165
- return wrapStaticHeadersInFunction(config.headers);
2166
- }
2167
-
2168
- // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/convert-legacy-node-http-options.js
2169
- function convertLegacyAgentOptions(config) {
2170
- if (typeof config.httpAgentOptions === "function") {
2171
- return config.httpAgentOptions;
2172
- }
2173
- let legacy = config.httpAgentOptions;
2174
- if (config.keepAlive != null) {
2175
- legacy = { keepAlive: config.keepAlive, ...legacy };
2176
- }
2177
- if (legacy != null) {
2178
- return httpAgentFactoryFromOptions(legacy);
2179
- } else {
2180
- return void 0;
2181
- }
2182
- }
2183
- function convertLegacyHttpOptions(config, signalIdentifier, signalResourcePath, requiredHeaders) {
2184
- if (config.metadata) {
2185
- diag.warn("Metadata cannot be set when using http");
2186
- }
2187
- return mergeOtlpNodeHttpConfigurationWithDefaults({
2188
- url: config.url,
2189
- headers: convertLegacyHeaders(config),
2190
- concurrencyLimit: config.concurrencyLimit,
2191
- timeoutMillis: config.timeoutMillis,
2192
- compression: config.compression,
2193
- agentFactory: convertLegacyAgentOptions(config),
2194
- userAgent: config.userAgent
2195
- }, getNodeHttpConfigurationFromEnvironment(signalIdentifier, signalResourcePath), getNodeHttpConfigurationDefaults(requiredHeaders, signalResourcePath));
2196
- }
2197
-
2198
- // ../../node_modules/@opentelemetry/exporter-trace-otlp-http/build/esm/platform/node/OTLPTraceExporter.js
2199
- var OTLPTraceExporter = class extends OTLPExporterBase {
2200
- constructor(config = {}) {
2201
- super(createOtlpHttpExportDelegate(convertLegacyHttpOptions(config, "TRACES", "v1/traces", {
2202
- "Content-Type": "application/json"
2203
- }), JsonTraceSerializer));
2204
- }
2205
- };
2206
-
2207
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/enums.js
2208
- var ExceptionEventName = "exception";
2209
-
2210
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/Span.js
2211
- var SpanImpl = class {
2212
- // Below properties are included to implement ReadableSpan for export
2213
- // purposes but are not intended to be written-to directly.
2214
- _spanContext;
2215
- kind;
2216
- parentSpanContext;
2217
- attributes = {};
2218
- links = [];
2219
- events = [];
2220
- startTime;
2221
- resource;
2222
- instrumentationScope;
2223
- _droppedAttributesCount = 0;
2224
- _droppedEventsCount = 0;
2225
- _droppedLinksCount = 0;
2226
- _attributesCount = 0;
2227
- name;
2228
- status = {
2229
- code: SpanStatusCode.UNSET
2230
- };
2231
- endTime = [0, 0];
2232
- _ended = false;
2233
- _duration = [-1, -1];
2234
- _spanProcessor;
2235
- _spanLimits;
2236
- _attributeValueLengthLimit;
2237
- _recordEndMetrics;
2238
- _performanceStartTime;
2239
- _performanceOffset;
2240
- _startTimeProvided;
2241
- /**
2242
- * Constructs a new SpanImpl instance.
2243
- */
2244
- constructor(opts) {
2245
- const now = Date.now();
2246
- this._spanContext = opts.spanContext;
2247
- this._performanceStartTime = otperformance.now();
2248
- this._performanceOffset = now - (this._performanceStartTime + otperformance.timeOrigin);
2249
- this._startTimeProvided = opts.startTime != null;
2250
- this._spanLimits = opts.spanLimits;
2251
- this._attributeValueLengthLimit = this._spanLimits.attributeValueLengthLimit ?? 0;
2252
- this._spanProcessor = opts.spanProcessor;
2253
- this.name = opts.name;
2254
- this.parentSpanContext = opts.parentSpanContext;
2255
- this.kind = opts.kind;
2256
- if (opts.links) {
2257
- for (const link of opts.links) {
2258
- this.addLink(link);
2259
- }
2260
- }
2261
- this.startTime = this._getTime(opts.startTime ?? now);
2262
- this.resource = opts.resource;
2263
- this.instrumentationScope = opts.scope;
2264
- this._recordEndMetrics = opts.recordEndMetrics;
2265
- if (opts.attributes != null) {
2266
- this.setAttributes(opts.attributes);
2267
- }
2268
- this._spanProcessor.onStart(this, opts.context);
2269
- }
2270
- spanContext() {
2271
- return this._spanContext;
2272
- }
2273
- setAttribute(key, value) {
2274
- if (value == null || this._isSpanEnded())
2275
- return this;
2276
- if (key.length === 0) {
2277
- diag.warn(`Invalid attribute key: ${key}`);
2278
- return this;
2279
- }
2280
- if (!isAttributeValue(value)) {
2281
- diag.warn(`Invalid attribute value set for key: ${key}`);
2282
- return this;
2283
- }
2284
- const { attributeCountLimit } = this._spanLimits;
2285
- const isNewKey = !Object.prototype.hasOwnProperty.call(this.attributes, key);
2286
- if (attributeCountLimit !== void 0 && this._attributesCount >= attributeCountLimit && isNewKey) {
2287
- this._droppedAttributesCount++;
2288
- return this;
2289
- }
2290
- this.attributes[key] = this._truncateToSize(value);
2291
- if (isNewKey) {
2292
- this._attributesCount++;
2293
- }
2294
- return this;
2295
- }
2296
- setAttributes(attributes) {
2297
- for (const key in attributes) {
2298
- if (Object.prototype.hasOwnProperty.call(attributes, key)) {
2299
- this.setAttribute(key, attributes[key]);
2300
- }
2301
- }
2302
- return this;
2303
- }
2304
- /**
2305
- *
2306
- * @param name Span Name
2307
- * @param [attributesOrStartTime] Span attributes or start time
2308
- * if type is {@type TimeInput} and 3rd param is undefined
2309
- * @param [timeStamp] Specified time stamp for the event
2310
- */
2311
- addEvent(name, attributesOrStartTime, timeStamp) {
2312
- if (this._isSpanEnded())
2313
- return this;
2314
- const { eventCountLimit } = this._spanLimits;
2315
- if (eventCountLimit === 0) {
2316
- diag.warn("No events allowed.");
2317
- this._droppedEventsCount++;
2318
- return this;
2319
- }
2320
- if (eventCountLimit !== void 0 && this.events.length >= eventCountLimit) {
2321
- if (this._droppedEventsCount === 0) {
2322
- diag.debug("Dropping extra events.");
2323
- }
2324
- this.events.shift();
2325
- this._droppedEventsCount++;
2326
- }
2327
- if (isTimeInput(attributesOrStartTime)) {
2328
- if (!isTimeInput(timeStamp)) {
2329
- timeStamp = attributesOrStartTime;
2330
- }
2331
- attributesOrStartTime = void 0;
2332
- }
2333
- const sanitized = sanitizeAttributes(attributesOrStartTime);
2334
- const { attributePerEventCountLimit } = this._spanLimits;
2335
- const attributes = {};
2336
- let droppedAttributesCount = 0;
2337
- let eventAttributesCount = 0;
2338
- for (const attr in sanitized) {
2339
- if (!Object.prototype.hasOwnProperty.call(sanitized, attr)) {
2340
- continue;
2341
- }
2342
- const attrVal = sanitized[attr];
2343
- if (attributePerEventCountLimit !== void 0 && eventAttributesCount >= attributePerEventCountLimit) {
2344
- droppedAttributesCount++;
2345
- continue;
2346
- }
2347
- attributes[attr] = this._truncateToSize(attrVal);
2348
- eventAttributesCount++;
2349
- }
2350
- this.events.push({
2351
- name,
2352
- attributes,
2353
- time: this._getTime(timeStamp),
2354
- droppedAttributesCount
2355
- });
2356
- return this;
2357
- }
2358
- addLink(link) {
2359
- if (this._isSpanEnded())
2360
- return this;
2361
- const { linkCountLimit } = this._spanLimits;
2362
- if (linkCountLimit === 0) {
2363
- this._droppedLinksCount++;
2364
- return this;
2365
- }
2366
- if (linkCountLimit !== void 0 && this.links.length >= linkCountLimit) {
2367
- if (this._droppedLinksCount === 0) {
2368
- diag.debug("Dropping extra links.");
2369
- }
2370
- this.links.shift();
2371
- this._droppedLinksCount++;
2372
- }
2373
- const { attributePerLinkCountLimit } = this._spanLimits;
2374
- const sanitized = sanitizeAttributes(link.attributes);
2375
- const attributes = {};
2376
- let droppedAttributesCount = 0;
2377
- let linkAttributesCount = 0;
2378
- for (const attr in sanitized) {
2379
- if (!Object.prototype.hasOwnProperty.call(sanitized, attr)) {
2380
- continue;
2381
- }
2382
- const attrVal = sanitized[attr];
2383
- if (attributePerLinkCountLimit !== void 0 && linkAttributesCount >= attributePerLinkCountLimit) {
2384
- droppedAttributesCount++;
2385
- continue;
2386
- }
2387
- attributes[attr] = this._truncateToSize(attrVal);
2388
- linkAttributesCount++;
2389
- }
2390
- const processedLink = { context: link.context };
2391
- if (linkAttributesCount > 0) {
2392
- processedLink.attributes = attributes;
2393
- }
2394
- if (droppedAttributesCount > 0) {
2395
- processedLink.droppedAttributesCount = droppedAttributesCount;
2396
- }
2397
- this.links.push(processedLink);
2398
- return this;
2399
- }
2400
- addLinks(links) {
2401
- for (const link of links) {
2402
- this.addLink(link);
2403
- }
2404
- return this;
2405
- }
2406
- setStatus(status) {
2407
- if (this._isSpanEnded())
2408
- return this;
2409
- if (status.code === SpanStatusCode.UNSET)
2410
- return this;
2411
- if (this.status.code === SpanStatusCode.OK)
2412
- return this;
2413
- const newStatus = { code: status.code };
2414
- if (status.code === SpanStatusCode.ERROR) {
2415
- if (typeof status.message === "string") {
2416
- newStatus.message = status.message;
2417
- } else if (status.message != null) {
2418
- diag.warn(`Dropping invalid status.message of type '${typeof status.message}', expected 'string'`);
2419
- }
2420
- }
2421
- this.status = newStatus;
2422
- return this;
2423
- }
2424
- updateName(name) {
2425
- if (this._isSpanEnded())
2426
- return this;
2427
- this.name = name;
2428
- return this;
2429
- }
2430
- end(endTime) {
2431
- if (this._isSpanEnded()) {
2432
- diag.error(`${this.name} ${this._spanContext.traceId}-${this._spanContext.spanId} - You can only call end() on a span once.`);
2433
- return;
2434
- }
2435
- this.endTime = this._getTime(endTime);
2436
- this._duration = hrTimeDuration(this.startTime, this.endTime);
2437
- if (this._duration[0] < 0) {
2438
- diag.warn("Inconsistent start and end time, startTime > endTime. Setting span duration to 0ms.", this.startTime, this.endTime);
2439
- this.endTime = this.startTime.slice();
2440
- this._duration = [0, 0];
2441
- }
2442
- if (this._droppedEventsCount > 0) {
2443
- diag.warn(`Dropped ${this._droppedEventsCount} events because eventCountLimit reached`);
2444
- }
2445
- if (this._droppedLinksCount > 0) {
2446
- diag.warn(`Dropped ${this._droppedLinksCount} links because linkCountLimit reached`);
2447
- }
2448
- if (this._spanProcessor.onEnding) {
2449
- this._spanProcessor.onEnding(this);
2450
- }
2451
- this._recordEndMetrics?.();
2452
- this._ended = true;
2453
- this._spanProcessor.onEnd(this);
2454
- }
2455
- _getTime(inp) {
2456
- if (typeof inp === "number" && inp <= otperformance.now()) {
2457
- return hrTime(inp + this._performanceOffset);
2458
- }
2459
- if (typeof inp === "number") {
2460
- return millisToHrTime(inp);
2461
- }
2462
- if (inp instanceof Date) {
2463
- return millisToHrTime(inp.getTime());
2464
- }
2465
- if (isTimeInputHrTime(inp)) {
2466
- return inp;
2467
- }
2468
- if (this._startTimeProvided) {
2469
- return millisToHrTime(Date.now());
2470
- }
2471
- const msDuration = otperformance.now() - this._performanceStartTime;
2472
- return addHrTimes(this.startTime, millisToHrTime(msDuration));
2473
- }
2474
- isRecording() {
2475
- return this._ended === false;
2476
- }
2477
- recordException(exception, time) {
2478
- const attributes = {};
2479
- if (typeof exception === "string") {
2480
- attributes[ATTR_EXCEPTION_MESSAGE] = exception;
2481
- } else if (exception) {
2482
- if (exception.code) {
2483
- attributes[ATTR_EXCEPTION_TYPE] = exception.code.toString();
2484
- } else if (exception.name) {
2485
- attributes[ATTR_EXCEPTION_TYPE] = exception.name;
2486
- }
2487
- if (exception.message) {
2488
- attributes[ATTR_EXCEPTION_MESSAGE] = exception.message;
2489
- }
2490
- if (exception.stack) {
2491
- attributes[ATTR_EXCEPTION_STACKTRACE] = exception.stack;
2492
- }
2493
- }
2494
- if (attributes[ATTR_EXCEPTION_TYPE] || attributes[ATTR_EXCEPTION_MESSAGE]) {
2495
- this.addEvent(ExceptionEventName, attributes, time);
2496
- } else {
2497
- diag.warn(`Failed to record an exception ${exception}`);
2498
- }
2499
- }
2500
- get duration() {
2501
- return this._duration;
2502
- }
2503
- get ended() {
2504
- return this._ended;
2505
- }
2506
- get droppedAttributesCount() {
2507
- return this._droppedAttributesCount;
2508
- }
2509
- get droppedEventsCount() {
2510
- return this._droppedEventsCount;
2511
- }
2512
- get droppedLinksCount() {
2513
- return this._droppedLinksCount;
2514
- }
2515
- _isSpanEnded() {
2516
- if (this._ended) {
2517
- const error = new Error(`Operation attempted on ended Span {traceId: ${this._spanContext.traceId}, spanId: ${this._spanContext.spanId}}`);
2518
- diag.warn(`Cannot execute the operation on ended Span {traceId: ${this._spanContext.traceId}, spanId: ${this._spanContext.spanId}}`, error);
2519
- }
2520
- return this._ended;
2521
- }
2522
- // Utility function to truncate given value within size
2523
- // for value type of string, will truncate to given limit
2524
- // for type of non-string, will return same value
2525
- _truncateToLimitUtil(value, limit) {
2526
- if (value.length <= limit) {
2527
- return value;
2528
- }
2529
- return value.substring(0, limit);
2530
- }
2531
- /**
2532
- * If the given attribute value is of type string and has more characters than given {@code attributeValueLengthLimit} then
2533
- * return string with truncated to {@code attributeValueLengthLimit} characters
2534
- *
2535
- * If the given attribute value is array of strings then
2536
- * return new array of strings with each element truncated to {@code attributeValueLengthLimit} characters
2537
- *
2538
- * Otherwise return same Attribute {@code value}
2539
- *
2540
- * @param value Attribute value
2541
- * @returns truncated attribute value if required, otherwise same value
2542
- */
2543
- _truncateToSize(value) {
2544
- const limit = this._attributeValueLengthLimit;
2545
- if (limit <= 0) {
2546
- diag.warn(`Attribute value limit must be positive, got ${limit}`);
2547
- return value;
2548
- }
2549
- if (typeof value === "string") {
2550
- return this._truncateToLimitUtil(value, limit);
2551
- }
2552
- if (Array.isArray(value)) {
2553
- return value.map((val) => typeof val === "string" ? this._truncateToLimitUtil(val, limit) : val);
2554
- }
2555
- return value;
2556
- }
2557
- };
2558
-
2559
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/Sampler.js
2560
- var SamplingDecision2;
2561
- (function(SamplingDecision3) {
2562
- SamplingDecision3[SamplingDecision3["NOT_RECORD"] = 0] = "NOT_RECORD";
2563
- SamplingDecision3[SamplingDecision3["RECORD"] = 1] = "RECORD";
2564
- SamplingDecision3[SamplingDecision3["RECORD_AND_SAMPLED"] = 2] = "RECORD_AND_SAMPLED";
2565
- })(SamplingDecision2 || (SamplingDecision2 = {}));
2566
-
2567
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/sampler/AlwaysOffSampler.js
2568
- var AlwaysOffSampler = class {
2569
- shouldSample() {
2570
- return {
2571
- decision: SamplingDecision2.NOT_RECORD
2572
- };
2573
- }
2574
- toString() {
2575
- return "AlwaysOffSampler";
2576
- }
2577
- };
2578
-
2579
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/sampler/AlwaysOnSampler.js
2580
- var AlwaysOnSampler = class {
2581
- shouldSample() {
2582
- return {
2583
- decision: SamplingDecision2.RECORD_AND_SAMPLED
2584
- };
2585
- }
2586
- toString() {
2587
- return "AlwaysOnSampler";
2588
- }
2589
- };
2590
-
2591
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/sampler/ParentBasedSampler.js
2592
- var ParentBasedSampler = class {
2593
- _root;
2594
- _remoteParentSampled;
2595
- _remoteParentNotSampled;
2596
- _localParentSampled;
2597
- _localParentNotSampled;
2598
- constructor(config) {
2599
- this._root = config.root;
2600
- if (!this._root) {
2601
- globalErrorHandler(new Error("ParentBasedSampler must have a root sampler configured"));
2602
- this._root = new AlwaysOnSampler();
2603
- }
2604
- this._remoteParentSampled = config.remoteParentSampled ?? new AlwaysOnSampler();
2605
- this._remoteParentNotSampled = config.remoteParentNotSampled ?? new AlwaysOffSampler();
2606
- this._localParentSampled = config.localParentSampled ?? new AlwaysOnSampler();
2607
- this._localParentNotSampled = config.localParentNotSampled ?? new AlwaysOffSampler();
2608
- }
2609
- shouldSample(context2, traceId, spanName, spanKind, attributes, links) {
2610
- const parentContext = trace.getSpanContext(context2);
2611
- if (!parentContext || !isSpanContextValid(parentContext)) {
2612
- return this._root.shouldSample(context2, traceId, spanName, spanKind, attributes, links);
2613
- }
2614
- if (parentContext.isRemote) {
2615
- if (parentContext.traceFlags & TraceFlags.SAMPLED) {
2616
- return this._remoteParentSampled.shouldSample(context2, traceId, spanName, spanKind, attributes, links);
2617
- }
2618
- return this._remoteParentNotSampled.shouldSample(context2, traceId, spanName, spanKind, attributes, links);
2619
- }
2620
- if (parentContext.traceFlags & TraceFlags.SAMPLED) {
2621
- return this._localParentSampled.shouldSample(context2, traceId, spanName, spanKind, attributes, links);
2622
- }
2623
- return this._localParentNotSampled.shouldSample(context2, traceId, spanName, spanKind, attributes, links);
2624
- }
2625
- toString() {
2626
- return `ParentBased{root=${this._root.toString()}, remoteParentSampled=${this._remoteParentSampled.toString()}, remoteParentNotSampled=${this._remoteParentNotSampled.toString()}, localParentSampled=${this._localParentSampled.toString()}, localParentNotSampled=${this._localParentNotSampled.toString()}}`;
2627
- }
2628
- };
2629
-
2630
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/sampler/TraceIdRatioBasedSampler.js
2631
- var TraceIdRatioBasedSampler = class {
2632
- _ratio;
2633
- _upperBound;
2634
- constructor(ratio = 0) {
2635
- this._ratio = this._normalize(ratio);
2636
- this._upperBound = Math.floor(this._ratio * 4294967295);
2637
- }
2638
- shouldSample(context2, traceId) {
2639
- return {
2640
- decision: isValidTraceId(traceId) && this._accumulate(traceId) < this._upperBound ? SamplingDecision2.RECORD_AND_SAMPLED : SamplingDecision2.NOT_RECORD
2641
- };
2642
- }
2643
- toString() {
2644
- return `TraceIdRatioBased{${this._ratio}}`;
2645
- }
2646
- _normalize(ratio) {
2647
- if (typeof ratio !== "number" || isNaN(ratio))
2648
- return 0;
2649
- return ratio >= 1 ? 1 : ratio <= 0 ? 0 : ratio;
2650
- }
2651
- _accumulate(traceId) {
2652
- let accumulation = 0;
2653
- for (let i = 0; i < traceId.length / 8; i++) {
2654
- const pos = i * 8;
2655
- const part = parseInt(traceId.slice(pos, pos + 8), 16);
2656
- accumulation = (accumulation ^ part) >>> 0;
2657
- }
2658
- return accumulation;
2659
- }
2660
- };
2661
-
2662
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/config.js
2663
- var TracesSamplerValues;
2664
- (function(TracesSamplerValues2) {
2665
- TracesSamplerValues2["AlwaysOff"] = "always_off";
2666
- TracesSamplerValues2["AlwaysOn"] = "always_on";
2667
- TracesSamplerValues2["ParentBasedAlwaysOff"] = "parentbased_always_off";
2668
- TracesSamplerValues2["ParentBasedAlwaysOn"] = "parentbased_always_on";
2669
- TracesSamplerValues2["ParentBasedTraceIdRatio"] = "parentbased_traceidratio";
2670
- TracesSamplerValues2["TraceIdRatio"] = "traceidratio";
2671
- })(TracesSamplerValues || (TracesSamplerValues = {}));
2672
- var DEFAULT_RATIO = 1;
2673
- function loadDefaultConfig() {
2674
- return {
2675
- sampler: buildSamplerFromEnv(),
2676
- forceFlushTimeoutMillis: 3e4,
2677
- generalLimits: {
2678
- attributeValueLengthLimit: getNumberFromEnv("OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT") ?? Infinity,
2679
- attributeCountLimit: getNumberFromEnv("OTEL_ATTRIBUTE_COUNT_LIMIT") ?? 128
2680
- },
2681
- spanLimits: {
2682
- attributeValueLengthLimit: getNumberFromEnv("OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT") ?? Infinity,
2683
- attributeCountLimit: getNumberFromEnv("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT") ?? 128,
2684
- linkCountLimit: getNumberFromEnv("OTEL_SPAN_LINK_COUNT_LIMIT") ?? 128,
2685
- eventCountLimit: getNumberFromEnv("OTEL_SPAN_EVENT_COUNT_LIMIT") ?? 128,
2686
- attributePerEventCountLimit: getNumberFromEnv("OTEL_SPAN_ATTRIBUTE_PER_EVENT_COUNT_LIMIT") ?? 128,
2687
- attributePerLinkCountLimit: getNumberFromEnv("OTEL_SPAN_ATTRIBUTE_PER_LINK_COUNT_LIMIT") ?? 128
2688
- }
2689
- };
2690
- }
2691
- function buildSamplerFromEnv() {
2692
- const sampler = getStringFromEnv("OTEL_TRACES_SAMPLER") ?? TracesSamplerValues.ParentBasedAlwaysOn;
2693
- switch (sampler) {
2694
- case TracesSamplerValues.AlwaysOn:
2695
- return new AlwaysOnSampler();
2696
- case TracesSamplerValues.AlwaysOff:
2697
- return new AlwaysOffSampler();
2698
- case TracesSamplerValues.ParentBasedAlwaysOn:
2699
- return new ParentBasedSampler({
2700
- root: new AlwaysOnSampler()
2701
- });
2702
- case TracesSamplerValues.ParentBasedAlwaysOff:
2703
- return new ParentBasedSampler({
2704
- root: new AlwaysOffSampler()
2705
- });
2706
- case TracesSamplerValues.TraceIdRatio:
2707
- return new TraceIdRatioBasedSampler(getSamplerProbabilityFromEnv());
2708
- case TracesSamplerValues.ParentBasedTraceIdRatio:
2709
- return new ParentBasedSampler({
2710
- root: new TraceIdRatioBasedSampler(getSamplerProbabilityFromEnv())
2711
- });
2712
- default:
2713
- diag.error(`OTEL_TRACES_SAMPLER value "${sampler}" invalid, defaulting to "${TracesSamplerValues.ParentBasedAlwaysOn}".`);
2714
- return new ParentBasedSampler({
2715
- root: new AlwaysOnSampler()
2716
- });
2717
- }
2718
- }
2719
- function getSamplerProbabilityFromEnv() {
2720
- const probability = getNumberFromEnv("OTEL_TRACES_SAMPLER_ARG");
2721
- if (probability == null) {
2722
- diag.error(`OTEL_TRACES_SAMPLER_ARG is blank, defaulting to ${DEFAULT_RATIO}.`);
2723
- return DEFAULT_RATIO;
2724
- }
2725
- if (probability < 0 || probability > 1) {
2726
- diag.error(`OTEL_TRACES_SAMPLER_ARG=${probability} was given, but it is out of range ([0..1]), defaulting to ${DEFAULT_RATIO}.`);
2727
- return DEFAULT_RATIO;
2728
- }
2729
- return probability;
2730
- }
2731
-
2732
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/utility.js
2733
- var DEFAULT_ATTRIBUTE_COUNT_LIMIT = 128;
2734
- var DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT = Infinity;
2735
- function mergeConfig(userConfig) {
2736
- const perInstanceDefaults = {
2737
- sampler: buildSamplerFromEnv()
2738
- };
2739
- const DEFAULT_CONFIG = loadDefaultConfig();
2740
- const target = Object.assign({}, DEFAULT_CONFIG, perInstanceDefaults, userConfig);
2741
- target.generalLimits = Object.assign({}, DEFAULT_CONFIG.generalLimits, userConfig.generalLimits || {});
2742
- target.spanLimits = Object.assign({}, DEFAULT_CONFIG.spanLimits, userConfig.spanLimits || {});
2743
- return target;
2744
- }
2745
- function reconfigureLimits(userConfig) {
2746
- const spanLimits = Object.assign({}, userConfig.spanLimits);
2747
- spanLimits.attributeCountLimit = userConfig.spanLimits?.attributeCountLimit ?? userConfig.generalLimits?.attributeCountLimit ?? getNumberFromEnv("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT") ?? getNumberFromEnv("OTEL_ATTRIBUTE_COUNT_LIMIT") ?? DEFAULT_ATTRIBUTE_COUNT_LIMIT;
2748
- spanLimits.attributeValueLengthLimit = userConfig.spanLimits?.attributeValueLengthLimit ?? userConfig.generalLimits?.attributeValueLengthLimit ?? getNumberFromEnv("OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT") ?? getNumberFromEnv("OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT") ?? DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT;
2749
- return Object.assign({}, userConfig, { spanLimits });
2750
- }
2751
-
2752
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/export/BatchSpanProcessorBase.js
2753
- var BatchSpanProcessorBase = class {
2754
- _maxExportBatchSize;
2755
- _maxQueueSize;
2756
- _scheduledDelayMillis;
2757
- _exportTimeoutMillis;
2758
- _exporter;
2759
- _isExporting = false;
2760
- _finishedSpans = [];
2761
- _timer;
2762
- _shutdownOnce;
2763
- _droppedSpansCount = 0;
2764
- constructor(exporter, config) {
2765
- this._exporter = exporter;
2766
- this._maxExportBatchSize = typeof config?.maxExportBatchSize === "number" ? config.maxExportBatchSize : getNumberFromEnv("OTEL_BSP_MAX_EXPORT_BATCH_SIZE") ?? 512;
2767
- this._maxQueueSize = typeof config?.maxQueueSize === "number" ? config.maxQueueSize : getNumberFromEnv("OTEL_BSP_MAX_QUEUE_SIZE") ?? 2048;
2768
- this._scheduledDelayMillis = typeof config?.scheduledDelayMillis === "number" ? config.scheduledDelayMillis : getNumberFromEnv("OTEL_BSP_SCHEDULE_DELAY") ?? 5e3;
2769
- this._exportTimeoutMillis = typeof config?.exportTimeoutMillis === "number" ? config.exportTimeoutMillis : getNumberFromEnv("OTEL_BSP_EXPORT_TIMEOUT") ?? 3e4;
2770
- this._shutdownOnce = new BindOnceFuture(this._shutdown, this);
2771
- if (this._maxExportBatchSize > this._maxQueueSize) {
2772
- diag.warn("BatchSpanProcessor: maxExportBatchSize must be smaller or equal to maxQueueSize, setting maxExportBatchSize to match maxQueueSize");
2773
- this._maxExportBatchSize = this._maxQueueSize;
2774
- }
2775
- }
2776
- forceFlush() {
2777
- if (this._shutdownOnce.isCalled) {
2778
- return this._shutdownOnce.promise;
2779
- }
2780
- return this._flushAll();
2781
- }
2782
- // does nothing.
2783
- onStart(_span, _parentContext) {
2784
- }
2785
- onEnd(span) {
2786
- if (this._shutdownOnce.isCalled) {
2787
- return;
2788
- }
2789
- if ((span.spanContext().traceFlags & TraceFlags.SAMPLED) === 0) {
2790
- return;
2791
- }
2792
- this._addToBuffer(span);
2793
- }
2794
- shutdown() {
2795
- return this._shutdownOnce.call();
2796
- }
2797
- _shutdown() {
2798
- return Promise.resolve().then(() => {
2799
- return this.onShutdown();
2800
- }).then(() => {
2801
- return this._flushAll();
2802
- }).then(() => {
2803
- return this._exporter.shutdown();
2804
- });
2805
- }
2806
- /** Add a span in the buffer. */
2807
- _addToBuffer(span) {
2808
- if (this._finishedSpans.length >= this._maxQueueSize) {
2809
- if (this._droppedSpansCount === 0) {
2810
- diag.debug("maxQueueSize reached, dropping spans");
2811
- }
2812
- this._droppedSpansCount++;
2813
- return;
2814
- }
2815
- if (this._droppedSpansCount > 0) {
2816
- diag.warn(`Dropped ${this._droppedSpansCount} spans because maxQueueSize reached`);
2817
- this._droppedSpansCount = 0;
2818
- }
2819
- this._finishedSpans.push(span);
2820
- this._maybeStartTimer();
2821
- }
2822
- /**
2823
- * Send all spans to the exporter respecting the batch size limit
2824
- * This function is used only on forceFlush or shutdown,
2825
- * for all other cases _flush should be used
2826
- * */
2827
- _flushAll() {
2828
- return new Promise((resolve2, reject) => {
2829
- const promises = [];
2830
- const count = Math.ceil(this._finishedSpans.length / this._maxExportBatchSize);
2831
- for (let i = 0, j = count; i < j; i++) {
2832
- promises.push(this._flushOneBatch());
2833
- }
2834
- Promise.all(promises).then(() => {
2835
- resolve2();
2836
- }).catch(reject);
2837
- });
2838
- }
2839
- _flushOneBatch() {
2840
- this._clearTimer();
2841
- if (this._finishedSpans.length === 0) {
2842
- return Promise.resolve();
2843
- }
2844
- return new Promise((resolve2, reject) => {
2845
- const timer = setTimeout(() => {
2846
- reject(new Error("Timeout"));
2847
- }, this._exportTimeoutMillis);
2848
- context.with(suppressTracing(context.active()), () => {
2849
- let spans;
2850
- if (this._finishedSpans.length <= this._maxExportBatchSize) {
2851
- spans = this._finishedSpans;
2852
- this._finishedSpans = [];
2853
- } else {
2854
- spans = this._finishedSpans.splice(0, this._maxExportBatchSize);
2855
- }
2856
- const doExport = () => this._exporter.export(spans, (result) => {
2857
- clearTimeout(timer);
2858
- if (result.code === ExportResultCode.SUCCESS) {
2859
- resolve2();
2860
- } else {
2861
- reject(result.error ?? new Error("BatchSpanProcessor: span export failed"));
2862
- }
2863
- });
2864
- let pendingResources = null;
2865
- for (let i = 0, len = spans.length; i < len; i++) {
2866
- const span = spans[i];
2867
- if (span.resource.asyncAttributesPending && span.resource.waitForAsyncAttributes) {
2868
- pendingResources ??= [];
2869
- pendingResources.push(span.resource.waitForAsyncAttributes());
2870
- }
2871
- }
2872
- if (pendingResources === null) {
2873
- doExport();
2874
- } else {
2875
- Promise.all(pendingResources).then(doExport, (err) => {
2876
- globalErrorHandler(err);
2877
- reject(err);
2878
- });
2879
- }
2880
- });
2881
- });
2882
- }
2883
- _maybeStartTimer() {
2884
- if (this._isExporting)
2885
- return;
2886
- const flush = () => {
2887
- this._isExporting = true;
2888
- this._flushOneBatch().finally(() => {
2889
- this._isExporting = false;
2890
- if (this._finishedSpans.length > 0) {
2891
- this._clearTimer();
2892
- this._maybeStartTimer();
2893
- }
2894
- }).catch((e) => {
2895
- this._isExporting = false;
2896
- globalErrorHandler(e);
2897
- });
2898
- };
2899
- if (this._finishedSpans.length >= this._maxExportBatchSize) {
2900
- return flush();
2901
- }
2902
- if (this._timer !== void 0)
2903
- return;
2904
- this._timer = setTimeout(() => flush(), this._scheduledDelayMillis);
2905
- if (typeof this._timer !== "number") {
2906
- this._timer.unref();
2907
- }
2908
- }
2909
- _clearTimer() {
2910
- if (this._timer !== void 0) {
2911
- clearTimeout(this._timer);
2912
- this._timer = void 0;
2913
- }
2914
- }
2915
- };
2916
-
2917
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/platform/node/export/BatchSpanProcessor.js
2918
- var BatchSpanProcessor = class extends BatchSpanProcessorBase {
2919
- onShutdown() {
2920
- }
2921
- };
2922
-
2923
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/platform/node/RandomIdGenerator.js
2924
- var SPAN_ID_BYTES = 8;
2925
- var TRACE_ID_BYTES = 16;
2926
- var RandomIdGenerator = class {
2927
- /**
2928
- * Returns a random 16-byte trace ID formatted/encoded as a 32 lowercase hex
2929
- * characters corresponding to 128 bits.
2930
- */
2931
- generateTraceId = getIdGenerator(TRACE_ID_BYTES);
2932
- /**
2933
- * Returns a random 8-byte span ID formatted/encoded as a 16 lowercase hex
2934
- * characters corresponding to 64 bits.
2935
- */
2936
- generateSpanId = getIdGenerator(SPAN_ID_BYTES);
2937
- };
2938
- var SHARED_BUFFER = Buffer.allocUnsafe(TRACE_ID_BYTES);
2939
- function getIdGenerator(bytes) {
2940
- return function generateId() {
2941
- for (let i = 0; i < bytes / 4; i++) {
2942
- SHARED_BUFFER.writeUInt32BE(Math.random() * 2 ** 32 >>> 0, i * 4);
2943
- }
2944
- for (let i = 0; i < bytes; i++) {
2945
- if (SHARED_BUFFER[i] > 0) {
2946
- break;
2947
- } else if (i === bytes - 1) {
2948
- SHARED_BUFFER[bytes - 1] = 1;
2949
- }
2950
- }
2951
- return SHARED_BUFFER.toString("hex", 0, bytes);
2952
- };
2953
- }
2954
-
2955
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/semconv.js
2956
- var ATTR_OTEL_SPAN_PARENT_ORIGIN = "otel.span.parent.origin";
2957
- var ATTR_OTEL_SPAN_SAMPLING_RESULT = "otel.span.sampling_result";
2958
- var METRIC_OTEL_SDK_SPAN_LIVE = "otel.sdk.span.live";
2959
- var METRIC_OTEL_SDK_SPAN_STARTED = "otel.sdk.span.started";
2960
-
2961
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/TracerMetrics.js
2962
- var TracerMetrics = class {
2963
- startedSpans;
2964
- liveSpans;
2965
- constructor(meter) {
2966
- this.startedSpans = meter.createCounter(METRIC_OTEL_SDK_SPAN_STARTED, {
2967
- unit: "{span}",
2968
- description: "The number of created spans."
2969
- });
2970
- this.liveSpans = meter.createUpDownCounter(METRIC_OTEL_SDK_SPAN_LIVE, {
2971
- unit: "{span}",
2972
- description: "The number of currently live spans."
2973
- });
2974
- }
2975
- startSpan(parentSpanCtx, samplingDecision) {
2976
- const samplingDecisionStr = samplingDecisionToString(samplingDecision);
2977
- this.startedSpans.add(1, {
2978
- [ATTR_OTEL_SPAN_PARENT_ORIGIN]: parentOrigin(parentSpanCtx),
2979
- [ATTR_OTEL_SPAN_SAMPLING_RESULT]: samplingDecisionStr
2980
- });
2981
- if (samplingDecision === SamplingDecision2.NOT_RECORD) {
2982
- return () => {
2983
- };
2984
- }
2985
- const liveSpanAttributes = {
2986
- [ATTR_OTEL_SPAN_SAMPLING_RESULT]: samplingDecisionStr
2987
- };
2988
- this.liveSpans.add(1, liveSpanAttributes);
2989
- return () => {
2990
- this.liveSpans.add(-1, liveSpanAttributes);
2991
- };
2992
- }
2993
- };
2994
- function parentOrigin(parentSpanContext) {
2995
- if (!parentSpanContext) {
2996
- return "none";
2997
- }
2998
- if (parentSpanContext.isRemote) {
2999
- return "remote";
3000
- }
3001
- return "local";
3002
- }
3003
- function samplingDecisionToString(decision) {
3004
- switch (decision) {
3005
- case SamplingDecision2.RECORD_AND_SAMPLED:
3006
- return "RECORD_AND_SAMPLE";
3007
- case SamplingDecision2.RECORD:
3008
- return "RECORD_ONLY";
3009
- case SamplingDecision2.NOT_RECORD:
3010
- return "DROP";
3011
- }
3012
- }
3013
-
3014
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/version.js
3015
- var VERSION3 = "2.6.1";
3016
-
3017
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/Tracer.js
3018
- var Tracer = class {
3019
- _sampler;
3020
- _generalLimits;
3021
- _spanLimits;
3022
- _idGenerator;
3023
- instrumentationScope;
3024
- _resource;
3025
- _spanProcessor;
3026
- _tracerMetrics;
3027
- /**
3028
- * Constructs a new Tracer instance.
3029
- */
3030
- constructor(instrumentationScope, config, resource, spanProcessor) {
3031
- const localConfig = mergeConfig(config);
3032
- this._sampler = localConfig.sampler;
3033
- this._generalLimits = localConfig.generalLimits;
3034
- this._spanLimits = localConfig.spanLimits;
3035
- this._idGenerator = config.idGenerator || new RandomIdGenerator();
3036
- this._resource = resource;
3037
- this._spanProcessor = spanProcessor;
3038
- this.instrumentationScope = instrumentationScope;
3039
- const meter = localConfig.meterProvider ? localConfig.meterProvider.getMeter("@opentelemetry/sdk-trace", VERSION3) : createNoopMeter();
3040
- this._tracerMetrics = new TracerMetrics(meter);
3041
- }
3042
- /**
3043
- * Starts a new Span or returns the default NoopSpan based on the sampling
3044
- * decision.
3045
- */
3046
- startSpan(name, options = {}, context2 = context.active()) {
3047
- if (options.root) {
3048
- context2 = trace.deleteSpan(context2);
3049
- }
3050
- const parentSpan = trace.getSpan(context2);
3051
- if (isTracingSuppressed(context2)) {
3052
- diag.debug("Instrumentation suppressed, returning Noop Span");
3053
- const nonRecordingSpan = trace.wrapSpanContext(INVALID_SPAN_CONTEXT);
3054
- return nonRecordingSpan;
3055
- }
3056
- const parentSpanContext = parentSpan?.spanContext();
3057
- const spanId = this._idGenerator.generateSpanId();
3058
- let validParentSpanContext;
3059
- let traceId;
3060
- let traceState;
3061
- if (!parentSpanContext || !trace.isSpanContextValid(parentSpanContext)) {
3062
- traceId = this._idGenerator.generateTraceId();
3063
- } else {
3064
- traceId = parentSpanContext.traceId;
3065
- traceState = parentSpanContext.traceState;
3066
- validParentSpanContext = parentSpanContext;
3067
- }
3068
- const spanKind = options.kind ?? SpanKind.INTERNAL;
3069
- const links = (options.links ?? []).map((link) => {
3070
- return {
3071
- context: link.context,
3072
- attributes: sanitizeAttributes(link.attributes)
3073
- };
3074
- });
3075
- const attributes = sanitizeAttributes(options.attributes);
3076
- const samplingResult = this._sampler.shouldSample(context2, traceId, name, spanKind, attributes, links);
3077
- const recordEndMetrics = this._tracerMetrics.startSpan(parentSpanContext, samplingResult.decision);
3078
- traceState = samplingResult.traceState ?? traceState;
3079
- const traceFlags = samplingResult.decision === SamplingDecision.RECORD_AND_SAMPLED ? TraceFlags.SAMPLED : TraceFlags.NONE;
3080
- const spanContext = { traceId, spanId, traceFlags, traceState };
3081
- if (samplingResult.decision === SamplingDecision.NOT_RECORD) {
3082
- diag.debug("Recording is off, propagating context in a non-recording span");
3083
- const nonRecordingSpan = trace.wrapSpanContext(spanContext);
3084
- return nonRecordingSpan;
3085
- }
3086
- const initAttributes = sanitizeAttributes(Object.assign(attributes, samplingResult.attributes));
3087
- const span = new SpanImpl({
3088
- resource: this._resource,
3089
- scope: this.instrumentationScope,
3090
- context: context2,
3091
- spanContext,
3092
- name,
3093
- kind: spanKind,
3094
- links,
3095
- parentSpanContext: validParentSpanContext,
3096
- attributes: initAttributes,
3097
- startTime: options.startTime,
3098
- spanProcessor: this._spanProcessor,
3099
- spanLimits: this._spanLimits,
3100
- recordEndMetrics
3101
- });
3102
- return span;
3103
- }
3104
- startActiveSpan(name, arg2, arg3, arg4) {
3105
- let opts;
3106
- let ctx;
3107
- let fn;
3108
- if (arguments.length < 2) {
3109
- return;
3110
- } else if (arguments.length === 2) {
3111
- fn = arg2;
3112
- } else if (arguments.length === 3) {
3113
- opts = arg2;
3114
- fn = arg3;
3115
- } else {
3116
- opts = arg2;
3117
- ctx = arg3;
3118
- fn = arg4;
3119
- }
3120
- const parentContext = ctx ?? context.active();
3121
- const span = this.startSpan(name, opts, parentContext);
3122
- const contextWithSpanSet = trace.setSpan(parentContext, span);
3123
- return context.with(contextWithSpanSet, fn, void 0, span);
3124
- }
3125
- /** Returns the active {@link GeneralLimits}. */
3126
- getGeneralLimits() {
3127
- return this._generalLimits;
3128
- }
3129
- /** Returns the active {@link SpanLimits}. */
3130
- getSpanLimits() {
3131
- return this._spanLimits;
3132
- }
3133
- };
3134
-
3135
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/MultiSpanProcessor.js
3136
- var MultiSpanProcessor = class {
3137
- _spanProcessors;
3138
- constructor(spanProcessors) {
3139
- this._spanProcessors = spanProcessors;
3140
- }
3141
- forceFlush() {
3142
- const promises = [];
3143
- for (const spanProcessor of this._spanProcessors) {
3144
- promises.push(spanProcessor.forceFlush());
3145
- }
3146
- return new Promise((resolve2) => {
3147
- Promise.all(promises).then(() => {
3148
- resolve2();
3149
- }).catch((error) => {
3150
- globalErrorHandler(error || new Error("MultiSpanProcessor: forceFlush failed"));
3151
- resolve2();
3152
- });
3153
- });
3154
- }
3155
- onStart(span, context2) {
3156
- for (const spanProcessor of this._spanProcessors) {
3157
- spanProcessor.onStart(span, context2);
3158
- }
3159
- }
3160
- onEnding(span) {
3161
- for (const spanProcessor of this._spanProcessors) {
3162
- if (spanProcessor.onEnding) {
3163
- spanProcessor.onEnding(span);
3164
- }
3165
- }
3166
- }
3167
- onEnd(span) {
3168
- for (const spanProcessor of this._spanProcessors) {
3169
- spanProcessor.onEnd(span);
3170
- }
3171
- }
3172
- shutdown() {
3173
- const promises = [];
3174
- for (const spanProcessor of this._spanProcessors) {
3175
- promises.push(spanProcessor.shutdown());
3176
- }
3177
- return new Promise((resolve2, reject) => {
3178
- Promise.all(promises).then(() => {
3179
- resolve2();
3180
- }, reject);
3181
- });
3182
- }
3183
- };
3184
-
3185
- // ../../node_modules/@opentelemetry/sdk-trace-base/build/esm/BasicTracerProvider.js
3186
- var ForceFlushState;
3187
- (function(ForceFlushState2) {
3188
- ForceFlushState2[ForceFlushState2["resolved"] = 0] = "resolved";
3189
- ForceFlushState2[ForceFlushState2["timeout"] = 1] = "timeout";
3190
- ForceFlushState2[ForceFlushState2["error"] = 2] = "error";
3191
- ForceFlushState2[ForceFlushState2["unresolved"] = 3] = "unresolved";
3192
- })(ForceFlushState || (ForceFlushState = {}));
3193
- var BasicTracerProvider = class {
3194
- _config;
3195
- _tracers = /* @__PURE__ */ new Map();
3196
- _resource;
3197
- _activeSpanProcessor;
3198
- constructor(config = {}) {
3199
- const mergedConfig = merge({}, loadDefaultConfig(), reconfigureLimits(config));
3200
- this._resource = mergedConfig.resource ?? defaultResource();
3201
- this._config = Object.assign({}, mergedConfig, {
3202
- resource: this._resource
3203
- });
3204
- const spanProcessors = [];
3205
- if (config.spanProcessors?.length) {
3206
- spanProcessors.push(...config.spanProcessors);
3207
- }
3208
- this._activeSpanProcessor = new MultiSpanProcessor(spanProcessors);
3209
- }
3210
- getTracer(name, version, options) {
3211
- const key = `${name}@${version || ""}:${options?.schemaUrl || ""}`;
3212
- if (!this._tracers.has(key)) {
3213
- this._tracers.set(key, new Tracer({ name, version, schemaUrl: options?.schemaUrl }, this._config, this._resource, this._activeSpanProcessor));
3214
- }
3215
- return this._tracers.get(key);
3216
- }
3217
- forceFlush() {
3218
- const timeout = this._config.forceFlushTimeoutMillis;
3219
- const promises = this._activeSpanProcessor["_spanProcessors"].map((spanProcessor) => {
3220
- return new Promise((resolve2) => {
3221
- let state;
3222
- const timeoutInterval = setTimeout(() => {
3223
- resolve2(new Error(`Span processor did not completed within timeout period of ${timeout} ms`));
3224
- state = ForceFlushState.timeout;
3225
- }, timeout);
3226
- spanProcessor.forceFlush().then(() => {
3227
- clearTimeout(timeoutInterval);
3228
- if (state !== ForceFlushState.timeout) {
3229
- state = ForceFlushState.resolved;
3230
- resolve2(state);
3231
- }
3232
- }).catch((error) => {
3233
- clearTimeout(timeoutInterval);
3234
- state = ForceFlushState.error;
3235
- resolve2(error);
3236
- });
3237
- });
3238
- });
3239
- return new Promise((resolve2, reject) => {
3240
- Promise.all(promises).then((results) => {
3241
- const errors = results.filter((result) => result !== ForceFlushState.resolved);
3242
- if (errors.length > 0) {
3243
- reject(errors);
3244
- } else {
3245
- resolve2();
3246
- }
3247
- }).catch((error) => reject([error]));
3248
- });
3249
- }
3250
- shutdown() {
3251
- return this._activeSpanProcessor.shutdown();
3252
- }
3253
- };
3254
-
3255
- // src/lifecycle.ts
3256
- import { EventEmitter } from "node:events";
3257
-
3258
- // src/signal-handler.ts
3259
- var coexistenceState = "unknown";
3260
- function setCoexistenceState(s) {
3261
- coexistenceState = s;
3262
- }
3263
- function getCoexistenceState() {
3264
- return coexistenceState;
3265
- }
3266
-
3267
- // src/lifecycle.ts
3268
- var CoreState = {
3269
- IDLE: "IDLE",
3270
- REGISTERING: "REGISTERING",
3271
- KEY_PENDING: "KEY_PENDING",
3272
- KEY_RESOLVED: "KEY_RESOLVED",
3273
- ACTIVE: "ACTIVE",
3274
- ACTIVE_DEGRADED: "ACTIVE_DEGRADED",
3275
- SHUTTING_DOWN: "SHUTTING_DOWN",
3276
- SHUTDOWN: "SHUTDOWN",
3277
- PRODUCTION_DISABLED: "PRODUCTION_DISABLED",
3278
- REGISTRATION_FAILED: "REGISTRATION_FAILED"
3279
- };
3280
- var AuthState = {
3281
- ANONYMOUS: "ANONYMOUS",
3282
- AUTHENTICATED: "AUTHENTICATED",
3283
- CLAIMING: "CLAIMING",
3284
- CLAIMED: "CLAIMED"
3285
- };
3286
- var OtelState = {
3287
- UNCONFIGURED: "UNCONFIGURED",
3288
- CONFIGURING: "CONFIGURING",
3289
- OWNS_PROVIDER: "OWNS_PROVIDER",
3290
- AUTO_ATTACHED: "AUTO_ATTACHED",
3291
- PROCESSOR_PRESENT: "PROCESSOR_PRESENT",
3292
- COEXISTENCE_FAILED: "COEXISTENCE_FAILED"
3293
- };
3294
- var VALID_CORE_TRANSITIONS = {
3295
- [CoreState.IDLE]: [CoreState.REGISTERING, CoreState.REGISTRATION_FAILED, CoreState.SHUTTING_DOWN],
3296
- [CoreState.REGISTERING]: [
3297
- CoreState.KEY_PENDING,
3298
- CoreState.PRODUCTION_DISABLED,
3299
- CoreState.REGISTRATION_FAILED,
3300
- CoreState.SHUTTING_DOWN
3301
- ],
3302
- [CoreState.KEY_PENDING]: [
3303
- CoreState.KEY_RESOLVED,
3304
- CoreState.REGISTRATION_FAILED,
3305
- CoreState.SHUTTING_DOWN
3306
- ],
3307
- [CoreState.KEY_RESOLVED]: [
3308
- CoreState.ACTIVE,
3309
- CoreState.ACTIVE_DEGRADED,
3310
- CoreState.SHUTTING_DOWN
3311
- ],
3312
- [CoreState.ACTIVE]: [
3313
- CoreState.ACTIVE_DEGRADED,
3314
- CoreState.SHUTTING_DOWN
3315
- ],
3316
- [CoreState.ACTIVE_DEGRADED]: [
3317
- CoreState.ACTIVE,
3318
- CoreState.SHUTTING_DOWN
3319
- ],
3320
- [CoreState.SHUTTING_DOWN]: [CoreState.SHUTDOWN],
3321
- [CoreState.SHUTDOWN]: [],
3322
- [CoreState.PRODUCTION_DISABLED]: [],
3323
- [CoreState.REGISTRATION_FAILED]: []
3324
- };
3325
- var VALID_AUTH_TRANSITIONS = {
3326
- [AuthState.ANONYMOUS]: [AuthState.CLAIMING],
3327
- [AuthState.AUTHENTICATED]: [AuthState.CLAIMING],
3328
- [AuthState.CLAIMING]: [AuthState.CLAIMED],
3329
- [AuthState.CLAIMED]: [AuthState.CLAIMING]
3330
- };
3331
- var VALID_OTEL_TRANSITIONS = {
3332
- [OtelState.UNCONFIGURED]: [OtelState.CONFIGURING],
3333
- [OtelState.CONFIGURING]: [
3334
- OtelState.OWNS_PROVIDER,
3335
- OtelState.AUTO_ATTACHED,
3336
- OtelState.PROCESSOR_PRESENT,
3337
- OtelState.COEXISTENCE_FAILED
3338
- ],
3339
- [OtelState.OWNS_PROVIDER]: [],
3340
- [OtelState.AUTO_ATTACHED]: [],
3341
- [OtelState.PROCESSOR_PRESENT]: [],
3342
- [OtelState.COEXISTENCE_FAILED]: []
3343
- };
3344
- var _coreState = CoreState.IDLE;
3345
- var _authState = AuthState.ANONYMOUS;
3346
- var _otelState = OtelState.UNCONFIGURED;
3347
- var _emitter = new EventEmitter();
3348
- var _logger = null;
3349
- var _initialized = false;
3350
- var _initWarned = false;
3351
- var _coreReadyEmitted = false;
3352
- var _authInitialized = false;
3353
- var _emitting = false;
3354
- function initLifecycle(options) {
3355
- if (_initialized) {
3356
- options.logger("warn", "[glasstrace] initLifecycle() called twice \u2014 ignored.");
3357
- return;
3358
- }
3359
- _logger = options.logger;
3360
- _initialized = true;
3361
- }
3362
- function warnIfNotInitialized() {
3363
- if (!_initialized && !_initWarned) {
3364
- _initWarned = true;
3365
- console.warn(
3366
- "[glasstrace] Lifecycle state changed before initLifecycle() was called. Logger not available \u2014 errors will be silent."
3367
- );
3368
- }
3369
- }
3370
- function setCoreState(to) {
3371
- warnIfNotInitialized();
3372
- const from = _coreState;
3373
- if (from === to) return;
3374
- const valid = VALID_CORE_TRANSITIONS[from];
3375
- if (!valid.includes(to)) {
3376
- _logger?.(
3377
- "warn",
3378
- `[glasstrace] Invalid core state transition: ${from} \u2192 ${to}. Ignored.`
3379
- );
3380
- return;
3381
- }
3382
- _coreState = to;
3383
- if (_emitting) return;
3384
- _emitting = true;
3385
- try {
3386
- emitSafe("core:state_changed", { from, to });
3387
- const current = _coreState;
3388
- if (!_coreReadyEmitted && (current === CoreState.ACTIVE || current === CoreState.ACTIVE_DEGRADED)) {
3389
- _coreReadyEmitted = true;
3390
- emitSafe("core:ready", {});
3391
- }
3392
- if (current === CoreState.SHUTTING_DOWN) {
3393
- emitSafe("core:shutdown_started", {});
3394
- }
3395
- if (current === CoreState.SHUTDOWN) {
3396
- emitSafe("core:shutdown_completed", {});
3397
- }
3398
- } finally {
3399
- _emitting = false;
3400
- }
3401
- }
3402
- function initAuthState(state) {
3403
- if (_authInitialized) {
3404
- _logger?.(
3405
- "warn",
3406
- "[glasstrace] initAuthState() called after auth state already initialized. Ignored."
3407
- );
3408
- return;
3409
- }
3410
- _authInitialized = true;
3411
- _authState = state;
3412
- }
3413
- function setAuthState(to) {
3414
- warnIfNotInitialized();
3415
- const from = _authState;
3416
- if (from === to) return;
3417
- const valid = VALID_AUTH_TRANSITIONS[from];
3418
- if (!valid.includes(to)) {
3419
- _logger?.(
3420
- "warn",
3421
- `[glasstrace] Invalid auth state transition: ${from} \u2192 ${to}. Ignored.`
3422
- );
3423
- return;
3424
- }
3425
- _authState = to;
3426
- }
3427
- function setOtelState(to) {
3428
- warnIfNotInitialized();
3429
- const from = _otelState;
3430
- if (from === to) return;
3431
- const valid = VALID_OTEL_TRANSITIONS[from];
3432
- if (!valid.includes(to)) {
3433
- _logger?.(
3434
- "warn",
3435
- `[glasstrace] Invalid OTel state transition: ${from} \u2192 ${to}. Ignored.`
3436
- );
3437
- return;
3438
- }
3439
- _otelState = to;
3440
- }
3441
- function getCoreState() {
3442
- return _coreState;
3443
- }
3444
- function getSdkState() {
3445
- return {
3446
- core: _coreState,
3447
- auth: _authState,
3448
- otel: _otelState
3449
- };
3450
- }
3451
- function onLifecycleEvent(event, listener) {
3452
- _emitter.on(event, listener);
3453
- }
3454
- function emitLifecycleEvent(event, payload) {
3455
- emitSafe(event, payload);
3456
- }
3457
- function offLifecycleEvent(event, listener) {
3458
- _emitter.off(event, listener);
3459
- }
3460
- function emitSafe(event, payload) {
3461
- const listeners = _emitter.listeners(event);
3462
- for (const listener of listeners) {
3463
- try {
3464
- const result = listener(payload);
3465
- if (result && typeof result.catch === "function") {
3466
- result.catch((err) => {
3467
- _logger?.(
3468
- "error",
3469
- `[glasstrace] Async error in lifecycle event listener for "${event}": ${err instanceof Error ? err.message : String(err)}`
3470
- );
3471
- });
3472
- }
3473
- } catch (err) {
3474
- _logger?.(
3475
- "error",
3476
- `[glasstrace] Error in lifecycle event listener for "${event}": ${err instanceof Error ? err.message : String(err)}`
3477
- );
3478
- }
3479
- }
3480
- }
3481
- function isReady() {
3482
- return _coreState === CoreState.ACTIVE || _coreState === CoreState.ACTIVE_DEGRADED;
3483
- }
3484
- function waitForReady(timeoutMs = 3e4) {
3485
- if (isReady()) {
3486
- return Promise.resolve();
3487
- }
3488
- if (_coreState === CoreState.PRODUCTION_DISABLED || _coreState === CoreState.REGISTRATION_FAILED || _coreState === CoreState.SHUTTING_DOWN || _coreState === CoreState.SHUTDOWN) {
3489
- return Promise.reject(new Error(`SDK is in terminal state: ${_coreState}`));
3490
- }
3491
- return new Promise((resolve2, reject) => {
3492
- let settled = false;
3493
- const listener = ({ to }) => {
3494
- if (settled) return;
3495
- if (to === CoreState.ACTIVE || to === CoreState.ACTIVE_DEGRADED) {
3496
- settled = true;
3497
- offLifecycleEvent("core:state_changed", listener);
3498
- resolve2();
3499
- } else if (to === CoreState.PRODUCTION_DISABLED || to === CoreState.REGISTRATION_FAILED || to === CoreState.SHUTTING_DOWN || to === CoreState.SHUTDOWN) {
3500
- settled = true;
3501
- offLifecycleEvent("core:state_changed", listener);
3502
- reject(new Error(`SDK reached terminal state: ${to}`));
3503
- }
3504
- };
3505
- onLifecycleEvent("core:state_changed", listener);
3506
- if (timeoutMs > 0) {
3507
- const timer = setTimeout(() => {
3508
- if (settled) return;
3509
- settled = true;
3510
- offLifecycleEvent("core:state_changed", listener);
3511
- reject(new Error(`waitForReady timed out after ${timeoutMs}ms (state: ${_coreState})`));
3512
- }, timeoutMs);
3513
- if (typeof timer === "object" && "unref" in timer) {
3514
- timer.unref();
3515
- }
3516
- }
3517
- });
3518
- }
3519
- function getStatus() {
3520
- let mode;
3521
- if (_coreState === CoreState.PRODUCTION_DISABLED) {
3522
- mode = "disabled";
3523
- } else if (_authState === AuthState.CLAIMING || _authState === AuthState.CLAIMED) {
3524
- mode = "claiming";
3525
- } else if (_authState === AuthState.AUTHENTICATED) {
3526
- mode = "authenticated";
3527
- } else {
3528
- mode = "anonymous";
3529
- }
3530
- let tracing;
3531
- if (_otelState === OtelState.COEXISTENCE_FAILED || _otelState === OtelState.UNCONFIGURED || _otelState === OtelState.CONFIGURING) {
3532
- tracing = "not-configured";
3533
- } else if (_coreState === CoreState.ACTIVE_DEGRADED) {
3534
- tracing = "degraded";
3535
- } else if (_otelState === OtelState.AUTO_ATTACHED || _otelState === OtelState.PROCESSOR_PRESENT) {
3536
- tracing = "coexistence";
3537
- } else {
3538
- tracing = "active";
3539
- }
3540
- return {
3541
- ready: isReady(),
3542
- mode,
3543
- tracing
3544
- };
3545
- }
3546
- var _shutdownHooks = [];
3547
- var _signalHandlersRegistered = false;
3548
- var _signalHandler = null;
3549
- var _beforeExitRegistered = false;
3550
- var _beforeExitHandler = null;
3551
- var _shutdownExecuted = false;
3552
- function registerShutdownHook(hook) {
3553
- _shutdownHooks.push(hook);
3554
- _shutdownHooks.sort((a, b) => a.priority - b.priority);
3555
- }
3556
- async function executeShutdown(timeoutMs = 5e3) {
3557
- if (_shutdownExecuted) return;
3558
- _shutdownExecuted = true;
3559
- setCoreState(CoreState.SHUTTING_DOWN);
3560
- for (const hook of _shutdownHooks) {
3561
- try {
3562
- const hookPromise = hook.fn();
3563
- hookPromise.catch(() => {
3564
- });
3565
- await Promise.race([
3566
- hookPromise,
3567
- new Promise((_, reject) => {
3568
- const timer = setTimeout(() => reject(new Error(`Shutdown hook "${hook.name}" timed out`)), timeoutMs);
3569
- if (typeof timer === "object" && "unref" in timer) {
3570
- timer.unref();
3571
- }
3572
- })
3573
- ]);
3574
- } catch (err) {
3575
- _logger?.(
3576
- "warn",
3577
- `[glasstrace] Shutdown hook "${hook.name}" failed: ${err instanceof Error ? err.message : String(err)}`
3578
- );
3579
- }
3580
- }
3581
- setCoreState(CoreState.SHUTDOWN);
3582
- }
3583
- function registerSignalHandlers() {
3584
- if (_signalHandlersRegistered) return;
3585
- if (typeof process === "undefined" || typeof process.once !== "function") return;
3586
- _signalHandlersRegistered = true;
3587
- const otherSigtermListeners = process.listenerCount("SIGTERM");
3588
- const otherSigintListeners = process.listenerCount("SIGINT");
3589
- const handler = (signal) => {
3590
- void executeShutdown().finally(() => {
3591
- if (_signalHandler) {
3592
- process.removeListener("SIGTERM", _signalHandler);
3593
- process.removeListener("SIGINT", _signalHandler);
3594
- }
3595
- const otherListeners = signal === "SIGTERM" ? otherSigtermListeners : otherSigintListeners;
3596
- const otherProviderOwnsSignal = getCoexistenceState() === "coexisting" && otherListeners > 0;
3597
- if (!otherProviderOwnsSignal) {
3598
- process.kill(process.pid, signal);
3599
- }
3600
- });
3601
- };
3602
- _signalHandler = handler;
3603
- process.once("SIGTERM", handler);
3604
- process.once("SIGINT", handler);
3605
- }
3606
- function registerBeforeExitTrigger() {
3607
- if (_beforeExitRegistered) return;
3608
- if (typeof process === "undefined" || typeof process.once !== "function") return;
3609
- _beforeExitRegistered = true;
3610
- const handler = () => {
3611
- void executeShutdown();
3612
- };
3613
- _beforeExitHandler = handler;
3614
- process.once("beforeExit", handler);
3615
- }
3616
-
3617
- // src/coexistence.ts
3618
- var GLASSTRACE_EXPORTER_BRAND = /* @__PURE__ */ Symbol.for("glasstrace.exporter");
3619
- function createGlasstraceSpanProcessor(options) {
3620
- const config = resolveConfig(options);
3621
- const exporterUrl = `${config.endpoint}/v1/traces`;
3622
- const createOtlpExporter = (url, headers) => new OTLPTraceExporter({ url, headers });
3623
- const exporter = new GlasstraceExporter({
3624
- getApiKey: getResolvedApiKey,
3625
- sessionManager: getSessionManager(),
3626
- getConfig: () => getActiveConfig(),
3627
- environment: config.environment,
3628
- endpointUrl: exporterUrl,
3629
- createDelegate: createOtlpExporter,
3630
- // Propagate verbose so exporter-level enrichment and export logs
3631
- // stay observable whether the processor is built automatically by
3632
- // the coexistence path or wired manually by the developer.
3633
- verbose: config.verbose
3634
- });
3635
- registerExporterForKeyNotification(exporter);
3636
- return new BatchSpanProcessor(exporter, {
3637
- scheduledDelayMillis: 1e3
3638
- });
3639
- }
3640
- function isGlasstraceProcessorPresent(tracerProvider) {
3641
- try {
3642
- const proxy = tracerProvider;
3643
- const delegate = typeof proxy.getDelegate === "function" ? proxy.getDelegate() : tracerProvider;
3644
- const v2 = delegate;
3645
- const v2Processors = v2._activeSpanProcessor?._spanProcessors;
3646
- if (Array.isArray(v2Processors) && hasBrandedProcessor(v2Processors)) {
3647
- return true;
3648
- }
3649
- const v1 = delegate;
3650
- if (typeof v1.getActiveSpanProcessor === "function") {
3651
- const active = v1.getActiveSpanProcessor();
3652
- const processors = active?._spanProcessors;
3653
- if (Array.isArray(processors) && hasBrandedProcessor(processors)) {
3654
- return true;
3655
- }
3656
- }
3657
- return false;
3658
- } catch {
3659
- return false;
3660
- }
3661
- }
3662
- function tryAutoAttachGlasstraceProcessor(tracerProvider, options) {
3663
- try {
3664
- if (isGlasstraceProcessorPresent(tracerProvider)) {
3665
- return "already_present";
3666
- }
3667
- const proxy = tracerProvider;
3668
- const delegate = typeof proxy.getDelegate === "function" ? proxy.getDelegate() : tracerProvider;
3669
- const withAdd = delegate;
3670
- if (typeof withAdd.addSpanProcessor === "function") {
3671
- const processor2 = createGlasstraceSpanProcessor(options);
3672
- withAdd.addSpanProcessor(processor2);
3673
- return { method: "v1_public", processor: processor2 };
3674
- }
3675
- const v2 = delegate;
3676
- const multiProcessor = v2._activeSpanProcessor;
3677
- if (!multiProcessor || !Array.isArray(multiProcessor._spanProcessors)) {
3678
- return null;
3679
- }
3680
- const processor = createGlasstraceSpanProcessor(options);
3681
- multiProcessor._spanProcessors.push(processor);
3682
- return { method: "v2_private", processor };
3683
- } catch {
3684
- return null;
3685
- }
3686
- }
3687
- function emitNudgeMessage() {
3688
- const isSentry = detectSentry();
3689
- if (isSentry) {
3690
- sdkLog(
3691
- "info",
3692
- `[glasstrace] Detected existing OTel provider \u2014 auto-attached Glasstrace span processor.
3693
- For a cleaner setup, add Glasstrace to your Sentry config:
3694
-
3695
- import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
3696
-
3697
- Sentry.init({
3698
- dsn: '...',
3699
- openTelemetrySpanProcessors: [createGlasstraceSpanProcessor()],
3700
- });
3701
-
3702
- This message will not appear once Glasstrace is added to your provider config.`
3703
- );
3704
- } else {
3705
- sdkLog(
3706
- "info",
3707
- `[glasstrace] Detected existing OTel provider \u2014 auto-attached Glasstrace span processor.
3708
- For a cleaner setup, add Glasstrace to your provider config:
3709
-
3710
- import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
3711
-
3712
- const provider = new BasicTracerProvider({
3713
- spanProcessors: [
3714
- // ... your existing processors,
3715
- createGlasstraceSpanProcessor(),
3716
- ],
3717
- });
3718
-
3719
- This message will not appear once Glasstrace is added to your provider config.`
3720
- );
3721
- }
3722
- }
3723
- function emitGuidanceMessage() {
3724
- const isSentry = detectSentry();
3725
- if (isSentry) {
3726
- sdkLog(
3727
- "warn",
3728
- `[glasstrace] An existing OTel TracerProvider is registered but Glasstrace could not auto-attach its span processor.
3729
- Add Glasstrace to your Sentry config:
3730
-
3731
- import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
3732
-
3733
- Sentry.init({
3734
- dsn: '...',
3735
- openTelemetrySpanProcessors: [createGlasstraceSpanProcessor()],
3736
- });`
3737
- );
3738
- } else {
3739
- sdkLog(
3740
- "warn",
3741
- `[glasstrace] An existing OTel TracerProvider is registered but Glasstrace could not auto-attach its span processor.
3742
- Add Glasstrace to your provider configuration:
3743
-
3744
- import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
3745
-
3746
- const provider = new BasicTracerProvider({
3747
- spanProcessors: [
3748
- // ... your existing processors,
3749
- createGlasstraceSpanProcessor(),
3750
- ],
3751
- });`
3752
- );
3753
- }
3754
- }
3755
- function hasBrandedProcessor(processors) {
3756
- return processors.some((p) => {
3757
- const exporter = p._exporter;
3758
- return exporter?.[GLASSTRACE_EXPORTER_BRAND] === true;
3759
- });
3760
- }
3761
- function detectSentry() {
3762
- try {
3763
- __require.resolve("@sentry/node");
3764
- return true;
3765
- } catch {
3766
- try {
3767
- __require.resolve("@sentry/nextjs");
3768
- return true;
3769
- } catch {
3770
- return false;
3771
- }
3772
- }
3773
- }
3774
-
3775
- // src/otel-config.ts
3776
- var _resolvedApiKey = API_KEY_PENDING;
3777
- var _activeExporter = null;
3778
- var _additionalExporters = [];
3779
- var _injectedProcessor = null;
3780
- function setResolvedApiKey(key) {
3781
- _resolvedApiKey = key;
3782
- }
3783
- function getResolvedApiKey() {
3784
- return _resolvedApiKey;
3785
- }
3786
- function notifyApiKeyResolved() {
3787
- _activeExporter?.notifyKeyResolved();
3788
- for (const exporter of _additionalExporters) {
3789
- exporter.notifyKeyResolved();
3790
- }
3791
- }
3792
- function registerExporterForKeyNotification(exporter) {
3793
- _additionalExporters.push(exporter);
3794
- }
3795
- async function tryImport(moduleId) {
3796
- try {
3797
- return await Function("id", "return import(id)")(moduleId);
3798
- } catch {
3799
- return null;
3800
- }
3801
- }
3802
- async function configureOtel(config, sessionManager) {
3803
- setOtelState(OtelState.CONFIGURING);
3804
- await new Promise((resolve2) => {
3805
- if (typeof setImmediate === "function") {
3806
- setImmediate(resolve2);
3807
- } else {
3808
- setTimeout(resolve2, 0);
3809
- }
3810
- });
3811
- const existingProvider = trace.getTracerProvider();
3812
- const probeTracer = existingProvider.getTracer("glasstrace-probe");
3813
- const anotherProviderRegistered = probeTracer.constructor.name !== "ProxyTracer";
3814
- if (anotherProviderRegistered) {
3815
- setCoexistenceState("coexisting");
3816
- await runCoexistencePath(existingProvider, config);
3817
- return;
3818
- }
3819
- setCoexistenceState("sole-owner");
3820
- await runRegistrationPath(config, sessionManager);
3821
- }
3822
- async function runCoexistencePath(existingProvider, config) {
3823
- const result = tryAutoAttachGlasstraceProcessor(existingProvider, {
3824
- endpoint: config.endpoint,
3825
- verbose: config.verbose
3826
- });
3827
- if (result === "already_present") {
3828
- if (config.verbose) {
3829
- sdkLog("info", "[glasstrace] Existing provider detected \u2014 Glasstrace processor already present.");
3830
- }
3831
- setOtelState(OtelState.PROCESSOR_PRESENT);
3832
- emitLifecycleEvent("otel:configured", { state: OtelState.PROCESSOR_PRESENT, scenario: "B-clean" });
3833
- return;
3834
- }
3835
- if (result !== null) {
3836
- _injectedProcessor = result.processor;
3837
- if (config.verbose) {
3838
- sdkLog(
3839
- "info",
3840
- "[glasstrace] Existing provider detected \u2014 auto-attached Glasstrace span processor."
3841
- );
3842
- }
3843
- registerShutdownHook({
3844
- name: "coexistence-flush",
3845
- priority: 5,
3846
- fn: async () => {
3847
- if (_injectedProcessor) {
3848
- await _injectedProcessor.forceFlush();
3849
- }
3850
- }
3851
- });
3852
- registerBeforeExitTrigger();
3853
- const scenario = result.method === "v1_public" ? "D1" : "B-auto";
3854
- setOtelState(OtelState.AUTO_ATTACHED);
3855
- emitLifecycleEvent("otel:configured", { state: OtelState.AUTO_ATTACHED, scenario });
3856
- emitLifecycleEvent("otel:injection_succeeded", { method: result.method });
3857
- emitNudgeMessage();
3858
- return;
3859
- }
3860
- if (config.verbose) {
3861
- sdkLog("info", "[glasstrace] Existing provider detected \u2014 could not auto-attach.");
3862
- }
3863
- emitGuidanceMessage();
3864
- setOtelState(OtelState.COEXISTENCE_FAILED);
3865
- emitLifecycleEvent("otel:configured", { state: OtelState.COEXISTENCE_FAILED, scenario: "C/F" });
3866
- emitLifecycleEvent("otel:injection_failed", { reason: "provider internals inaccessible" });
3867
- const coreState = getCoreState();
3868
- if (coreState === CoreState.ACTIVE || coreState === CoreState.KEY_RESOLVED) {
3869
- setCoreState(CoreState.ACTIVE_DEGRADED);
3870
- }
3871
- }
3872
- async function runRegistrationPath(config, sessionManager) {
3873
- const exporterUrl = `${config.endpoint}/v1/traces`;
3874
- const createOtlpExporter = (url, headers) => new OTLPTraceExporter({ url, headers });
3875
- const glasstraceExporter = new GlasstraceExporter({
3876
- getApiKey: getResolvedApiKey,
3877
- sessionManager,
3878
- getConfig: () => getActiveConfig(),
3879
- environment: config.environment,
3880
- endpointUrl: exporterUrl,
3881
- createDelegate: createOtlpExporter,
3882
- verbose: config.verbose
3883
- });
3884
- _activeExporter = glasstraceExporter;
3885
- const vercelOtel = await tryImport("@vercel/otel");
3886
- if (vercelOtel && typeof vercelOtel.registerOTel === "function") {
3887
- const otelConfig = {
3888
- serviceName: "glasstrace-sdk",
3889
- traceExporter: glasstraceExporter
3890
- };
3891
- const prismaModule2 = await tryImport("@prisma/instrumentation");
3892
- if (prismaModule2) {
3893
- const PrismaInstrumentation = prismaModule2.PrismaInstrumentation;
3894
- if (PrismaInstrumentation) {
3895
- otelConfig.instrumentations = [new PrismaInstrumentation()];
3896
- }
3897
- }
3898
- vercelOtel.registerOTel(otelConfig);
3899
- const vercelProxy = trace.getTracerProvider();
3900
- const vercelConcreteProvider = typeof vercelProxy.getDelegate === "function" ? vercelProxy.getDelegate() : vercelProxy;
3901
- registerShutdownHook({
3902
- name: "vercel-otel-shutdown",
3903
- priority: 0,
3904
- fn: async () => {
3905
- try {
3906
- await vercelConcreteProvider.shutdown?.();
3907
- } catch {
3908
- }
3909
- }
3910
- });
3911
- registerBeforeExitTrigger();
3912
- setOtelState(OtelState.OWNS_PROVIDER);
3913
- emitLifecycleEvent("otel:configured", { state: OtelState.OWNS_PROVIDER, scenario: "E" });
3914
- return;
3915
- }
3916
- if (config.verbose) {
3917
- diag.setLogger(
3918
- {
3919
- verbose: (msg) => sdkLog("info", `[otel] ${msg}`),
3920
- debug: (msg) => sdkLog("info", `[otel] ${msg}`),
3921
- info: (msg) => sdkLog("info", `[otel] ${msg}`),
3922
- warn: (msg) => sdkLog("warn", `[otel] ${msg}`),
3923
- error: (msg) => sdkLog("error", `[otel] ${msg}`)
3924
- },
3925
- DiagLogLevel.WARN
3926
- );
3927
- }
3928
- const processor = new BatchSpanProcessor(glasstraceExporter, {
3929
- scheduledDelayMillis: 1e3
3930
- });
3931
- const provider = new BasicTracerProvider({
3932
- spanProcessors: [processor]
3933
- });
3934
- trace.setGlobalTracerProvider(provider);
3935
- registerShutdownHook({
3936
- name: "otel-provider-shutdown",
3937
- priority: 0,
3938
- fn: async () => {
3939
- await provider.shutdown();
3940
- }
3941
- });
3942
- registerBeforeExitTrigger();
3943
- const prismaModule = await tryImport("@prisma/instrumentation");
3944
- if (prismaModule) {
3945
- const PrismaInstrumentation = prismaModule.PrismaInstrumentation;
3946
- if (PrismaInstrumentation) {
3947
- try {
3948
- const inst = new PrismaInstrumentation();
3949
- inst.setTracerProvider(provider);
3950
- inst.enable();
3951
- } catch {
3952
- }
3953
- }
3954
- }
3955
- setOtelState(OtelState.OWNS_PROVIDER);
3956
- emitLifecycleEvent("otel:configured", { state: OtelState.OWNS_PROVIDER, scenario: "A" });
3957
- }
3958
-
3959
- // src/context-manager.ts
3960
- import { AsyncLocalStorage } from "node:async_hooks";
3961
- function installContextManager() {
3962
- try {
3963
- const als = new AsyncLocalStorage();
3964
- const contextManager = {
3965
- active: () => als.getStore() ?? ROOT_CONTEXT,
3966
- with: (context2, fn, thisArg, ...args) => als.run(context2, () => fn.apply(thisArg, args)),
3967
- bind: (context2, target) => {
3968
- if (typeof target === "function") {
3969
- const bound = (...fnArgs) => als.run(context2, () => target(...fnArgs));
3970
- return bound;
3971
- }
3972
- return target;
3973
- },
3974
- enable: () => contextManager,
3975
- disable: () => contextManager
3976
- };
3977
- const success = context.setGlobalContextManager(contextManager);
3978
- if (!success) {
3979
- console.warn(
3980
- "[glasstrace] Another context manager is already registered. Trace context propagation may not work as expected."
3981
- );
3982
- }
3983
- return success;
3984
- } catch {
3985
- return false;
3986
- }
3987
- }
3988
-
3989
- // src/heartbeat.ts
3990
- var HEARTBEAT_INTERVAL_MS = 5 * 60 * 1e3;
3991
- var BACKOFF_BASE_MS = HEARTBEAT_INTERVAL_MS;
3992
- var BACKOFF_MAX_MS = 30 * 60 * 1e3;
3993
- var BACKOFF_JITTER = 0.2;
3994
- var HEARTBEAT_SHUTDOWN_PRIORITY = 10;
3995
- var SHUTDOWN_MARKER_RELPATH = ".glasstrace/shutdown-requested";
3996
- var heartbeatTimer = null;
3997
- var heartbeatGeneration = 0;
3998
- var backoffAttempts = 0;
3999
- var backoffUntil = 0;
4000
- var tickInProgress = false;
4001
- var shutdownHookRegistered = false;
4002
- var shutdownFired = false;
4003
- function startHeartbeat(config, anonKey, sdkVersion, generation, onClaimTransition) {
4004
- if (heartbeatTimer !== null) return;
4005
- heartbeatGeneration = generation;
4006
- heartbeatTimer = setInterval(() => {
4007
- void heartbeatTick(config, anonKey, sdkVersion, generation, onClaimTransition);
4008
- }, HEARTBEAT_INTERVAL_MS);
4009
- heartbeatTimer.unref();
4010
- registerHeartbeatShutdownHook(config, anonKey, sdkVersion);
4011
- if (config.verbose) {
4012
- sdkLog("info", "[glasstrace] Heartbeat started (5-minute interval).");
4013
- }
4014
- }
4015
- function stopHeartbeat() {
4016
- if (heartbeatTimer !== null) {
4017
- clearInterval(heartbeatTimer);
4018
- heartbeatTimer = null;
4019
- }
4020
- }
4021
- function checkShutdownMarker(projectRoot) {
4022
- let fsSync = null;
4023
- let pathSync = null;
4024
- try {
4025
- fsSync = __require("node:fs");
4026
- pathSync = __require("node:path");
4027
- } catch {
4028
- return { triggered: false };
4029
- }
4030
- const root = projectRoot ?? (typeof process !== "undefined" ? process.cwd() : ".");
4031
- const markerPath = pathSync.join(root, SHUTDOWN_MARKER_RELPATH);
4032
- if (!fsSync.existsSync(markerPath)) return { triggered: false };
4033
- try {
4034
- fsSync.unlinkSync(markerPath);
4035
- } catch {
4036
- }
4037
- const shutdown = executeShutdown().catch(() => {
4038
- });
4039
- return { triggered: true, shutdown };
4040
- }
4041
- async function heartbeatTick(config, anonKey, sdkVersion, generation, onClaimTransition) {
4042
- if (tickInProgress) return;
4043
- tickInProgress = true;
4044
- try {
4045
- if (generation !== heartbeatGeneration) {
4046
- stopHeartbeat();
4047
- return;
4048
- }
4049
- const markerResult = checkShutdownMarker();
4050
- if (markerResult.triggered) {
4051
- stopHeartbeat();
4052
- if (markerResult.shutdown) {
4053
- await markerResult.shutdown;
4054
- }
4055
- return;
4056
- }
4057
- if (Date.now() < backoffUntil) {
4058
- if (config.verbose) {
4059
- sdkLog("info", "[glasstrace] Heartbeat skipped (rate-limit backoff).");
4060
- }
4061
- return;
4062
- }
4063
- const healthReport = collectHealthReport(sdkVersion);
4064
- const initResult = await performInit(config, anonKey, sdkVersion, healthReport);
4065
- if (generation !== heartbeatGeneration) return;
4066
- if (initResult === null && consumeRateLimitFlag()) {
4067
- backoffAttempts++;
4068
- const delay = Math.min(
4069
- BACKOFF_BASE_MS * Math.pow(2, backoffAttempts - 1),
4070
- BACKOFF_MAX_MS
4071
- );
4072
- const jitter = delay * BACKOFF_JITTER * (Math.random() * 2 - 1);
4073
- backoffUntil = Date.now() + delay + jitter;
4074
- if (config.verbose) {
4075
- sdkLog("info", `[glasstrace] Heartbeat backing off for ${Math.round((delay + jitter) / 1e3)}s.`);
4076
- }
4077
- } else {
4078
- backoffAttempts = 0;
4079
- backoffUntil = 0;
4080
- }
4081
- if (initResult?.claimResult) {
4082
- onClaimTransition(initResult.claimResult.newApiKey, initResult.claimResult.accountId);
4083
- }
4084
- if (config.verbose) {
4085
- sdkLog("info", "[glasstrace] Heartbeat completed.");
4086
- }
4087
- } finally {
4088
- tickInProgress = false;
4089
- }
4090
- }
4091
- function registerHeartbeatShutdownHook(config, anonKey, sdkVersion) {
4092
- if (shutdownHookRegistered) return;
4093
- shutdownHookRegistered = true;
4094
- registerShutdownHook({
4095
- name: "heartbeat-final-report",
4096
- priority: HEARTBEAT_SHUTDOWN_PRIORITY,
4097
- fn: async () => {
4098
- if (shutdownFired) return;
4099
- shutdownFired = true;
4100
- if (heartbeatTimer !== null) {
4101
- clearInterval(heartbeatTimer);
4102
- heartbeatTimer = null;
4103
- }
4104
- try {
4105
- const healthReport = collectHealthReport(sdkVersion);
4106
- await performInit(config, anonKey, sdkVersion, healthReport);
4107
- } catch {
4108
- }
4109
- }
4110
- });
4111
- }
4112
-
4113
- // src/runtime-state.ts
4114
- import { writeFileSync, renameSync, mkdirSync } from "node:fs";
4115
- import { join } from "node:path";
4116
- var _projectRoot = null;
4117
- var _sdkVersion = "unknown";
4118
- var _lastScenario;
4119
- var _debounceTimer = null;
4120
- var _started = false;
4121
- function startRuntimeStateWriter(options) {
4122
- if (_started) return;
4123
- _started = true;
4124
- _projectRoot = options.projectRoot;
4125
- _sdkVersion = options.sdkVersion;
4126
- onLifecycleEvent("core:state_changed", ({ to }) => {
4127
- if (to === CoreState.SHUTDOWN) {
4128
- writeStateNow();
4129
- } else {
4130
- debouncedWrite();
4131
- }
4132
- });
4133
- onLifecycleEvent("otel:configured", ({ scenario }) => {
4134
- _lastScenario = scenario;
4135
- debouncedWrite();
4136
- });
4137
- onLifecycleEvent("auth:key_resolved", () => debouncedWrite());
4138
- onLifecycleEvent("auth:claim_started", () => debouncedWrite());
4139
- onLifecycleEvent("auth:claim_completed", () => debouncedWrite());
4140
- writeStateNow();
4141
- }
4142
- function debouncedWrite() {
4143
- if (_debounceTimer) return;
4144
- _debounceTimer = setTimeout(() => {
4145
- _debounceTimer = null;
4146
- writeStateNow();
4147
- }, 1e3);
4148
- if (typeof _debounceTimer === "object" && "unref" in _debounceTimer) {
4149
- _debounceTimer.unref();
4150
- }
4151
- }
4152
- function writeStateNow() {
4153
- if (!_projectRoot) return;
4154
- try {
4155
- const state = getSdkState();
4156
- const runtimeState = {
4157
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
4158
- pid: process.pid,
4159
- sdkVersion: _sdkVersion,
4160
- core: { state: state.core },
4161
- auth: { state: state.auth },
4162
- otel: { state: state.otel, scenario: _lastScenario }
4163
- };
4164
- const dir = join(_projectRoot, ".glasstrace");
4165
- const filePath = join(dir, "runtime-state.json");
4166
- const tmpPath = join(dir, "runtime-state.json.tmp");
4167
- mkdirSync(dir, { recursive: true, mode: 448 });
4168
- writeFileSync(tmpPath, JSON.stringify(runtimeState, null, 2) + "\n", {
4169
- mode: 384
4170
- });
4171
- renameSync(tmpPath, filePath);
4172
- } catch (err) {
4173
- sdkLog(
4174
- "warn",
4175
- `[glasstrace] Failed to write runtime state: ${err instanceof Error ? err.message : String(err)}`
4176
- );
4177
- }
4178
- }
4179
-
4180
- // src/register.ts
4181
- function maskKey(key) {
4182
- if (key.length <= 12) return key.slice(0, 4) + "...";
4183
- return key.slice(0, 8) + "..." + key.slice(-4);
4184
- }
4185
- var consoleCaptureInstalled = false;
4186
- var discoveryHandler = null;
4187
- var registrationGeneration = 0;
4188
- var _sessionManager = null;
4189
- function getSessionManager() {
4190
- if (!_sessionManager) {
4191
- _sessionManager = new SessionManager();
4192
- }
4193
- return _sessionManager;
4194
- }
4195
- function registerGlasstrace(options) {
4196
- try {
4197
- if (getCoreState() !== CoreState.IDLE) {
4198
- return;
4199
- }
4200
- initLifecycle({ logger: sdkLog });
4201
- if (typeof process === "undefined" || typeof process.versions?.node !== "string") {
4202
- console.warn(
4203
- "[glasstrace] SDK requires a Node.js runtime. Edge Runtime, browser, and Deno without Node compat are not supported. Glasstrace is disabled in this environment."
4204
- );
4205
- return;
4206
- }
4207
- setCoreState(CoreState.REGISTERING);
4208
- startRuntimeStateWriter({
4209
- projectRoot: process.cwd(),
4210
- sdkVersion: "0.19.0"
4211
- });
4212
- const config = resolveConfig(options);
4213
- if (config.verbose) {
4214
- console.info("[glasstrace] Config resolved.");
4215
- }
4216
- if (isProductionDisabled(config)) {
4217
- setCoreState(CoreState.PRODUCTION_DISABLED);
4218
- console.warn(
4219
- "[glasstrace] Disabled in production. Set GLASSTRACE_FORCE_ENABLE=true to override."
4220
- );
4221
- return;
4222
- }
4223
- if (config.verbose) {
4224
- console.info("[glasstrace] Not production-disabled.");
4225
- }
4226
- const existingProbe = trace.getTracerProvider().getTracer("glasstrace-probe");
4227
- const anotherProviderRegistered = existingProbe.constructor.name !== "ProxyTracer";
4228
- if (anotherProviderRegistered) {
4229
- setCoexistenceState("coexisting");
4230
- }
4231
- registerSignalHandlers();
4232
- const anonymous = isAnonymousMode(config);
4233
- let effectiveKey = config.apiKey;
4234
- initAuthState(anonymous ? AuthState.ANONYMOUS : AuthState.AUTHENTICATED);
4235
- if (effectiveKey) {
4236
- setResolvedApiKey(effectiveKey);
4237
- emitLifecycleEvent("auth:key_resolved", {
4238
- key: maskKey(effectiveKey),
4239
- mode: anonymous ? "anonymous" : "dev"
4240
- });
4241
- }
4242
- if (config.verbose) {
4243
- console.info(
4244
- `[glasstrace] Auth mode = ${anonymous ? "anonymous" : "dev-key"}.`
4245
- );
4246
- }
4247
- const cachedInitResponse = loadCachedConfig();
4248
- if (cachedInitResponse) {
4249
- _setCurrentConfig(cachedInitResponse);
4250
- }
4251
- if (config.verbose) {
4252
- console.info(
4253
- `[glasstrace] Cached config ${cachedInitResponse ? "loaded and applied" : "not found"}.`
4254
- );
4255
- }
4256
- const sessionManager = getSessionManager();
4257
- if (config.verbose) {
4258
- console.info("[glasstrace] SessionManager created.");
4259
- }
4260
- setCoreState(CoreState.KEY_PENDING);
4261
- const currentGeneration = registrationGeneration;
4262
- if (anotherProviderRegistered) {
4263
- if (config.verbose) {
4264
- console.info("[glasstrace] Another OTel provider detected \u2014 using existing context manager.");
4265
- }
4266
- } else {
4267
- const contextManagerInstalled = installContextManager();
4268
- if (config.verbose) {
4269
- console.info(
4270
- contextManagerInstalled ? "[glasstrace] Context manager installed." : "[glasstrace] Context manager not available \u2014 trace context propagation disabled."
4271
- );
4272
- }
4273
- }
4274
- void configureOtel(config, sessionManager).then(
4275
- () => {
4276
- maybeInstallConsoleCapture();
4277
- if (config.verbose) {
4278
- console.info("[glasstrace] OTel configured.");
4279
- }
4280
- },
4281
- (err) => {
4282
- console.warn(
4283
- `[glasstrace] Failed to configure OTel: ${err instanceof Error ? err.message : String(err)}`
4284
- );
4285
- }
4286
- );
4287
- if (anonymous) {
4288
- if (isDiscoveryEnabled(config)) {
4289
- let resolvedAnonKey = null;
4290
- const anonKeyPromise = getOrCreateAnonKey();
4291
- const getClaimState = () => {
4292
- if (getLinkedAccountId()) return { claimed: true };
4293
- if (getClaimResult()) return { claimed: true };
4294
- return null;
4295
- };
4296
- discoveryHandler = createDiscoveryHandler(
4297
- async () => resolvedAnonKey,
4298
- () => sessionManager.getSessionId(getResolvedApiKey()),
4299
- getClaimState
4300
- );
4301
- if (config.verbose) {
4302
- console.info("[glasstrace] Discovery endpoint registered (key pending).");
4303
- }
4304
- void (async () => {
4305
- try {
4306
- if (currentGeneration !== registrationGeneration) return;
4307
- const anonKey = await anonKeyPromise;
4308
- resolvedAnonKey = anonKey;
4309
- setResolvedApiKey(anonKey);
4310
- notifyApiKeyResolved();
4311
- emitLifecycleEvent("auth:key_resolved", { key: maskKey(anonKey), mode: "anonymous" });
4312
- effectiveKey = anonKey;
4313
- if (currentGeneration !== registrationGeneration) return;
4314
- discoveryHandler = createDiscoveryHandler(
4315
- () => Promise.resolve(anonKey),
4316
- () => sessionManager.getSessionId(getResolvedApiKey()),
4317
- getClaimState
4318
- );
4319
- await backgroundInit(config, anonKey, currentGeneration);
4320
- } catch (err) {
4321
- console.warn(
4322
- `[glasstrace] Background init failed: ${err instanceof Error ? err.message : String(err)}`
4323
- );
4324
- }
4325
- })();
4326
- } else {
4327
- void (async () => {
4328
- try {
4329
- if (currentGeneration !== registrationGeneration) return;
4330
- const anonKey = await getOrCreateAnonKey();
4331
- setResolvedApiKey(anonKey);
4332
- notifyApiKeyResolved();
4333
- emitLifecycleEvent("auth:key_resolved", { key: maskKey(anonKey), mode: "anonymous" });
4334
- effectiveKey = anonKey;
4335
- if (currentGeneration !== registrationGeneration) return;
4336
- await backgroundInit(config, anonKey, currentGeneration);
4337
- } catch (err) {
4338
- console.warn(
4339
- `[glasstrace] Background init failed: ${err instanceof Error ? err.message : String(err)}`
4340
- );
4341
- }
4342
- })();
4343
- }
4344
- } else {
4345
- void (async () => {
4346
- try {
4347
- if (currentGeneration !== registrationGeneration) return;
4348
- let anonKeyForInit = null;
4349
- try {
4350
- anonKeyForInit = await readAnonKey();
4351
- } catch {
4352
- }
4353
- if (currentGeneration !== registrationGeneration) return;
4354
- await backgroundInit(config, anonKeyForInit, currentGeneration);
4355
- } catch (err) {
4356
- console.warn(
4357
- `[glasstrace] Background init failed: ${err instanceof Error ? err.message : String(err)}`
4358
- );
4359
- }
4360
- })();
4361
- }
4362
- if (config.coverageMapEnabled && config.verbose) {
4363
- console.info("[glasstrace] Import graph building skipped.");
4364
- }
4365
- } catch (err) {
4366
- setCoreState(CoreState.REGISTRATION_FAILED);
4367
- console.warn(
4368
- `[glasstrace] Registration failed: ${err instanceof Error ? err.message : String(err)}`
4369
- );
4370
- }
4371
- }
4372
- async function backgroundInit(config, anonKeyForInit, generation) {
4373
- if (config.verbose) {
4374
- console.info("[glasstrace] Background init firing.");
4375
- }
4376
- const healthReport = collectHealthReport("0.19.0");
4377
- const initResult = await performInit(config, anonKeyForInit, "0.19.0", healthReport);
4378
- if (generation !== registrationGeneration) return;
4379
- const currentState = getCoreState();
4380
- if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
4381
- return;
4382
- }
4383
- if (currentState === CoreState.KEY_PENDING) {
4384
- setCoreState(CoreState.KEY_RESOLVED);
4385
- }
4386
- if (getCoreState() === CoreState.KEY_RESOLVED) {
4387
- setCoreState(didLastInitSucceed() ? CoreState.ACTIVE : CoreState.ACTIVE_DEGRADED);
4388
- }
4389
- if (initResult?.claimResult) {
4390
- const { newApiKey, accountId } = initResult.claimResult;
4391
- setAuthState(AuthState.CLAIMING);
4392
- emitLifecycleEvent("auth:claim_started", { accountId });
4393
- setResolvedApiKey(newApiKey);
4394
- notifyApiKeyResolved();
4395
- setAuthState(AuthState.CLAIMED);
4396
- emitLifecycleEvent("auth:claim_completed", { newKey: maskKey(newApiKey), accountId });
4397
- }
4398
- maybeInstallConsoleCapture();
4399
- if (didLastInitSucceed()) {
4400
- startHeartbeat(config, anonKeyForInit, "0.19.0", generation, (newApiKey, accountId) => {
4401
- setAuthState(AuthState.CLAIMING);
4402
- emitLifecycleEvent("auth:claim_started", { accountId });
4403
- setResolvedApiKey(newApiKey);
4404
- notifyApiKeyResolved();
4405
- setAuthState(AuthState.CLAIMED);
4406
- emitLifecycleEvent("auth:claim_completed", { newKey: maskKey(newApiKey), accountId });
4407
- });
4408
- }
4409
- }
4410
- function getDiscoveryHandler() {
4411
- return discoveryHandler;
4412
- }
4413
- function maybeInstallConsoleCapture() {
4414
- if (consoleCaptureInstalled) return;
4415
- if (getActiveConfig().consoleErrors) {
4416
- consoleCaptureInstalled = true;
4417
- void installConsoleCapture();
4418
- }
4419
- }
4420
- function isDiscoveryEnabled(config) {
4421
- if (process.env.GLASSTRACE_DISCOVERY_ENABLED === "true") return true;
4422
- if (process.env.GLASSTRACE_DISCOVERY_ENABLED === "false") return false;
4423
- if (config.nodeEnv === "production") return false;
4424
- if (config.vercelEnv === "production") return false;
4425
- if (config.nodeEnv === "development" || config.nodeEnv === void 0) return true;
4426
- return false;
4427
- }
4428
-
4429
- // src/config-wrapper.ts
4430
- import { isBuiltin as isNodeBuiltin } from "node:module";
4431
- function isTurbopackBuild() {
4432
- if (typeof process === "undefined") return false;
4433
- const argv = Array.isArray(process.argv) ? process.argv : [];
4434
- if (argv.includes("--webpack")) return false;
4435
- if (argv.includes("--turbopack")) return true;
4436
- if (process.env?.TURBOPACK === "1") return true;
4437
- return false;
4438
- }
4439
- var SDK_PACKAGE_NAME = "@glasstrace/sdk";
4440
- function appendNodeSchemeExternal(webpackConfig) {
4441
- const nodeBuiltinExternal = (data, callback) => {
4442
- const request = data.request;
4443
- if (typeof request === "string" && isNodeBuiltin(request)) {
4444
- callback(null, "commonjs " + request);
4445
- return;
4446
- }
4447
- callback(null);
4448
- };
4449
- const existing = webpackConfig.externals;
4450
- if (Array.isArray(existing)) {
4451
- webpackConfig.externals = [...existing, nodeBuiltinExternal];
4452
- } else if (existing == null) {
4453
- webpackConfig.externals = [nodeBuiltinExternal];
4454
- } else {
4455
- webpackConfig.externals = [existing, nodeBuiltinExternal];
4456
- }
4457
- }
4458
- function ensureServerExternal(config) {
4459
- const existingStable = config.serverExternalPackages;
4460
- const stable = Array.isArray(existingStable) ? (
4461
- // Clone so we never mutate a caller-owned array in place.
4462
- existingStable.filter((entry) => typeof entry === "string")
4463
- ) : [];
4464
- if (!stable.includes(SDK_PACKAGE_NAME)) {
4465
- stable.push(SDK_PACKAGE_NAME);
4466
- }
4467
- config.serverExternalPackages = stable;
4468
- }
4469
- function withGlasstraceConfig(nextConfig) {
4470
- if (typeof process === "undefined" || typeof process.versions?.node !== "string") {
4471
- return nextConfig != null ? { ...nextConfig } : {};
4472
- }
4473
- const config = nextConfig != null ? { ...nextConfig } : {};
4474
- const bag = config;
4475
- const existingExperimental = bag.experimental ?? {};
4476
- bag.experimental = {
4477
- ...existingExperimental,
4478
- serverSourceMaps: true
4479
- };
4480
- ensureServerExternal(bag);
4481
- if (bag.turbopack == null) {
4482
- bag.turbopack = {};
4483
- }
4484
- if (isTurbopackBuild()) {
4485
- warnTurbopackLimitationOnce();
4486
- }
4487
- const distDir = typeof bag.distDir === "string" ? bag.distDir : ".next";
4488
- const existingWebpack = bag.webpack;
4489
- bag.webpack = (webpackConfig, context2) => {
4490
- let result = webpackConfig;
4491
- if (typeof existingWebpack === "function") {
4492
- result = existingWebpack(webpackConfig, context2);
4493
- }
4494
- const webpackContext = context2;
4495
- if (webpackContext.isServer) {
4496
- appendNodeSchemeExternal(result);
4497
- }
4498
- if (!webpackContext.isServer && webpackContext.dev === false) {
4499
- const plugins = result.plugins ?? [];
4500
- plugins.push({
4501
- apply(compiler) {
4502
- const typedCompiler = compiler;
4503
- if (typedCompiler.hooks?.afterEmit?.tapPromise) {
4504
- typedCompiler.hooks.afterEmit.tapPromise(
4505
- "GlasstraceSourceMapUpload",
4506
- async () => {
4507
- await handleSourceMapUpload(distDir);
4508
- }
4509
- );
4510
- }
4511
- }
4512
- });
4513
- result.plugins = plugins;
4514
- }
4515
- return result;
4516
- };
4517
- return config;
4518
- }
4519
- var _turbopackWarningEmitted = false;
4520
- function warnTurbopackLimitationOnce() {
4521
- if (_turbopackWarningEmitted) return;
4522
- _turbopackWarningEmitted = true;
4523
- console.warn(
4524
- "[glasstrace] Turbopack detected. Source-map upload currently runs only under webpack \u2014 run `next build --webpack` to upload source maps, or wait for the Turbopack port in a future SDK release."
4525
- );
4526
- }
4527
- async function handleSourceMapUpload(distDir) {
4528
- try {
4529
- const apiKey = process.env.GLASSTRACE_API_KEY;
4530
- const endpoint = process.env.GLASSTRACE_ENDPOINT ?? "https://api.glasstrace.dev";
4531
- if (!apiKey || apiKey.trim() === "") {
4532
- console.info(
4533
- "[glasstrace] Source map upload skipped (no API key). Stack traces will show compiled locations."
4534
- );
4535
- return;
4536
- }
4537
- const { discoverSourceMapFiles: discoverSourceMapFiles2, computeBuildHash: computeBuildHash2, uploadSourceMaps: uploadSourceMaps2 } = await import("./source-map-uploader-VPDZWWM2.js");
4538
- const files = await discoverSourceMapFiles2(distDir);
4539
- if (files.length === 0) {
4540
- console.info("[glasstrace] No source map files found. Skipping upload.");
4541
- return;
4542
- }
4543
- const buildHash = await computeBuildHash2(files);
4544
- await uploadSourceMaps2(apiKey, endpoint, buildHash, files);
4545
- console.info(
4546
- `[glasstrace] Uploaded ${String(files.length)} source map(s) for build ${buildHash}.`
4547
- );
4548
- } catch (error) {
4549
- const message = error instanceof Error ? error.message : "Unknown error";
4550
- console.warn(
4551
- `[glasstrace] Source map upload failed: ${message}. Build continues normally.`
4552
- );
4553
- }
4554
- }
4555
-
4556
- // src/capture-error.ts
4557
- function captureError(error) {
4558
- try {
4559
- const span = trace.getSpan(context.active());
4560
- if (!span) return;
4561
- const attributes = {
4562
- "error.message": String(error)
4563
- };
4564
- if (error instanceof Error) {
4565
- attributes["error.type"] = error.constructor.name;
4566
- if (error.stack) {
4567
- attributes["error.stack"] = error.stack;
4568
- }
4569
- }
4570
- span.addEvent("glasstrace.error", attributes);
4571
- maybeShowMcpNudge(String(error));
4572
- } catch {
4573
- }
4574
- }
4575
-
4576
- // src/correlation-id.ts
4577
- var ATTR2 = GLASSTRACE_ATTRIBUTE_NAMES;
4578
- var HEADER_NAME = "x-gt-cid";
4579
- var MAX_CID_LENGTH = 128;
4580
- function captureCorrelationId(req) {
4581
- try {
4582
- if (!req || !req.headers) {
4583
- return;
4584
- }
4585
- const value = readHeader(req.headers);
4586
- if (!value) {
4587
- return;
4588
- }
4589
- const span = trace.getActiveSpan();
4590
- if (!span) {
4591
- return;
4592
- }
4593
- span.setAttribute(ATTR2.CORRELATION_ID, value);
4594
- } catch {
4595
- }
4596
- }
4597
- function readHeader(headers) {
4598
- const asFetch = headers;
4599
- if (typeof asFetch.get === "function") {
4600
- const raw = asFetch.get(HEADER_NAME);
4601
- return firstToken(raw);
4602
- }
4603
- const dict = headers;
4604
- const direct = dict[HEADER_NAME];
4605
- if (direct !== void 0) {
4606
- return firstValue(direct);
4607
- }
4608
- for (const key of Object.keys(dict)) {
4609
- if (key.toLowerCase() === HEADER_NAME) {
4610
- return firstValue(dict[key]);
4611
- }
4612
- }
4613
- return void 0;
4614
- }
4615
- function firstValue(value) {
4616
- if (Array.isArray(value)) {
4617
- for (const entry of value) {
4618
- const token = firstToken(entry);
4619
- if (token) return token;
4620
- }
4621
- return void 0;
4622
- }
4623
- return firstToken(value);
4624
- }
4625
- function firstToken(value) {
4626
- if (typeof value !== "string") return void 0;
4627
- const parts = value.split(",");
4628
- for (const part of parts) {
4629
- const trimmed = part.trim();
4630
- if (trimmed.length === 0) continue;
4631
- if (trimmed.length > MAX_CID_LENGTH) return void 0;
4632
- return trimmed;
4633
- }
4634
- return void 0;
4635
- }
57
+ } from "./chunk-TQ54WLCZ.js";
58
+ import "./chunk-NSBPE2FW.js";
4636
59
  export {
4637
60
  GlasstraceExporter,
4638
61
  GlasstraceSpanProcessor,