autotel 2.18.0 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attributes.cjs +21 -20
- package/dist/attributes.js +2 -1
- package/dist/chunk-2ZKEORFN.cjs +14 -0
- package/dist/chunk-2ZKEORFN.cjs.map +1 -0
- package/dist/chunk-4A53YIAX.js +180 -0
- package/dist/chunk-4A53YIAX.js.map +1 -0
- package/dist/{chunk-QKVQWGTF.js → chunk-5JLXDCL2.js} +3 -3
- package/dist/{chunk-QKVQWGTF.js.map → chunk-5JLXDCL2.js.map} +1 -1
- package/dist/chunk-7552UTQW.js +11 -0
- package/dist/chunk-7552UTQW.js.map +1 -0
- package/dist/{chunk-NWT5SYOX.cjs → chunk-BEVIAKTB.cjs} +5 -5
- package/dist/{chunk-NWT5SYOX.cjs.map → chunk-BEVIAKTB.cjs.map} +1 -1
- package/dist/chunk-ESMHTKLJ.cjs +206 -0
- package/dist/chunk-ESMHTKLJ.cjs.map +1 -0
- package/dist/{chunk-QP5LVD4L.js → chunk-G47ZCJGW.js} +25 -3
- package/dist/{chunk-QP5LVD4L.js.map → chunk-G47ZCJGW.js.map} +1 -1
- package/dist/{chunk-WC2AMGBX.js → chunk-LCMARHLX.js} +3 -3
- package/dist/{chunk-WC2AMGBX.js.map → chunk-LCMARHLX.js.map} +1 -1
- package/dist/{chunk-HZ23L5KR.cjs → chunk-LGT7XA5O.cjs} +5 -5
- package/dist/{chunk-HZ23L5KR.cjs.map → chunk-LGT7XA5O.cjs.map} +1 -1
- package/dist/{chunk-4HPWUYCV.js → chunk-M4US3P4K.js} +3 -170
- package/dist/chunk-M4US3P4K.js.map +1 -0
- package/dist/{chunk-FMPBL2NF.js → chunk-XBVB3AFF.js} +3 -3
- package/dist/{chunk-FMPBL2NF.js.map → chunk-XBVB3AFF.js.map} +1 -1
- package/dist/{chunk-DWRTSOGR.cjs → chunk-XI5WPVR5.cjs} +25 -3
- package/dist/chunk-XI5WPVR5.cjs.map +1 -0
- package/dist/{chunk-74L5DOB4.cjs → chunk-XNBTEFRZ.cjs} +7 -7
- package/dist/{chunk-74L5DOB4.cjs.map → chunk-XNBTEFRZ.cjs.map} +1 -1
- package/dist/chunk-XRBP4RYL.cjs +764 -0
- package/dist/chunk-XRBP4RYL.cjs.map +1 -0
- package/dist/decorators.cjs +1 -1
- package/dist/decorators.js +1 -1
- package/dist/functional.cjs +8 -8
- package/dist/functional.js +1 -1
- package/dist/index.cjs +65 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/messaging.cjs +5 -5
- package/dist/messaging.js +2 -2
- package/dist/semantic-conventions.cjs +30 -0
- package/dist/semantic-conventions.cjs.map +1 -0
- package/dist/semantic-conventions.d.cts +29 -0
- package/dist/semantic-conventions.d.ts +29 -0
- package/dist/semantic-conventions.js +5 -0
- package/dist/semantic-conventions.js.map +1 -0
- package/dist/semantic-helpers.cjs +6 -6
- package/dist/semantic-helpers.js +2 -2
- package/dist/webhook.cjs +2 -2
- package/dist/webhook.js +1 -1
- package/dist/workflow-distributed.cjs +3 -3
- package/dist/workflow-distributed.js +1 -1
- package/dist/workflow.cjs +6 -6
- package/dist/workflow.js +2 -2
- package/package.json +16 -11
- package/src/decorators.test.ts +22 -72
- package/src/functional.test.ts +24 -6
- package/src/functional.ts +37 -2
- package/src/index.ts +9 -0
- package/src/init.openllmetry.test.ts +76 -76
- package/src/semantic-conventions.ts +15 -0
- package/dist/chunk-4HPWUYCV.js.map +0 -1
- package/dist/chunk-7F4PDILZ.cjs +0 -931
- package/dist/chunk-7F4PDILZ.cjs.map +0 -1
- package/dist/chunk-DWRTSOGR.cjs.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shutdown.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Graceful shutdown with flush and cleanup\n */\n\nimport { getSdk, getLogger } from './init';\nimport { getEventQueue, resetEventQueue } from './track';\nimport { resetEvents } from './event';\nimport { resetMetrics } from './metric';\n\n/**\n * Flush all pending telemetry\n *\n * Flushes both events events and OpenTelemetry spans to their destinations.\n * Includes timeout protection to prevent hanging in serverless environments.\n *\n * Safe to call multiple times.\n *\n * @param options - Optional configuration\n * @param options.timeout - Timeout in milliseconds (default: 2000ms)\n * @param options.forShutdown - If true, permanently disables the events queue after flush (used internally by shutdown())\n *\n * @example Manual flush in serverless\n * ```typescript\n * import { flush } from 'autotel';\n *\n * export const handler = async (event) => {\n * // ... process event\n * await flush(); // Flush before function returns\n * return result;\n * };\n * ```\n *\n * @example With custom timeout\n * ```typescript\n * await flush({ timeout: 5000 }); // 5 second timeout\n * ```\n */\nexport async function flush(options?: {\n timeout?: number;\n forShutdown?: boolean;\n}): Promise<void> {\n const timeout = options?.timeout ?? 2000;\n const forShutdown = options?.forShutdown ?? false;\n\n const doFlush = async () => {\n // Flush events queue (or shutdown queue when tearing down)\n const eventsQueue = getEventQueue();\n if (eventsQueue) {\n if (forShutdown) {\n await eventsQueue.shutdown();\n } else {\n await eventsQueue.flush();\n }\n }\n\n // Flush OpenTelemetry spans\n // This ensures spans are exported immediately, critical for serverless\n const sdk = getSdk();\n if (sdk) {\n try {\n // Type assertion needed as getTracerProvider is not in the public NodeSDK interface\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdkAny = sdk as any;\n if (typeof sdkAny.getTracerProvider === 'function') {\n const tracerProvider = sdkAny.getTracerProvider();\n if (\n tracerProvider &&\n typeof tracerProvider.forceFlush === 'function'\n ) {\n await tracerProvider.forceFlush();\n }\n }\n } catch {\n // Ignore errors when accessing tracer provider (may not be available in test mocks)\n }\n }\n };\n\n // Add timeout protection to prevent hanging\n let timeoutHandle: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n doFlush().finally(() => {\n // Clear timeout as soon as flush completes\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }),\n new Promise<void>((_, reject) => {\n timeoutHandle = setTimeout(\n () => reject(new Error('Flush timeout')),\n timeout,\n );\n // Use unref() to allow Node to exit if flush completes first\n // This prevents the 2s delay in serverless when flush succeeds immediately\n timeoutHandle.unref();\n }),\n ]);\n } catch (error) {\n // Clear timeout on error too\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n const logger = getLogger();\n logger.error(\n {\n err: error instanceof Error ? error : new Error(String(error)),\n },\n '[autotel] Flush error',\n );\n throw error;\n }\n}\n\n/**\n * Shutdown telemetry and cleanup resources\n *\n * - Flushes all pending data\n * - Shuts down OpenTelemetry SDK\n * - Cleans up resources\n *\n * Call this before process exit.\n *\n * Always performs cleanup even if flush fails, preventing resource leaks\n * in serverless handlers or tests.\n *\n * @example Express server\n * ```typescript\n * const server = app.listen(3000)\n *\n * process.on('SIGTERM', async () => {\n * await server.close()\n * await shutdown()\n * process.exit(0)\n * })\n * ```\n */\nexport async function shutdown(): Promise<void> {\n const logger = getLogger();\n let shutdownError: Error | null = null;\n\n // Attempt to flush (with queue shutdown so new events are rejected), but continue with cleanup even if it fails\n try {\n await flush({ forShutdown: true });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n shutdownError = err;\n logger.error(\n {\n err,\n },\n '[autotel] Flush failed during shutdown, continuing cleanup',\n );\n }\n\n // Always shutdown SDK and clean up resources\n try {\n // Shutdown OpenTelemetry SDK\n const sdk = getSdk();\n if (sdk) {\n await sdk.shutdown();\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n\n // Ignore ECONNREFUSED errors - this happens when no OTLP endpoint was configured\n // The SDK tries to flush exporters that don't exist, which is harmless\n const isConnectionRefused =\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'ECONNREFUSED';\n\n if (!isConnectionRefused) {\n // Only store/log non-connection errors\n if (!shutdownError) {\n shutdownError = err;\n }\n logger.error({ err }, '[autotel] SDK shutdown failed');\n }\n } finally {\n // Clean up singleton Maps and queues to prevent memory leaks\n // This runs even if SDK shutdown fails\n const eventsQueue = getEventQueue();\n if (eventsQueue && typeof eventsQueue.cleanup === 'function') {\n eventsQueue.cleanup();\n }\n resetEvents();\n resetMetrics();\n resetEventQueue();\n }\n\n // Rethrow first error after cleanup completes\n // This allows tests and CI to detect failures while still ensuring cleanup\n if (shutdownError) {\n throw shutdownError;\n }\n}\n\n/**\n * Register automatic shutdown hooks for common signals\n *\n * Handles:\n * - SIGTERM (Docker/K8s graceful shutdown)\n * - SIGINT (Ctrl+C)\n *\n * @internal Called automatically on module load\n */\nfunction registerShutdownHooks(): void {\n if (typeof process === 'undefined') return; // Not in Node.js\n\n const signals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT'];\n let shuttingDown = false;\n\n for (const signal of signals) {\n process.on(signal, async () => {\n if (shuttingDown) return; // Prevent double shutdown\n shuttingDown = true;\n\n if (process.env.NODE_ENV !== 'test') {\n getLogger().info(\n {},\n `[autotel] Received ${signal}, flushing telemetry...`,\n );\n }\n\n try {\n await shutdown();\n } catch (error) {\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n },\n '[autotel] Error during shutdown',\n );\n } finally {\n process.exit(0);\n }\n });\n }\n}\n\n// Auto-register shutdown hooks\nregisterShutdownHooks();\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/shutdown.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Graceful shutdown with flush and cleanup\n */\n\nimport { getSdk, getLogger } from './init';\nimport { getEventQueue, resetEventQueue } from './track';\nimport { resetEvents } from './event';\nimport { resetMetrics } from './metric';\n\n/**\n * Flush all pending telemetry\n *\n * Flushes both events events and OpenTelemetry spans to their destinations.\n * Includes timeout protection to prevent hanging in serverless environments.\n *\n * Safe to call multiple times.\n *\n * @param options - Optional configuration\n * @param options.timeout - Timeout in milliseconds (default: 2000ms)\n * @param options.forShutdown - If true, permanently disables the events queue after flush (used internally by shutdown())\n *\n * @example Manual flush in serverless\n * ```typescript\n * import { flush } from 'autotel';\n *\n * export const handler = async (event) => {\n * // ... process event\n * await flush(); // Flush before function returns\n * return result;\n * };\n * ```\n *\n * @example With custom timeout\n * ```typescript\n * await flush({ timeout: 5000 }); // 5 second timeout\n * ```\n */\nexport async function flush(options?: {\n timeout?: number;\n forShutdown?: boolean;\n}): Promise<void> {\n const timeout = options?.timeout ?? 2000;\n const forShutdown = options?.forShutdown ?? false;\n\n const doFlush = async () => {\n // Flush events queue (or shutdown queue when tearing down)\n const eventsQueue = getEventQueue();\n if (eventsQueue) {\n if (forShutdown) {\n await eventsQueue.shutdown();\n } else {\n await eventsQueue.flush();\n }\n }\n\n // Flush OpenTelemetry spans\n // This ensures spans are exported immediately, critical for serverless\n const sdk = getSdk();\n if (sdk) {\n try {\n // Type assertion needed as getTracerProvider is not in the public NodeSDK interface\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdkAny = sdk as any;\n if (typeof sdkAny.getTracerProvider === 'function') {\n const tracerProvider = sdkAny.getTracerProvider();\n if (\n tracerProvider &&\n typeof tracerProvider.forceFlush === 'function'\n ) {\n await tracerProvider.forceFlush();\n }\n }\n } catch {\n // Ignore errors when accessing tracer provider (may not be available in test mocks)\n }\n }\n };\n\n // Add timeout protection to prevent hanging\n let timeoutHandle: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n doFlush().finally(() => {\n // Clear timeout as soon as flush completes\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }),\n new Promise<void>((_, reject) => {\n timeoutHandle = setTimeout(\n () => reject(new Error('Flush timeout')),\n timeout,\n );\n // Use unref() to allow Node to exit if flush completes first\n // This prevents the 2s delay in serverless when flush succeeds immediately\n timeoutHandle.unref();\n }),\n ]);\n } catch (error) {\n // Clear timeout on error too\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n const logger = getLogger();\n logger.error(\n {\n err: error instanceof Error ? error : new Error(String(error)),\n },\n '[autotel] Flush error',\n );\n throw error;\n }\n}\n\n/**\n * Shutdown telemetry and cleanup resources\n *\n * - Flushes all pending data\n * - Shuts down OpenTelemetry SDK\n * - Cleans up resources\n *\n * Call this before process exit.\n *\n * Always performs cleanup even if flush fails, preventing resource leaks\n * in serverless handlers or tests.\n *\n * @example Express server\n * ```typescript\n * const server = app.listen(3000)\n *\n * process.on('SIGTERM', async () => {\n * await server.close()\n * await shutdown()\n * process.exit(0)\n * })\n * ```\n */\nexport async function shutdown(): Promise<void> {\n const logger = getLogger();\n let shutdownError: Error | null = null;\n\n // Attempt to flush (with queue shutdown so new events are rejected), but continue with cleanup even if it fails\n try {\n await flush({ forShutdown: true });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n shutdownError = err;\n logger.error(\n {\n err,\n },\n '[autotel] Flush failed during shutdown, continuing cleanup',\n );\n }\n\n // Always shutdown SDK and clean up resources\n try {\n // Shutdown OpenTelemetry SDK\n const sdk = getSdk();\n if (sdk) {\n await sdk.shutdown();\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n\n // Ignore ECONNREFUSED errors - this happens when no OTLP endpoint was configured\n // The SDK tries to flush exporters that don't exist, which is harmless\n const isConnectionRefused =\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'ECONNREFUSED';\n\n if (!isConnectionRefused) {\n // Only store/log non-connection errors\n if (!shutdownError) {\n shutdownError = err;\n }\n logger.error({ err }, '[autotel] SDK shutdown failed');\n }\n } finally {\n // Clean up singleton Maps and queues to prevent memory leaks\n // This runs even if SDK shutdown fails\n const eventsQueue = getEventQueue();\n if (eventsQueue && typeof eventsQueue.cleanup === 'function') {\n eventsQueue.cleanup();\n }\n resetEvents();\n resetMetrics();\n resetEventQueue();\n }\n\n // Rethrow first error after cleanup completes\n // This allows tests and CI to detect failures while still ensuring cleanup\n if (shutdownError) {\n throw shutdownError;\n }\n}\n\n/**\n * Register automatic shutdown hooks for common signals\n *\n * Handles:\n * - SIGTERM (Docker/K8s graceful shutdown)\n * - SIGINT (Ctrl+C)\n *\n * @internal Called automatically on module load\n */\nfunction registerShutdownHooks(): void {\n if (typeof process === 'undefined') return; // Not in Node.js\n\n const signals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT'];\n let shuttingDown = false;\n\n for (const signal of signals) {\n process.on(signal, async () => {\n if (shuttingDown) return; // Prevent double shutdown\n shuttingDown = true;\n\n if (process.env.NODE_ENV !== 'test') {\n getLogger().info(\n {},\n `[autotel] Received ${signal}, flushing telemetry...`,\n );\n }\n\n try {\n await shutdown();\n } catch (error) {\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n },\n '[autotel] Error during shutdown',\n );\n } finally {\n process.exit(0);\n }\n });\n }\n}\n\n// Auto-register shutdown hooks\nregisterShutdownHooks();\n"]}
|
package/dist/messaging.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkBEVIAKTB_cjs = require('./chunk-BEVIAKTB.cjs');
|
|
4
|
+
require('./chunk-XI5WPVR5.cjs');
|
|
5
5
|
require('./chunk-W4EUTSB2.cjs');
|
|
6
6
|
require('./chunk-5PZZHX4Y.cjs');
|
|
7
7
|
require('./chunk-D5LMF53P.cjs');
|
|
@@ -25,15 +25,15 @@ require('./chunk-JEQ2X3Z6.cjs');
|
|
|
25
25
|
|
|
26
26
|
Object.defineProperty(exports, "clearOrderingState", {
|
|
27
27
|
enumerable: true,
|
|
28
|
-
get: function () { return
|
|
28
|
+
get: function () { return chunkBEVIAKTB_cjs.clearOrderingState; }
|
|
29
29
|
});
|
|
30
30
|
Object.defineProperty(exports, "traceConsumer", {
|
|
31
31
|
enumerable: true,
|
|
32
|
-
get: function () { return
|
|
32
|
+
get: function () { return chunkBEVIAKTB_cjs.traceConsumer; }
|
|
33
33
|
});
|
|
34
34
|
Object.defineProperty(exports, "traceProducer", {
|
|
35
35
|
enumerable: true,
|
|
36
|
-
get: function () { return
|
|
36
|
+
get: function () { return chunkBEVIAKTB_cjs.traceProducer; }
|
|
37
37
|
});
|
|
38
38
|
//# sourceMappingURL=messaging.cjs.map
|
|
39
39
|
//# sourceMappingURL=messaging.cjs.map
|
package/dist/messaging.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { clearOrderingState, traceConsumer, traceProducer } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { clearOrderingState, traceConsumer, traceProducer } from './chunk-XBVB3AFF.js';
|
|
2
|
+
import './chunk-G47ZCJGW.js';
|
|
3
3
|
import './chunk-SR35DG5A.js';
|
|
4
4
|
import './chunk-HJPXNUZR.js';
|
|
5
5
|
import './chunk-WD4RP6IV.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk2ZKEORFN_cjs = require('./chunk-2ZKEORFN.cjs');
|
|
4
|
+
var chunkESMHTKLJ_cjs = require('./chunk-ESMHTKLJ.cjs');
|
|
5
|
+
require('./chunk-JEQ2X3Z6.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Object.defineProperty(exports, "httpRequestHeaderAttribute", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () { return chunk2ZKEORFN_cjs.httpRequestHeaderAttribute; }
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(exports, "httpResponseHeaderAttribute", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return chunk2ZKEORFN_cjs.httpResponseHeaderAttribute; }
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(exports, "HTTPAttributes", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return chunkESMHTKLJ_cjs.HTTPAttributes; }
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(exports, "ServiceAttributes", {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () { return chunkESMHTKLJ_cjs.ServiceAttributes; }
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "URLAttributes", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () { return chunkESMHTKLJ_cjs.URLAttributes; }
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=semantic-conventions.cjs.map
|
|
30
|
+
//# sourceMappingURL=semantic-conventions.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"semantic-conventions.cjs"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare const HTTPAttributes: {
|
|
2
|
+
readonly connectionState: "http.connection.state";
|
|
3
|
+
readonly requestMethod: "http.request.method";
|
|
4
|
+
readonly requestMethodOriginal: "http.request.method_original";
|
|
5
|
+
readonly requestResendCount: "http.request.resend_count";
|
|
6
|
+
readonly requestSize: "http.request.size";
|
|
7
|
+
readonly requestBodySize: "http.request.body.size";
|
|
8
|
+
readonly responseSize: "http.response.size";
|
|
9
|
+
readonly responseBodySize: "http.response.body.size";
|
|
10
|
+
readonly responseStatusCode: "http.response.status_code";
|
|
11
|
+
readonly route: "http.route";
|
|
12
|
+
};
|
|
13
|
+
declare const ServiceAttributes: {
|
|
14
|
+
readonly name: "service.name";
|
|
15
|
+
readonly instance: "service.instance.id";
|
|
16
|
+
readonly version: "service.version";
|
|
17
|
+
};
|
|
18
|
+
declare const URLAttributes: {
|
|
19
|
+
readonly scheme: "url.scheme";
|
|
20
|
+
readonly full: "url.full";
|
|
21
|
+
readonly path: "url.path";
|
|
22
|
+
readonly query: "url.query";
|
|
23
|
+
readonly fragment: "url.fragment";
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
declare function httpRequestHeaderAttribute(name: string): string;
|
|
27
|
+
declare function httpResponseHeaderAttribute(name: string): string;
|
|
28
|
+
|
|
29
|
+
export { HTTPAttributes, ServiceAttributes, URLAttributes, httpRequestHeaderAttribute, httpResponseHeaderAttribute };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare const HTTPAttributes: {
|
|
2
|
+
readonly connectionState: "http.connection.state";
|
|
3
|
+
readonly requestMethod: "http.request.method";
|
|
4
|
+
readonly requestMethodOriginal: "http.request.method_original";
|
|
5
|
+
readonly requestResendCount: "http.request.resend_count";
|
|
6
|
+
readonly requestSize: "http.request.size";
|
|
7
|
+
readonly requestBodySize: "http.request.body.size";
|
|
8
|
+
readonly responseSize: "http.response.size";
|
|
9
|
+
readonly responseBodySize: "http.response.body.size";
|
|
10
|
+
readonly responseStatusCode: "http.response.status_code";
|
|
11
|
+
readonly route: "http.route";
|
|
12
|
+
};
|
|
13
|
+
declare const ServiceAttributes: {
|
|
14
|
+
readonly name: "service.name";
|
|
15
|
+
readonly instance: "service.instance.id";
|
|
16
|
+
readonly version: "service.version";
|
|
17
|
+
};
|
|
18
|
+
declare const URLAttributes: {
|
|
19
|
+
readonly scheme: "url.scheme";
|
|
20
|
+
readonly full: "url.full";
|
|
21
|
+
readonly path: "url.path";
|
|
22
|
+
readonly query: "url.query";
|
|
23
|
+
readonly fragment: "url.fragment";
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
declare function httpRequestHeaderAttribute(name: string): string;
|
|
27
|
+
declare function httpResponseHeaderAttribute(name: string): string;
|
|
28
|
+
|
|
29
|
+
export { HTTPAttributes, ServiceAttributes, URLAttributes, httpRequestHeaderAttribute, httpResponseHeaderAttribute };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { httpRequestHeaderAttribute, httpResponseHeaderAttribute } from './chunk-7552UTQW.js';
|
|
2
|
+
export { HTTPAttributes, ServiceAttributes, URLAttributes } from './chunk-4A53YIAX.js';
|
|
3
|
+
import './chunk-DGUM43GV.js';
|
|
4
|
+
//# sourceMappingURL=semantic-conventions.js.map
|
|
5
|
+
//# sourceMappingURL=semantic-conventions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"semantic-conventions.js"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkXNBTEFRZ_cjs = require('./chunk-XNBTEFRZ.cjs');
|
|
4
|
+
require('./chunk-XI5WPVR5.cjs');
|
|
5
5
|
require('./chunk-W4EUTSB2.cjs');
|
|
6
6
|
require('./chunk-5PZZHX4Y.cjs');
|
|
7
7
|
require('./chunk-D5LMF53P.cjs');
|
|
@@ -25,19 +25,19 @@ require('./chunk-JEQ2X3Z6.cjs');
|
|
|
25
25
|
|
|
26
26
|
Object.defineProperty(exports, "traceDB", {
|
|
27
27
|
enumerable: true,
|
|
28
|
-
get: function () { return
|
|
28
|
+
get: function () { return chunkXNBTEFRZ_cjs.traceDB; }
|
|
29
29
|
});
|
|
30
30
|
Object.defineProperty(exports, "traceHTTP", {
|
|
31
31
|
enumerable: true,
|
|
32
|
-
get: function () { return
|
|
32
|
+
get: function () { return chunkXNBTEFRZ_cjs.traceHTTP; }
|
|
33
33
|
});
|
|
34
34
|
Object.defineProperty(exports, "traceLLM", {
|
|
35
35
|
enumerable: true,
|
|
36
|
-
get: function () { return
|
|
36
|
+
get: function () { return chunkXNBTEFRZ_cjs.traceLLM; }
|
|
37
37
|
});
|
|
38
38
|
Object.defineProperty(exports, "traceMessaging", {
|
|
39
39
|
enumerable: true,
|
|
40
|
-
get: function () { return
|
|
40
|
+
get: function () { return chunkXNBTEFRZ_cjs.traceMessaging; }
|
|
41
41
|
});
|
|
42
42
|
//# sourceMappingURL=semantic-helpers.cjs.map
|
|
43
43
|
//# sourceMappingURL=semantic-helpers.cjs.map
|
package/dist/semantic-helpers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-5JLXDCL2.js';
|
|
2
|
+
import './chunk-G47ZCJGW.js';
|
|
3
3
|
import './chunk-SR35DG5A.js';
|
|
4
4
|
import './chunk-HJPXNUZR.js';
|
|
5
5
|
import './chunk-WD4RP6IV.js';
|
package/dist/webhook.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkXI5WPVR5_cjs = require('./chunk-XI5WPVR5.cjs');
|
|
4
4
|
require('./chunk-W4EUTSB2.cjs');
|
|
5
5
|
require('./chunk-5PZZHX4Y.cjs');
|
|
6
6
|
require('./chunk-D5LMF53P.cjs');
|
|
@@ -148,7 +148,7 @@ function createParkingLot(config) {
|
|
|
148
148
|
},
|
|
149
149
|
traceCallback(callbackConfig) {
|
|
150
150
|
return (fnFactory) => {
|
|
151
|
-
return
|
|
151
|
+
return chunkXI5WPVR5_cjs.trace(
|
|
152
152
|
{
|
|
153
153
|
name: callbackConfig.name,
|
|
154
154
|
spanKind: api.SpanKind.SERVER
|
package/dist/webhook.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkINJD3G4K_cjs = require('./chunk-INJD3G4K.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkXI5WPVR5_cjs = require('./chunk-XI5WPVR5.cjs');
|
|
5
5
|
require('./chunk-W4EUTSB2.cjs');
|
|
6
6
|
require('./chunk-5PZZHX4Y.cjs');
|
|
7
7
|
require('./chunk-D5LMF53P.cjs');
|
|
@@ -59,7 +59,7 @@ var WorkflowBaggage = chunkINJD3G4K_cjs.createSafeBaggageSchema(workflowBaggageF
|
|
|
59
59
|
function traceDistributedWorkflow(config) {
|
|
60
60
|
const spanName = `workflow.${config.name}`;
|
|
61
61
|
return (fnFactory) => {
|
|
62
|
-
return
|
|
62
|
+
return chunkXI5WPVR5_cjs.trace(
|
|
63
63
|
{ name: spanName, spanKind: api.SpanKind.INTERNAL },
|
|
64
64
|
(baseCtx) => {
|
|
65
65
|
return async (...args) => {
|
|
@@ -158,7 +158,7 @@ function traceDistributedWorkflow(config) {
|
|
|
158
158
|
function traceDistributedStep(config) {
|
|
159
159
|
const spanName = `workflow.step.${config.name}`;
|
|
160
160
|
return (fnFactory) => {
|
|
161
|
-
return
|
|
161
|
+
return chunkXI5WPVR5_cjs.trace(
|
|
162
162
|
{ name: spanName, spanKind: api.SpanKind.INTERNAL },
|
|
163
163
|
(baseCtx) => {
|
|
164
164
|
return async (...args) => {
|
package/dist/workflow.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkLGT7XA5O_cjs = require('./chunk-LGT7XA5O.cjs');
|
|
4
|
+
require('./chunk-XI5WPVR5.cjs');
|
|
5
5
|
require('./chunk-W4EUTSB2.cjs');
|
|
6
6
|
require('./chunk-5PZZHX4Y.cjs');
|
|
7
7
|
require('./chunk-D5LMF53P.cjs');
|
|
@@ -25,19 +25,19 @@ require('./chunk-JEQ2X3Z6.cjs');
|
|
|
25
25
|
|
|
26
26
|
Object.defineProperty(exports, "getCurrentWorkflowContext", {
|
|
27
27
|
enumerable: true,
|
|
28
|
-
get: function () { return
|
|
28
|
+
get: function () { return chunkLGT7XA5O_cjs.getCurrentWorkflowContext; }
|
|
29
29
|
});
|
|
30
30
|
Object.defineProperty(exports, "isInWorkflow", {
|
|
31
31
|
enumerable: true,
|
|
32
|
-
get: function () { return
|
|
32
|
+
get: function () { return chunkLGT7XA5O_cjs.isInWorkflow; }
|
|
33
33
|
});
|
|
34
34
|
Object.defineProperty(exports, "traceStep", {
|
|
35
35
|
enumerable: true,
|
|
36
|
-
get: function () { return
|
|
36
|
+
get: function () { return chunkLGT7XA5O_cjs.traceStep; }
|
|
37
37
|
});
|
|
38
38
|
Object.defineProperty(exports, "traceWorkflow", {
|
|
39
39
|
enumerable: true,
|
|
40
|
-
get: function () { return
|
|
40
|
+
get: function () { return chunkLGT7XA5O_cjs.traceWorkflow; }
|
|
41
41
|
});
|
|
42
42
|
//# sourceMappingURL=workflow.cjs.map
|
|
43
43
|
//# sourceMappingURL=workflow.cjs.map
|
package/dist/workflow.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-LCMARHLX.js';
|
|
2
|
+
import './chunk-G47ZCJGW.js';
|
|
3
3
|
import './chunk-SR35DG5A.js';
|
|
4
4
|
import './chunk-HJPXNUZR.js';
|
|
5
5
|
import './chunk-WD4RP6IV.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0",
|
|
4
4
|
"description": "Write Once, Observe Anywhere",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -188,6 +188,11 @@
|
|
|
188
188
|
"import": "./dist/workflow-distributed.js",
|
|
189
189
|
"require": "./dist/workflow-distributed.cjs"
|
|
190
190
|
},
|
|
191
|
+
"./semantic-conventions": {
|
|
192
|
+
"types": "./dist/semantic-conventions.d.ts",
|
|
193
|
+
"import": "./dist/semantic-conventions.js",
|
|
194
|
+
"require": "./dist/semantic-conventions.cjs"
|
|
195
|
+
},
|
|
191
196
|
"./correlation-id": {
|
|
192
197
|
"types": "./dist/correlation-id.d.ts",
|
|
193
198
|
"import": "./dist/correlation-id.js",
|
|
@@ -229,7 +234,7 @@
|
|
|
229
234
|
"@opentelemetry/sdk-node": "^0.211.0",
|
|
230
235
|
"@opentelemetry/sdk-trace-base": "^2.5.0",
|
|
231
236
|
"@opentelemetry/semantic-conventions": "^1.39.0",
|
|
232
|
-
"import-in-the-middle": "^
|
|
237
|
+
"import-in-the-middle": "^3.0.0"
|
|
233
238
|
},
|
|
234
239
|
"peerDependencies": {
|
|
235
240
|
"@opentelemetry/auto-instrumentations-node": "^0.69.0",
|
|
@@ -242,8 +247,8 @@
|
|
|
242
247
|
"@opentelemetry/resource-detector-gcp": "^0.46.0",
|
|
243
248
|
"@opentelemetry/sdk-logs": "^0.211.0",
|
|
244
249
|
"@opentelemetry/sdk-trace-node": "^2.5.0",
|
|
245
|
-
"@traceloop/node-server-sdk": "^0.22.
|
|
246
|
-
"pino": "^10.3.
|
|
250
|
+
"@traceloop/node-server-sdk": "^0.22.7",
|
|
251
|
+
"pino": "^10.3.1",
|
|
247
252
|
"pino-pretty": "^13.1.3",
|
|
248
253
|
"yaml": "^2.8.2"
|
|
249
254
|
},
|
|
@@ -308,19 +313,19 @@
|
|
|
308
313
|
"@total-typescript/ts-reset": "^0.6.1",
|
|
309
314
|
"@total-typescript/tsconfig": "^1.0.4",
|
|
310
315
|
"@types/eslint-config-prettier": "^6.11.3",
|
|
311
|
-
"@types/node": "^25.
|
|
312
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
313
|
-
"@typescript-eslint/parser": "^8.
|
|
316
|
+
"@types/node": "^25.2.3",
|
|
317
|
+
"@typescript-eslint/eslint-plugin": "^8.55.0",
|
|
318
|
+
"@typescript-eslint/parser": "^8.55.0",
|
|
314
319
|
"eslint-config-prettier": "^10.1.8",
|
|
315
|
-
"eslint-plugin-unicorn": "^
|
|
316
|
-
"pino": "^10.3.
|
|
320
|
+
"eslint-plugin-unicorn": "^63.0.0",
|
|
321
|
+
"pino": "^10.3.1",
|
|
317
322
|
"prettier": "^3.8.1",
|
|
318
323
|
"rimraf": "^6.1.2",
|
|
319
324
|
"tsup": "^8.5.1",
|
|
320
325
|
"tsx": "^4.21.0",
|
|
321
326
|
"typescript": "^5.9.3",
|
|
322
|
-
"typescript-eslint": "^8.
|
|
323
|
-
"vite-tsconfig-paths": "^6.0
|
|
327
|
+
"typescript-eslint": "^8.55.0",
|
|
328
|
+
"vite-tsconfig-paths": "^6.1.0",
|
|
324
329
|
"vitest": "^4.0.18",
|
|
325
330
|
"vitest-mock-extended": "^3.1.0",
|
|
326
331
|
"winston": "^3.19.0",
|
package/src/decorators.test.ts
CHANGED
|
@@ -1,47 +1,33 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import { Trace } from './decorators';
|
|
3
|
-
import { init } from './init';
|
|
4
3
|
import { configure, resetConfig } from './config';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// Attempts to fix this have been unsuccessful - spans are not exported even with
|
|
14
|
-
// proper tracer configuration, flushing, and SDK initialization delays.
|
|
15
|
-
// Root cause: Decorator metadata/metadata reflection may not work correctly in the
|
|
16
|
-
// test environment's transpilation pipeline, preventing spans from being created/exported.
|
|
17
|
-
describe.skip('Decorators', () => {
|
|
4
|
+
import { trace as otelTrace, SpanStatusCode } from '@opentelemetry/api';
|
|
5
|
+
import {
|
|
6
|
+
BasicTracerProvider,
|
|
7
|
+
InMemorySpanExporter,
|
|
8
|
+
SimpleSpanProcessor,
|
|
9
|
+
} from '@opentelemetry/sdk-trace-base';
|
|
10
|
+
|
|
11
|
+
describe('Decorators', () => {
|
|
18
12
|
let exporter: InMemorySpanExporter;
|
|
13
|
+
let provider: BasicTracerProvider;
|
|
19
14
|
|
|
20
|
-
beforeEach(
|
|
21
|
-
// Reset config to ensure clean state
|
|
15
|
+
beforeEach(() => {
|
|
22
16
|
resetConfig();
|
|
23
17
|
|
|
24
|
-
// Clear any existing spans
|
|
25
18
|
exporter = new InMemorySpanExporter();
|
|
26
|
-
|
|
27
|
-
// Initialize with in-memory exporter for testing
|
|
28
|
-
init({
|
|
29
|
-
service: 'test-decorators',
|
|
19
|
+
provider = new BasicTracerProvider({
|
|
30
20
|
spanProcessors: [new SimpleSpanProcessor(exporter)],
|
|
31
|
-
metrics: false,
|
|
32
21
|
});
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
otelTrace.setGlobalTracerProvider(provider);
|
|
24
|
+
const tracer = provider.getTracer('test-decorators');
|
|
25
|
+
configure({ tracer });
|
|
26
|
+
});
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const tracerProvider = otelTrace.getTracerProvider();
|
|
41
|
-
const tracer = tracerProvider.getTracer('test-decorators', '1.0.0');
|
|
42
|
-
configure({
|
|
43
|
-
tracer,
|
|
44
|
-
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
exporter.reset();
|
|
30
|
+
otelTrace.setGlobalTracerProvider(undefined as any);
|
|
45
31
|
});
|
|
46
32
|
|
|
47
33
|
describe('@Trace method decorator', () => {
|
|
@@ -58,9 +44,6 @@ describe.skip('Decorators', () => {
|
|
|
58
44
|
|
|
59
45
|
expect(result).toEqual({ data: 'test' });
|
|
60
46
|
|
|
61
|
-
// Flush spans to ensure they're exported
|
|
62
|
-
await flush();
|
|
63
|
-
|
|
64
47
|
const spans = exporter.getFinishedSpans();
|
|
65
48
|
expect(spans).toHaveLength(1);
|
|
66
49
|
expect(spans[0]?.name).toBe('getData');
|
|
@@ -77,8 +60,6 @@ describe.skip('Decorators', () => {
|
|
|
77
60
|
const service = new TestService();
|
|
78
61
|
await service.processData();
|
|
79
62
|
|
|
80
|
-
await flush();
|
|
81
|
-
|
|
82
63
|
const spans = exporter.getFinishedSpans();
|
|
83
64
|
expect(spans[0]?.name).toBe('custom.operation');
|
|
84
65
|
});
|
|
@@ -94,8 +75,6 @@ describe.skip('Decorators', () => {
|
|
|
94
75
|
const service = new TestService();
|
|
95
76
|
await service.execute();
|
|
96
77
|
|
|
97
|
-
await flush();
|
|
98
|
-
|
|
99
78
|
const spans = exporter.getFinishedSpans();
|
|
100
79
|
expect(spans[0]?.name).toBe('test.method');
|
|
101
80
|
});
|
|
@@ -109,7 +88,6 @@ describe.skip('Decorators', () => {
|
|
|
109
88
|
// @ts-expect-error - Decorator type resolution issue in test environment, works in production
|
|
110
89
|
@Trace()
|
|
111
90
|
async createUser(data: { id: string }) {
|
|
112
|
-
// Access ctx via this.ctx
|
|
113
91
|
const ctx = (this as unknown as WithTraceContext).ctx;
|
|
114
92
|
if (ctx) {
|
|
115
93
|
ctx.setAttribute('user.id', data.id);
|
|
@@ -121,8 +99,6 @@ describe.skip('Decorators', () => {
|
|
|
121
99
|
const service = new TestService();
|
|
122
100
|
await service.createUser({ id: '123' });
|
|
123
101
|
|
|
124
|
-
await flush();
|
|
125
|
-
|
|
126
102
|
const spans = exporter.getFinishedSpans();
|
|
127
103
|
expect(spans[0]?.attributes['user.id']).toBe('123');
|
|
128
104
|
});
|
|
@@ -131,7 +107,6 @@ describe.skip('Decorators', () => {
|
|
|
131
107
|
class TestService {
|
|
132
108
|
@Trace()
|
|
133
109
|
async simpleMethod() {
|
|
134
|
-
// No ctx access
|
|
135
110
|
return 'result';
|
|
136
111
|
}
|
|
137
112
|
}
|
|
@@ -140,9 +115,6 @@ describe.skip('Decorators', () => {
|
|
|
140
115
|
const result = await service.simpleMethod();
|
|
141
116
|
|
|
142
117
|
expect(result).toBe('result');
|
|
143
|
-
|
|
144
|
-
await flush();
|
|
145
|
-
|
|
146
118
|
expect(exporter.getFinishedSpans()).toHaveLength(1);
|
|
147
119
|
});
|
|
148
120
|
|
|
@@ -171,33 +143,11 @@ describe.skip('Decorators', () => {
|
|
|
171
143
|
|
|
172
144
|
const service = new TestService();
|
|
173
145
|
|
|
174
|
-
|
|
175
|
-
await service.failingMethod();
|
|
176
|
-
expect.fail('Should have thrown an error');
|
|
177
|
-
} catch (error) {
|
|
178
|
-
expect(error).toBeInstanceOf(Error);
|
|
179
|
-
expect((error as Error).message).toBe('Test error');
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Wait a bit for span to be processed
|
|
183
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
184
|
-
await flush();
|
|
146
|
+
await expect(service.failingMethod()).rejects.toThrow('Test error');
|
|
185
147
|
|
|
186
148
|
const spans = exporter.getFinishedSpans();
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (spans.length === 0) {
|
|
190
|
-
// This is a known limitation - decorators may not export spans for error cases in test environment
|
|
191
|
-
// The decorators work correctly in production (compiled with tsc)
|
|
192
|
-
expect(spans.length).toBeGreaterThanOrEqual(0); // Allow this test to pass for now
|
|
193
|
-
} else {
|
|
194
|
-
expect(spans).toHaveLength(1);
|
|
195
|
-
// Check status - OpenTelemetry status has code property
|
|
196
|
-
const status = spans[0]?.status;
|
|
197
|
-
expect(status).toBeDefined();
|
|
198
|
-
// Status code 2 = ERROR in OpenTelemetry
|
|
199
|
-
expect((status as { code: number }).code).toBe(2);
|
|
200
|
-
}
|
|
149
|
+
expect(spans).toHaveLength(1);
|
|
150
|
+
expect(spans[0]?.status.code).toBe(SpanStatusCode.ERROR);
|
|
201
151
|
});
|
|
202
152
|
});
|
|
203
153
|
});
|
package/src/functional.test.ts
CHANGED
|
@@ -1025,12 +1025,7 @@ describe('Functional API', () => {
|
|
|
1025
1025
|
expect(collector.getSpans()).toHaveLength(1);
|
|
1026
1026
|
});
|
|
1027
1027
|
|
|
1028
|
-
|
|
1029
|
-
// The inner trace creates a new span that doesn't properly inherit baggage
|
|
1030
|
-
// from withBaggage() due to context storage synchronization issues.
|
|
1031
|
-
// This was a false-positive before - the inner function wasn't being called
|
|
1032
|
-
// because childCtx wasn't detected as a factory parameter.
|
|
1033
|
-
it.skip('withBaggage should set baggage for child spans', async () => {
|
|
1028
|
+
it('withBaggage should set baggage for child spans', async () => {
|
|
1034
1029
|
const collector = createTraceCollector();
|
|
1035
1030
|
|
|
1036
1031
|
await trace((ctx) => async () => {
|
|
@@ -1107,6 +1102,29 @@ describe('Functional API', () => {
|
|
|
1107
1102
|
expect(collector.getSpans()).toHaveLength(1);
|
|
1108
1103
|
});
|
|
1109
1104
|
|
|
1105
|
+
it('withBaggage should not leak baggage after callback completes', async () => {
|
|
1106
|
+
const collector = createTraceCollector();
|
|
1107
|
+
|
|
1108
|
+
await trace((ctx) => async () => {
|
|
1109
|
+
expect(ctx.getBaggage('tenant.id')).toBeUndefined();
|
|
1110
|
+
|
|
1111
|
+
await withBaggage({
|
|
1112
|
+
baggage: { 'tenant.id': 'tenant-456' },
|
|
1113
|
+
fn: async () => {
|
|
1114
|
+
expect(ctx.getBaggage('tenant.id')).toBe('tenant-456');
|
|
1115
|
+
},
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
// Child spans created after withBaggage must not inherit scoped baggage.
|
|
1119
|
+
// (Same-ctx after await may still see baggage due to async context propagation.)
|
|
1120
|
+
await trace((childCtx) => async () => {
|
|
1121
|
+
expect(childCtx.getBaggage('tenant.id')).toBeUndefined();
|
|
1122
|
+
})();
|
|
1123
|
+
})();
|
|
1124
|
+
|
|
1125
|
+
expect(collector.getSpans()).toHaveLength(2);
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1110
1128
|
it('ctx.getAllBaggage should return all baggage entries', async () => {
|
|
1111
1129
|
const collector = createTraceCollector();
|
|
1112
1130
|
const { context, propagation } = await import('@opentelemetry/api');
|