autotel 2.22.0 → 2.23.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 (126) hide show
  1. package/README.md +112 -6
  2. package/bin/intent.js +6 -0
  3. package/dist/auto.cjs +3 -3
  4. package/dist/auto.js +2 -2
  5. package/dist/{chunk-EWH2542B.js → chunk-3AMR5XLZ.js} +3 -3
  6. package/dist/{chunk-EWH2542B.js.map → chunk-3AMR5XLZ.js.map} +1 -1
  7. package/dist/chunk-3QXBFGKP.js +344 -0
  8. package/dist/chunk-3QXBFGKP.js.map +1 -0
  9. package/dist/{chunk-VQFF2WMP.cjs → chunk-3ZFDJJWZ.cjs} +37 -29
  10. package/dist/chunk-3ZFDJJWZ.cjs.map +1 -0
  11. package/dist/{chunk-CQC6RVLR.cjs → chunk-4RZ4JUBY.cjs} +5 -5
  12. package/dist/{chunk-CQC6RVLR.cjs.map → chunk-4RZ4JUBY.cjs.map} +1 -1
  13. package/dist/{chunk-PAVYKPCQ.js → chunk-5XUEHX7J.js} +3 -3
  14. package/dist/{chunk-PAVYKPCQ.js.map → chunk-5XUEHX7J.js.map} +1 -1
  15. package/dist/chunk-6S5RUKU3.cjs +347 -0
  16. package/dist/chunk-6S5RUKU3.cjs.map +1 -0
  17. package/dist/{chunk-BS757SL2.js → chunk-724XLWR3.js} +9 -4
  18. package/dist/chunk-724XLWR3.js.map +1 -0
  19. package/dist/chunk-7EQ4G4SI.cjs +146 -0
  20. package/dist/chunk-7EQ4G4SI.cjs.map +1 -0
  21. package/dist/{chunk-CQP5SQT4.cjs → chunk-AXFWWJF3.cjs} +7 -7
  22. package/dist/{chunk-CQP5SQT4.cjs.map → chunk-AXFWWJF3.cjs.map} +1 -1
  23. package/dist/{chunk-7NH625MS.cjs → chunk-BSZP4URK.cjs} +5 -5
  24. package/dist/{chunk-7NH625MS.cjs.map → chunk-BSZP4URK.cjs.map} +1 -1
  25. package/dist/{chunk-GZFH6P5U.js → chunk-GY4CRZSV.js} +14 -6
  26. package/dist/chunk-GY4CRZSV.js.map +1 -0
  27. package/dist/{chunk-QKUGUDXJ.cjs → chunk-HSEIUH7F.cjs} +10 -5
  28. package/dist/chunk-HSEIUH7F.cjs.map +1 -0
  29. package/dist/{chunk-DTW3WB7Z.js → chunk-IPKXURBW.js} +3 -3
  30. package/dist/{chunk-DTW3WB7Z.js.map → chunk-IPKXURBW.js.map} +1 -1
  31. package/dist/chunk-J7VGRIAJ.js +64 -0
  32. package/dist/chunk-J7VGRIAJ.js.map +1 -0
  33. package/dist/chunk-KFOHQK7X.js +144 -0
  34. package/dist/chunk-KFOHQK7X.js.map +1 -0
  35. package/dist/{chunk-4UYR46UP.cjs → chunk-MSUHW2I4.cjs} +13 -13
  36. package/dist/{chunk-4UYR46UP.cjs.map → chunk-MSUHW2I4.cjs.map} +1 -1
  37. package/dist/chunk-T4B5LB6E.cjs +66 -0
  38. package/dist/chunk-T4B5LB6E.cjs.map +1 -0
  39. package/dist/{chunk-QHT4MUED.js → chunk-WCIIFRGL.js} +3 -3
  40. package/dist/{chunk-QHT4MUED.js.map → chunk-WCIIFRGL.js.map} +1 -1
  41. package/dist/decorators.cjs +3 -3
  42. package/dist/decorators.js +3 -3
  43. package/dist/drain-pipeline.cjs +13 -0
  44. package/dist/drain-pipeline.cjs.map +1 -0
  45. package/dist/drain-pipeline.d.cts +37 -0
  46. package/dist/drain-pipeline.d.ts +37 -0
  47. package/dist/drain-pipeline.js +4 -0
  48. package/dist/drain-pipeline.js.map +1 -0
  49. package/dist/enrichers.cjs +90 -0
  50. package/dist/enrichers.cjs.map +1 -0
  51. package/dist/enrichers.d.cts +23 -0
  52. package/dist/enrichers.d.ts +23 -0
  53. package/dist/enrichers.js +86 -0
  54. package/dist/enrichers.js.map +1 -0
  55. package/dist/event.cjs +6 -6
  56. package/dist/event.js +3 -3
  57. package/dist/functional.cjs +10 -10
  58. package/dist/functional.js +3 -3
  59. package/dist/index.cjs +274 -41
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +73 -3
  62. package/dist/index.d.ts +73 -3
  63. package/dist/index.js +227 -11
  64. package/dist/index.js.map +1 -1
  65. package/dist/{init-BMiXSJNM.d.cts → init-BC5aN8bh.d.cts} +18 -0
  66. package/dist/{init-ByRbNTRo.d.ts → init-_FG4IbhF.d.ts} +18 -0
  67. package/dist/instrumentation.cjs +9 -9
  68. package/dist/instrumentation.js +2 -2
  69. package/dist/messaging.cjs +7 -7
  70. package/dist/messaging.js +4 -4
  71. package/dist/parse-error.cjs +13 -0
  72. package/dist/parse-error.cjs.map +1 -0
  73. package/dist/parse-error.d.cts +13 -0
  74. package/dist/parse-error.d.ts +13 -0
  75. package/dist/parse-error.js +4 -0
  76. package/dist/parse-error.js.map +1 -0
  77. package/dist/processors.cjs +2 -2
  78. package/dist/processors.d.cts +40 -4
  79. package/dist/processors.d.ts +40 -4
  80. package/dist/processors.js +1 -1
  81. package/dist/semantic-helpers.cjs +8 -8
  82. package/dist/semantic-helpers.js +4 -4
  83. package/dist/webhook.cjs +4 -4
  84. package/dist/webhook.js +3 -3
  85. package/dist/workflow-distributed.cjs +5 -5
  86. package/dist/workflow-distributed.js +3 -3
  87. package/dist/workflow.cjs +8 -8
  88. package/dist/workflow.js +4 -4
  89. package/dist/yaml-config.d.cts +2 -1
  90. package/dist/yaml-config.d.ts +2 -1
  91. package/package.json +55 -33
  92. package/skills/autotel-core/SKILL.md +162 -0
  93. package/skills/autotel-events/SKILL.md +88 -0
  94. package/skills/autotel-frameworks/SKILL.md +97 -0
  95. package/skills/autotel-instrumentation/SKILL.md +125 -0
  96. package/skills/autotel-request-logging/SKILL.md +100 -0
  97. package/skills/autotel-structured-errors/SKILL.md +130 -0
  98. package/src/drain-pipeline.test.ts +68 -0
  99. package/src/drain-pipeline.ts +199 -0
  100. package/src/enrichers.test.ts +150 -0
  101. package/src/enrichers.ts +145 -0
  102. package/src/flatten-attributes.test.ts +76 -0
  103. package/src/flatten-attributes.ts +80 -0
  104. package/src/functional.test.ts +63 -0
  105. package/src/functional.ts +11 -3
  106. package/src/index.ts +34 -0
  107. package/src/init.ts +22 -0
  108. package/src/package-manifest.test.ts +24 -0
  109. package/src/parse-error.test.ts +73 -0
  110. package/src/parse-error.ts +112 -0
  111. package/src/pretty-log-formatter.test.ts +123 -0
  112. package/src/pretty-log-formatter.ts +210 -0
  113. package/src/processors/canonical-log-line-processor.test.ts +81 -25
  114. package/src/processors/canonical-log-line-processor.ts +130 -42
  115. package/src/request-logger.test.ts +137 -0
  116. package/src/request-logger.ts +150 -0
  117. package/src/structured-error.test.ts +106 -0
  118. package/src/structured-error.ts +97 -0
  119. package/dist/chunk-2RQDNGV3.js +0 -126
  120. package/dist/chunk-2RQDNGV3.js.map +0 -1
  121. package/dist/chunk-BS757SL2.js.map +0 -1
  122. package/dist/chunk-GZFH6P5U.js.map +0 -1
  123. package/dist/chunk-ONK2Y22L.cjs +0 -128
  124. package/dist/chunk-ONK2Y22L.cjs.map +0 -1
  125. package/dist/chunk-QKUGUDXJ.cjs.map +0 -1
  126. package/dist/chunk-VQFF2WMP.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shutdown.ts"],"names":["getEventQueue","getSdk","getLogger","resetEvents","resetMetrics","resetEventQueue"],"mappings":"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","file":"index.cjs","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","../src/flatten-attributes.ts","../src/structured-error.ts","../src/request-logger.ts"],"names":["getEventQueue","getSdk","getLogger","resetEvents","resetMetrics","resetEventQueue","ctx","SpanStatusCode","AsyncLocalStorage","span","otelTrace","createTraceContext","attrs"],"mappings":"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","file":"index.cjs","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","import type { AttributeValue } from './trace-context';\n\n/**\n * Convert an unknown value to an OTel-compatible AttributeValue.\n * Returns undefined when the value cannot be represented.\n */\nexport function toAttributeValue(value: unknown): AttributeValue | undefined {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return value;\n }\n if (Array.isArray(value)) {\n if (\n value.every((v) => typeof v === 'string') ||\n value.every((v) => typeof v === 'number') ||\n value.every((v) => typeof v === 'boolean')\n ) {\n return value as AttributeValue;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '<serialization-failed>';\n }\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (value instanceof Error) {\n return value.message;\n }\n return undefined;\n}\n\n/**\n * Recursively flatten a nested object into dot-notation OTel attributes.\n * Includes circular reference protection via WeakSet.\n */\nexport function flattenToAttributes(\n fields: Record<string, unknown>,\n prefix = '',\n): Record<string, AttributeValue> {\n const out: Record<string, AttributeValue> = {};\n const seen = new WeakSet<object>();\n\n function flatten(obj: Record<string, unknown>, currentPrefix: string): void {\n for (const [key, value] of Object.entries(obj)) {\n if (value == null) continue;\n const nextKey = currentPrefix ? `${currentPrefix}.${key}` : key;\n\n const attr = toAttributeValue(value);\n if (attr !== undefined) {\n out[nextKey] = attr;\n continue;\n }\n\n if (typeof value === 'object' && value.constructor === Object) {\n if (seen.has(value)) {\n out[nextKey] = '<circular-reference>';\n continue;\n }\n seen.add(value);\n flatten(value as Record<string, unknown>, nextKey);\n continue;\n }\n\n try {\n out[nextKey] = JSON.stringify(value);\n } catch {\n out[nextKey] = '<serialization-failed>';\n }\n }\n }\n\n flatten(fields, prefix);\n return out;\n}\n","import { SpanStatusCode } from '@opentelemetry/api';\nimport type { AttributeValue, TraceContext } from './trace-context';\nimport { flattenToAttributes } from './flatten-attributes';\n\nexport interface StructuredErrorInput {\n message: string;\n why?: string;\n fix?: string;\n link?: string;\n code?: string | number;\n status?: number;\n cause?: unknown;\n details?: Record<string, unknown>;\n name?: string;\n}\n\nexport interface StructuredError extends Error {\n why?: string;\n fix?: string;\n link?: string;\n code?: string | number;\n status?: number;\n details?: Record<string, unknown>;\n}\n\nexport function createStructuredError(\n input: StructuredErrorInput,\n): StructuredError {\n const error = new Error(input.message, {\n cause: input.cause,\n }) as StructuredError;\n\n error.name = input.name ?? 'StructuredError';\n if (input.why !== undefined) error.why = input.why;\n if (input.fix !== undefined) error.fix = input.fix;\n if (input.link !== undefined) error.link = input.link;\n if (input.code !== undefined) error.code = input.code;\n if (input.status !== undefined) error.status = input.status;\n if (input.details !== undefined) error.details = input.details;\n\n error.toString = () => {\n const lines = [`${error.name}: ${error.message}`];\n if (error.why) lines.push(` Why: ${error.why}`);\n if (error.fix) lines.push(` Fix: ${error.fix}`);\n if (error.link) lines.push(` Link: ${error.link}`);\n if (error.code !== undefined) lines.push(` Code: ${error.code}`);\n if (error.status !== undefined) lines.push(` Status: ${error.status}`);\n if (error.cause) lines.push(` Caused by: ${error.cause}`);\n return lines.join('\\n');\n };\n\n return error;\n}\n\nexport function getStructuredErrorAttributes(\n error: Error,\n): Record<string, AttributeValue> {\n const structured = error as StructuredError;\n const attributes: Record<string, AttributeValue> = {\n 'error.type': error.name || 'Error',\n 'error.message': error.message,\n };\n\n if (error.stack) attributes['error.stack'] = error.stack;\n if (structured.why) attributes['error.why'] = structured.why;\n if (structured.fix) attributes['error.fix'] = structured.fix;\n if (structured.link) attributes['error.link'] = structured.link;\n if (structured.code !== undefined) {\n attributes['error.code'] =\n typeof structured.code === 'string'\n ? structured.code\n : String(structured.code);\n }\n if (structured.status !== undefined) {\n attributes['error.status'] = structured.status;\n }\n if (structured.details) {\n Object.assign(\n attributes,\n flattenToAttributes(structured.details, 'error.details'),\n );\n }\n\n return attributes;\n}\n\nexport function recordStructuredError(\n ctx: Pick<TraceContext, 'recordException' | 'setAttributes' | 'setStatus'>,\n error: Error,\n): void {\n ctx.recordException(error);\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n });\n ctx.setAttributes(getStructuredErrorAttributes(error));\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { trace as otelTrace } from '@opentelemetry/api';\nimport type { TraceContext } from './trace-context';\nimport { createTraceContext } from './trace-context';\nimport { recordStructuredError } from './structured-error';\nimport { flattenToAttributes } from './flatten-attributes';\n\nconst requestContextStore = new AsyncLocalStorage<TraceContext>();\n\nexport function runWithRequestContext<T>(ctx: TraceContext, fn: () => T): T {\n return requestContextStore.run(ctx, fn);\n}\n\nexport interface RequestLogger {\n set(fields: Record<string, unknown>): void;\n info(message: string, fields?: Record<string, unknown>): void;\n warn(message: string, fields?: Record<string, unknown>): void;\n error(error: Error | string, fields?: Record<string, unknown>): void;\n getContext(): Record<string, unknown>;\n emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot;\n}\n\nexport interface RequestLogSnapshot {\n timestamp: string;\n traceId: string;\n spanId: string;\n correlationId: string;\n context: Record<string, unknown>;\n}\n\nexport interface RequestLoggerOptions {\n /** Callback invoked by emitNow() for manual fan-out. */\n onEmit?: (snapshot: RequestLogSnapshot) => void | Promise<void>;\n}\n\nfunction resolveContext(ctx?: TraceContext): TraceContext {\n if (ctx) return ctx;\n\n const stored = requestContextStore.getStore();\n if (stored) return stored;\n\n const span = otelTrace.getActiveSpan();\n if (!span) {\n throw new Error(\n '[autotel] getRequestLogger() requires an active span or runWithRequestContext(). Wrap your handler with trace() or use runWithRequestContext().',\n );\n }\n return createTraceContext(span);\n}\n\nexport function getRequestLogger(\n ctx?: TraceContext,\n options?: RequestLoggerOptions,\n): RequestLogger {\n const activeContext = resolveContext(ctx);\n let contextState: Record<string, unknown> = {};\n\n const addLogEvent = (\n level: 'info' | 'warn' | 'error',\n message: string,\n fields?: Record<string, unknown>,\n ) => {\n const attrs = fields ? flattenToAttributes(fields) : undefined;\n activeContext.addEvent(`log.${level}`, {\n message,\n ...attrs,\n });\n };\n\n return {\n set(fields: Record<string, unknown>) {\n contextState = {\n ...contextState,\n ...fields,\n };\n activeContext.setAttributes(flattenToAttributes(fields));\n },\n\n info(message: string, fields?: Record<string, unknown>) {\n addLogEvent('info', message, fields);\n if (fields) {\n contextState = {\n ...contextState,\n ...fields,\n };\n activeContext.setAttributes(flattenToAttributes(fields));\n }\n },\n\n warn(message: string, fields?: Record<string, unknown>) {\n addLogEvent('warn', message, fields);\n activeContext.setAttribute('autotel.log.level', 'warn');\n if (fields) {\n contextState = {\n ...contextState,\n ...fields,\n };\n activeContext.setAttributes(flattenToAttributes(fields));\n }\n },\n\n error(error: Error | string, fields?: Record<string, unknown>) {\n const err = typeof error === 'string' ? new Error(error) : error;\n recordStructuredError(activeContext, err);\n addLogEvent('error', err.message, fields);\n\n if (fields) {\n contextState = {\n ...contextState,\n ...fields,\n };\n activeContext.setAttributes(flattenToAttributes(fields));\n }\n activeContext.setAttribute('autotel.log.level', 'error');\n },\n\n getContext() {\n return { ...contextState };\n },\n\n emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot {\n const mergedContext = {\n ...contextState,\n ...(overrides ?? {}),\n };\n const flattened = flattenToAttributes(mergedContext);\n activeContext.setAttributes(flattened);\n\n const snapshot: RequestLogSnapshot = {\n timestamp: new Date().toISOString(),\n traceId: activeContext.traceId,\n spanId: activeContext.spanId,\n correlationId: activeContext.correlationId,\n context: mergedContext,\n };\n\n activeContext.addEvent('log.emit.manual', {\n ...flattened,\n });\n\n if (options?.onEmit) {\n Promise.resolve(options.onEmit(snapshot)).catch((error) => {\n console.warn('[autotel] request logger onEmit failed:', error);\n });\n }\n\n return snapshot;\n },\n };\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AutotelConfig, i as init } from './init-BMiXSJNM.cjs';
1
+ export { A as AutotelConfig, i as init } from './init-BC5aN8bh.cjs';
2
2
  import { Span, Context } from '@opentelemetry/api';
3
3
  export { Context, ROOT_CONTEXT, Span, SpanContext, SpanKind, Link as SpanLink, SpanStatusCode, TextMapGetter, TextMapSetter, Tracer, context, trace as otelTrace, propagation } from '@opentelemetry/api';
4
4
  import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
@@ -9,6 +9,10 @@ export { InstrumentOptions, SpanOptions, WithBaggageOptions, WithNewContextOptio
9
9
  import { EventSubscriber, EventAttributes, AutotelEventContext } from './event-subscriber.cjs';
10
10
  export { FunnelStatus, OutcomeStatus } from './event-subscriber.cjs';
11
11
  export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage } from './correlation-id.cjs';
12
+ import { T as TraceContext, A as AttributeValue } from './trace-context-t5X1AP-e.cjs';
13
+ export { d as defineBaggageSchema } from './trace-context-t5X1AP-e.cjs';
14
+ export { ParsedError, parseError } from './parse-error.cjs';
15
+ export { DrainPipelineOptions, PipelineDrainFn, createDrainPipeline } from './drain-pipeline.cjs';
12
16
  export { AdaptiveSampler, AlwaysSampler, NeverSampler, RandomSampler, Sampler, SamplingContext, UserIdSampler, createLinkFromHeaders, extractLinksFromBatch } from './sampling.cjs';
13
17
  export { Event, EventsOptions, getEvents, resetEvents } from './event.cjs';
14
18
  export { Metric, MetricsOptions, getMetrics, resetMetrics } from './metric.cjs';
@@ -18,7 +22,6 @@ export { getAutotelTracer, getAutotelTracerProvider, setAutotelTracerProvider }
18
22
  export { DBConfig, HTTPConfig, LLMConfig, MessagingConfig, traceDB, traceHTTP, traceLLM, traceMessaging } from './semantic-helpers.cjs';
19
23
  export { HTTPAttributes, ServiceAttributes, URLAttributes, httpRequestHeaderAttribute, httpResponseHeaderAttribute } from './semantic-conventions.cjs';
20
24
  export { p as AttributeGuardrails, A as AttributePolicy, J as ClientAttrs, C as CloudAttrs, Q as CodeAttrs, z as ContainerAttrs, t as DBAttrs, L as DeploymentAttrs, D as DeviceAttrs, E as ErrorAttrs, V as ExceptionAttrs, B as FaaSAttrs, F as FeatureFlagAttrs, G as GenAIAttrs, I as GraphQLAttrs, q as HTTPClientAttrs, H as HTTPServerAttrs, K as K8sAttrs, M as MessagingAttrs, N as NetworkAttrs, O as OTelAttrs, P as PeerAttrs, y as ProcessAttrs, R as RPCAttrs, w as ServerAddressAttrs, u as ServiceAttrs, S as SessionAttrs, W as TLSAttrs, T as ThreadAttrs, x as URLAttrs, U as UserAttrs, a as attrs, n as autoRedactPII, e as dbClient, d as httpClient, h as httpServer, i as identify, j as mergeAttrs, m as mergeServiceResource, r as request, k as safeSetAttributes, c as setDevice, f as setError, g as setException, b as setSession, s as setUser, v as validateAttribute } from './utils-DuNJfXSH.cjs';
21
- export { T as TraceContext, d as defineBaggageSchema } from './trace-context-t5X1AP-e.cjs';
22
25
  export { ConsumerConfig, ConsumerContext, LagMetricsConfig, MessagingOperation, MessagingSystem, ProducerConfig, ProducerContext, traceConsumer, traceProducer } from './messaging.cjs';
23
26
  export { BaggageError, BaggageFieldDefinition, BaggageFieldType, BusinessBaggage, BusinessBaggageValues, SafeBaggageOptions, SafeBaggageSchema, createSafeBaggageSchema } from './business-baggage.cjs';
24
27
  export { StepConfig, StepContext, StepStatus, WorkflowConfig, WorkflowContext, WorkflowStatus, getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './workflow.cjs';
@@ -28,6 +31,7 @@ import './logger.cjs';
28
31
  import 'pino';
29
32
  import '@opentelemetry/sdk-metrics';
30
33
  import '@opentelemetry/sdk-logs';
34
+ import './processors.cjs';
31
35
  import 'node:async_hooks';
32
36
  import './event-testing.cjs';
33
37
  import './metric-testing.cjs';
@@ -410,4 +414,70 @@ declare function flush(options?: {
410
414
  */
411
415
  declare function shutdown(): Promise<void>;
412
416
 
413
- export { BaggageSpanProcessor, type BaggageSpanProcessorOptions, EventAttributes, EventSubscriber, type OperationContext, flush, getEventQueue, getOperationContext, runInOperationContext, shutdown, track };
417
+ declare function runWithRequestContext<T>(ctx: TraceContext, fn: () => T): T;
418
+ interface RequestLogger {
419
+ set(fields: Record<string, unknown>): void;
420
+ info(message: string, fields?: Record<string, unknown>): void;
421
+ warn(message: string, fields?: Record<string, unknown>): void;
422
+ error(error: Error | string, fields?: Record<string, unknown>): void;
423
+ getContext(): Record<string, unknown>;
424
+ emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot;
425
+ }
426
+ interface RequestLogSnapshot {
427
+ timestamp: string;
428
+ traceId: string;
429
+ spanId: string;
430
+ correlationId: string;
431
+ context: Record<string, unknown>;
432
+ }
433
+ interface RequestLoggerOptions {
434
+ /** Callback invoked by emitNow() for manual fan-out. */
435
+ onEmit?: (snapshot: RequestLogSnapshot) => void | Promise<void>;
436
+ }
437
+ declare function getRequestLogger(ctx?: TraceContext, options?: RequestLoggerOptions): RequestLogger;
438
+
439
+ interface StructuredErrorInput {
440
+ message: string;
441
+ why?: string;
442
+ fix?: string;
443
+ link?: string;
444
+ code?: string | number;
445
+ status?: number;
446
+ cause?: unknown;
447
+ details?: Record<string, unknown>;
448
+ name?: string;
449
+ }
450
+ interface StructuredError extends Error {
451
+ why?: string;
452
+ fix?: string;
453
+ link?: string;
454
+ code?: string | number;
455
+ status?: number;
456
+ details?: Record<string, unknown>;
457
+ }
458
+ declare function createStructuredError(input: StructuredErrorInput): StructuredError;
459
+ declare function getStructuredErrorAttributes(error: Error): Record<string, AttributeValue>;
460
+ declare function recordStructuredError(ctx: Pick<TraceContext, 'recordException' | 'setAttributes' | 'setStatus'>, error: Error): void;
461
+
462
+ /**
463
+ * Convert an unknown value to an OTel-compatible AttributeValue.
464
+ * Returns undefined when the value cannot be represented.
465
+ */
466
+ declare function toAttributeValue(value: unknown): AttributeValue | undefined;
467
+ /**
468
+ * Recursively flatten a nested object into dot-notation OTel attributes.
469
+ * Includes circular reference protection via WeakSet.
470
+ */
471
+ declare function flattenToAttributes(fields: Record<string, unknown>, prefix?: string): Record<string, AttributeValue>;
472
+
473
+ /**
474
+ * Format milliseconds into a human-readable duration string.
475
+ *
476
+ * @example
477
+ * formatDuration(45) // "45ms"
478
+ * formatDuration(1234) // "1.2s"
479
+ * formatDuration(65000) // "1m 5s"
480
+ */
481
+ declare function formatDuration(ms: number): string;
482
+
483
+ export { BaggageSpanProcessor, type BaggageSpanProcessorOptions, EventAttributes, EventSubscriber, type OperationContext, type RequestLogSnapshot, type RequestLogger, type RequestLoggerOptions, type StructuredError, type StructuredErrorInput, TraceContext, createStructuredError, flattenToAttributes, flush, formatDuration, getEventQueue, getOperationContext, getRequestLogger, getStructuredErrorAttributes, recordStructuredError, runInOperationContext, runWithRequestContext, shutdown, toAttributeValue, track };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AutotelConfig, i as init } from './init-ByRbNTRo.js';
1
+ export { A as AutotelConfig, i as init } from './init-_FG4IbhF.js';
2
2
  import { Span, Context } from '@opentelemetry/api';
3
3
  export { Context, ROOT_CONTEXT, Span, SpanContext, SpanKind, Link as SpanLink, SpanStatusCode, TextMapGetter, TextMapSetter, Tracer, context, trace as otelTrace, propagation } from '@opentelemetry/api';
4
4
  import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
@@ -9,6 +9,10 @@ export { InstrumentOptions, SpanOptions, WithBaggageOptions, WithNewContextOptio
9
9
  import { EventSubscriber, EventAttributes, AutotelEventContext } from './event-subscriber.js';
10
10
  export { FunnelStatus, OutcomeStatus } from './event-subscriber.js';
11
11
  export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage } from './correlation-id.js';
12
+ import { T as TraceContext, A as AttributeValue } from './trace-context-t5X1AP-e.js';
13
+ export { d as defineBaggageSchema } from './trace-context-t5X1AP-e.js';
14
+ export { ParsedError, parseError } from './parse-error.js';
15
+ export { DrainPipelineOptions, PipelineDrainFn, createDrainPipeline } from './drain-pipeline.js';
12
16
  export { AdaptiveSampler, AlwaysSampler, NeverSampler, RandomSampler, Sampler, SamplingContext, UserIdSampler, createLinkFromHeaders, extractLinksFromBatch } from './sampling.js';
13
17
  export { Event, EventsOptions, getEvents, resetEvents } from './event.js';
14
18
  export { Metric, MetricsOptions, getMetrics, resetMetrics } from './metric.js';
@@ -18,7 +22,6 @@ export { getAutotelTracer, getAutotelTracerProvider, setAutotelTracerProvider }
18
22
  export { DBConfig, HTTPConfig, LLMConfig, MessagingConfig, traceDB, traceHTTP, traceLLM, traceMessaging } from './semantic-helpers.js';
19
23
  export { HTTPAttributes, ServiceAttributes, URLAttributes, httpRequestHeaderAttribute, httpResponseHeaderAttribute } from './semantic-conventions.js';
20
24
  export { p as AttributeGuardrails, A as AttributePolicy, J as ClientAttrs, C as CloudAttrs, Q as CodeAttrs, z as ContainerAttrs, t as DBAttrs, L as DeploymentAttrs, D as DeviceAttrs, E as ErrorAttrs, V as ExceptionAttrs, B as FaaSAttrs, F as FeatureFlagAttrs, G as GenAIAttrs, I as GraphQLAttrs, q as HTTPClientAttrs, H as HTTPServerAttrs, K as K8sAttrs, M as MessagingAttrs, N as NetworkAttrs, O as OTelAttrs, P as PeerAttrs, y as ProcessAttrs, R as RPCAttrs, w as ServerAddressAttrs, u as ServiceAttrs, S as SessionAttrs, W as TLSAttrs, T as ThreadAttrs, x as URLAttrs, U as UserAttrs, a as attrs, n as autoRedactPII, e as dbClient, d as httpClient, h as httpServer, i as identify, j as mergeAttrs, m as mergeServiceResource, r as request, k as safeSetAttributes, c as setDevice, f as setError, g as setException, b as setSession, s as setUser, v as validateAttribute } from './utils-D1trOLNm.js';
21
- export { T as TraceContext, d as defineBaggageSchema } from './trace-context-t5X1AP-e.js';
22
25
  export { ConsumerConfig, ConsumerContext, LagMetricsConfig, MessagingOperation, MessagingSystem, ProducerConfig, ProducerContext, traceConsumer, traceProducer } from './messaging.js';
23
26
  export { BaggageError, BaggageFieldDefinition, BaggageFieldType, BusinessBaggage, BusinessBaggageValues, SafeBaggageOptions, SafeBaggageSchema, createSafeBaggageSchema } from './business-baggage.js';
24
27
  export { StepConfig, StepContext, StepStatus, WorkflowConfig, WorkflowContext, WorkflowStatus, getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './workflow.js';
@@ -28,6 +31,7 @@ import './logger.js';
28
31
  import 'pino';
29
32
  import '@opentelemetry/sdk-metrics';
30
33
  import '@opentelemetry/sdk-logs';
34
+ import './processors.js';
31
35
  import 'node:async_hooks';
32
36
  import './event-testing.js';
33
37
  import './metric-testing.js';
@@ -410,4 +414,70 @@ declare function flush(options?: {
410
414
  */
411
415
  declare function shutdown(): Promise<void>;
412
416
 
413
- export { BaggageSpanProcessor, type BaggageSpanProcessorOptions, EventAttributes, EventSubscriber, type OperationContext, flush, getEventQueue, getOperationContext, runInOperationContext, shutdown, track };
417
+ declare function runWithRequestContext<T>(ctx: TraceContext, fn: () => T): T;
418
+ interface RequestLogger {
419
+ set(fields: Record<string, unknown>): void;
420
+ info(message: string, fields?: Record<string, unknown>): void;
421
+ warn(message: string, fields?: Record<string, unknown>): void;
422
+ error(error: Error | string, fields?: Record<string, unknown>): void;
423
+ getContext(): Record<string, unknown>;
424
+ emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot;
425
+ }
426
+ interface RequestLogSnapshot {
427
+ timestamp: string;
428
+ traceId: string;
429
+ spanId: string;
430
+ correlationId: string;
431
+ context: Record<string, unknown>;
432
+ }
433
+ interface RequestLoggerOptions {
434
+ /** Callback invoked by emitNow() for manual fan-out. */
435
+ onEmit?: (snapshot: RequestLogSnapshot) => void | Promise<void>;
436
+ }
437
+ declare function getRequestLogger(ctx?: TraceContext, options?: RequestLoggerOptions): RequestLogger;
438
+
439
+ interface StructuredErrorInput {
440
+ message: string;
441
+ why?: string;
442
+ fix?: string;
443
+ link?: string;
444
+ code?: string | number;
445
+ status?: number;
446
+ cause?: unknown;
447
+ details?: Record<string, unknown>;
448
+ name?: string;
449
+ }
450
+ interface StructuredError extends Error {
451
+ why?: string;
452
+ fix?: string;
453
+ link?: string;
454
+ code?: string | number;
455
+ status?: number;
456
+ details?: Record<string, unknown>;
457
+ }
458
+ declare function createStructuredError(input: StructuredErrorInput): StructuredError;
459
+ declare function getStructuredErrorAttributes(error: Error): Record<string, AttributeValue>;
460
+ declare function recordStructuredError(ctx: Pick<TraceContext, 'recordException' | 'setAttributes' | 'setStatus'>, error: Error): void;
461
+
462
+ /**
463
+ * Convert an unknown value to an OTel-compatible AttributeValue.
464
+ * Returns undefined when the value cannot be represented.
465
+ */
466
+ declare function toAttributeValue(value: unknown): AttributeValue | undefined;
467
+ /**
468
+ * Recursively flatten a nested object into dot-notation OTel attributes.
469
+ * Includes circular reference protection via WeakSet.
470
+ */
471
+ declare function flattenToAttributes(fields: Record<string, unknown>, prefix?: string): Record<string, AttributeValue>;
472
+
473
+ /**
474
+ * Format milliseconds into a human-readable duration string.
475
+ *
476
+ * @example
477
+ * formatDuration(45) // "45ms"
478
+ * formatDuration(1234) // "1.2s"
479
+ * formatDuration(65000) // "1m 5s"
480
+ */
481
+ declare function formatDuration(ms: number): string;
482
+
483
+ export { BaggageSpanProcessor, type BaggageSpanProcessorOptions, EventAttributes, EventSubscriber, type OperationContext, type RequestLogSnapshot, type RequestLogger, type RequestLoggerOptions, type StructuredError, type StructuredErrorInput, TraceContext, createStructuredError, flattenToAttributes, flush, formatDuration, getEventQueue, getOperationContext, getRequestLogger, getStructuredErrorAttributes, recordStructuredError, runInOperationContext, runWithRequestContext, shutdown, toAttributeValue, track };
package/dist/index.js CHANGED
@@ -1,39 +1,44 @@
1
- export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-QHT4MUED.js';
1
+ export { createDrainPipeline } from './chunk-KFOHQK7X.js';
2
+ export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-WCIIFRGL.js';
2
3
  export { attrs, autoRedactPII, dbClient, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, validateAttribute } from './chunk-M4US3P4K.js';
3
4
  export { httpRequestHeaderAttribute, httpResponseHeaderAttribute } from './chunk-7552UTQW.js';
4
5
  export { HTTPAttributes, ServiceAttributes, URLAttributes } from './chunk-4A53YIAX.js';
5
- export { traceConsumer, traceProducer } from './chunk-EWH2542B.js';
6
+ export { parseError } from './chunk-J7VGRIAJ.js';
7
+ export { traceConsumer, traceProducer } from './chunk-3AMR5XLZ.js';
6
8
  export { BusinessBaggage, createSafeBaggageSchema } from './chunk-4IFSYQVX.js';
7
9
  import { resetMetrics } from './chunk-7SAWIN74.js';
8
10
  export { Metric, getMetrics, resetMetrics } from './chunk-7SAWIN74.js';
9
11
  import './chunk-5ZN622AO.js';
10
12
  export { createCounter, createHistogram, createObservableGauge, createUpDownCounter, getMeter } from './chunk-TQ5UWA7S.js';
11
- export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-DTW3WB7Z.js';
12
- import { getEventQueue, resetEventQueue } from './chunk-GZFH6P5U.js';
13
- export { ctx, getEventQueue, instrument, span, trace, track, withBaggage, withNewContext, withTracing } from './chunk-GZFH6P5U.js';
13
+ export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-IPKXURBW.js';
14
+ import { getEventQueue, resetEventQueue } from './chunk-GY4CRZSV.js';
15
+ export { ctx, getEventQueue, instrument, span, trace, track, withBaggage, withNewContext, withTracing } from './chunk-GY4CRZSV.js';
16
+ import { createTraceContext } from './chunk-SR35DG5A.js';
14
17
  export { defineBaggageSchema } from './chunk-SR35DG5A.js';
15
18
  export { createDeterministicTraceId, enrichWithTraceContext, finalizeSpan, flattenMetadata, getActiveContext, getActiveSpan, getTraceContext, getTracer, isTracing, resolveTraceUrl, runWithSpan } from './chunk-B3ZHLLMP.js';
16
- import { resetEvents } from './chunk-PAVYKPCQ.js';
17
- export { Event, getEvents, resetEvents } from './chunk-PAVYKPCQ.js';
19
+ import { resetEvents } from './chunk-5XUEHX7J.js';
20
+ export { Event, getEvents, resetEvents } from './chunk-5XUEHX7J.js';
18
21
  import './chunk-LITNXTTT.js';
19
22
  import './chunk-BZHG5IZ4.js';
20
23
  export { getOperationContext, runInOperationContext } from './chunk-WD4RP6IV.js';
21
24
  export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage } from './chunk-USSL3D6L.js';
22
- import { getLogger, getSdk } from './chunk-BS757SL2.js';
23
- export { BaggageSpanProcessor, init } from './chunk-BS757SL2.js';
25
+ import { getLogger, getSdk } from './chunk-724XLWR3.js';
26
+ export { BaggageSpanProcessor, init } from './chunk-724XLWR3.js';
24
27
  import './chunk-YTGF4L2C.js';
25
28
  import './chunk-X4RMFFMR.js';
26
29
  export { FilteringSpanProcessor } from './chunk-WGWSHJ2N.js';
27
30
  export { NORMALIZER_PATTERNS, NORMALIZER_PRESETS, SpanNameNormalizingProcessor } from './chunk-GYR5K654.js';
28
31
  export { AttributeRedactingProcessor, REDACTOR_PATTERNS, REDACTOR_PRESETS, createRedactedSpan } from './chunk-SNINLBEE.js';
29
32
  import './chunk-6UQRVUN3.js';
30
- import './chunk-2RQDNGV3.js';
33
+ export { formatDuration } from './chunk-3QXBFGKP.js';
31
34
  import './chunk-33WTKH7X.js';
32
35
  export { AdaptiveSampler, AlwaysSampler, NeverSampler, RandomSampler, UserIdSampler, createLinkFromHeaders, extractLinksFromBatch } from './chunk-XND7WBVX.js';
33
36
  import './chunk-B33XPEKY.js';
34
37
  import './chunk-J5QENANM.js';
35
38
  export { getAutotelTracer, getAutotelTracerProvider, setAutotelTracerProvider } from './chunk-HA2WBOGQ.js';
36
39
  import './chunk-DGUM43GV.js';
40
+ import { AsyncLocalStorage } from 'async_hooks';
41
+ import { SpanStatusCode, trace } from '@opentelemetry/api';
37
42
  export { ROOT_CONTEXT, SpanKind, SpanStatusCode, context, trace as otelTrace, propagation } from '@opentelemetry/api';
38
43
 
39
44
  // src/shutdown.ts
@@ -166,6 +171,217 @@ function registerShutdownHooks() {
166
171
  }
167
172
  registerShutdownHooks();
168
173
 
169
- export { flush, shutdown };
174
+ // src/flatten-attributes.ts
175
+ function toAttributeValue(value) {
176
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
177
+ return value;
178
+ }
179
+ if (Array.isArray(value)) {
180
+ if (value.every((v) => typeof v === "string") || value.every((v) => typeof v === "number") || value.every((v) => typeof v === "boolean")) {
181
+ return value;
182
+ }
183
+ try {
184
+ return JSON.stringify(value);
185
+ } catch {
186
+ return "<serialization-failed>";
187
+ }
188
+ }
189
+ if (value instanceof Date) {
190
+ return value.toISOString();
191
+ }
192
+ if (value instanceof Error) {
193
+ return value.message;
194
+ }
195
+ return void 0;
196
+ }
197
+ function flattenToAttributes(fields, prefix = "") {
198
+ const out = {};
199
+ const seen = /* @__PURE__ */ new WeakSet();
200
+ function flatten(obj, currentPrefix) {
201
+ for (const [key, value] of Object.entries(obj)) {
202
+ if (value == null) continue;
203
+ const nextKey = currentPrefix ? `${currentPrefix}.${key}` : key;
204
+ const attr = toAttributeValue(value);
205
+ if (attr !== void 0) {
206
+ out[nextKey] = attr;
207
+ continue;
208
+ }
209
+ if (typeof value === "object" && value.constructor === Object) {
210
+ if (seen.has(value)) {
211
+ out[nextKey] = "<circular-reference>";
212
+ continue;
213
+ }
214
+ seen.add(value);
215
+ flatten(value, nextKey);
216
+ continue;
217
+ }
218
+ try {
219
+ out[nextKey] = JSON.stringify(value);
220
+ } catch {
221
+ out[nextKey] = "<serialization-failed>";
222
+ }
223
+ }
224
+ }
225
+ flatten(fields, prefix);
226
+ return out;
227
+ }
228
+
229
+ // src/structured-error.ts
230
+ function createStructuredError(input) {
231
+ const error = new Error(input.message, {
232
+ cause: input.cause
233
+ });
234
+ error.name = input.name ?? "StructuredError";
235
+ if (input.why !== void 0) error.why = input.why;
236
+ if (input.fix !== void 0) error.fix = input.fix;
237
+ if (input.link !== void 0) error.link = input.link;
238
+ if (input.code !== void 0) error.code = input.code;
239
+ if (input.status !== void 0) error.status = input.status;
240
+ if (input.details !== void 0) error.details = input.details;
241
+ error.toString = () => {
242
+ const lines = [`${error.name}: ${error.message}`];
243
+ if (error.why) lines.push(` Why: ${error.why}`);
244
+ if (error.fix) lines.push(` Fix: ${error.fix}`);
245
+ if (error.link) lines.push(` Link: ${error.link}`);
246
+ if (error.code !== void 0) lines.push(` Code: ${error.code}`);
247
+ if (error.status !== void 0) lines.push(` Status: ${error.status}`);
248
+ if (error.cause) lines.push(` Caused by: ${error.cause}`);
249
+ return lines.join("\n");
250
+ };
251
+ return error;
252
+ }
253
+ function getStructuredErrorAttributes(error) {
254
+ const structured = error;
255
+ const attributes = {
256
+ "error.type": error.name || "Error",
257
+ "error.message": error.message
258
+ };
259
+ if (error.stack) attributes["error.stack"] = error.stack;
260
+ if (structured.why) attributes["error.why"] = structured.why;
261
+ if (structured.fix) attributes["error.fix"] = structured.fix;
262
+ if (structured.link) attributes["error.link"] = structured.link;
263
+ if (structured.code !== void 0) {
264
+ attributes["error.code"] = typeof structured.code === "string" ? structured.code : String(structured.code);
265
+ }
266
+ if (structured.status !== void 0) {
267
+ attributes["error.status"] = structured.status;
268
+ }
269
+ if (structured.details) {
270
+ Object.assign(
271
+ attributes,
272
+ flattenToAttributes(structured.details, "error.details")
273
+ );
274
+ }
275
+ return attributes;
276
+ }
277
+ function recordStructuredError(ctx2, error) {
278
+ ctx2.recordException(error);
279
+ ctx2.setStatus({
280
+ code: SpanStatusCode.ERROR,
281
+ message: error.message
282
+ });
283
+ ctx2.setAttributes(getStructuredErrorAttributes(error));
284
+ }
285
+
286
+ // src/request-logger.ts
287
+ var requestContextStore = new AsyncLocalStorage();
288
+ function runWithRequestContext(ctx2, fn) {
289
+ return requestContextStore.run(ctx2, fn);
290
+ }
291
+ function resolveContext(ctx2) {
292
+ if (ctx2) return ctx2;
293
+ const stored = requestContextStore.getStore();
294
+ if (stored) return stored;
295
+ const span2 = trace.getActiveSpan();
296
+ if (!span2) {
297
+ throw new Error(
298
+ "[autotel] getRequestLogger() requires an active span or runWithRequestContext(). Wrap your handler with trace() or use runWithRequestContext()."
299
+ );
300
+ }
301
+ return createTraceContext(span2);
302
+ }
303
+ function getRequestLogger(ctx2, options) {
304
+ const activeContext = resolveContext(ctx2);
305
+ let contextState = {};
306
+ const addLogEvent = (level, message, fields) => {
307
+ const attrs2 = fields ? flattenToAttributes(fields) : void 0;
308
+ activeContext.addEvent(`log.${level}`, {
309
+ message,
310
+ ...attrs2
311
+ });
312
+ };
313
+ return {
314
+ set(fields) {
315
+ contextState = {
316
+ ...contextState,
317
+ ...fields
318
+ };
319
+ activeContext.setAttributes(flattenToAttributes(fields));
320
+ },
321
+ info(message, fields) {
322
+ addLogEvent("info", message, fields);
323
+ if (fields) {
324
+ contextState = {
325
+ ...contextState,
326
+ ...fields
327
+ };
328
+ activeContext.setAttributes(flattenToAttributes(fields));
329
+ }
330
+ },
331
+ warn(message, fields) {
332
+ addLogEvent("warn", message, fields);
333
+ activeContext.setAttribute("autotel.log.level", "warn");
334
+ if (fields) {
335
+ contextState = {
336
+ ...contextState,
337
+ ...fields
338
+ };
339
+ activeContext.setAttributes(flattenToAttributes(fields));
340
+ }
341
+ },
342
+ error(error, fields) {
343
+ const err = typeof error === "string" ? new Error(error) : error;
344
+ recordStructuredError(activeContext, err);
345
+ addLogEvent("error", err.message, fields);
346
+ if (fields) {
347
+ contextState = {
348
+ ...contextState,
349
+ ...fields
350
+ };
351
+ activeContext.setAttributes(flattenToAttributes(fields));
352
+ }
353
+ activeContext.setAttribute("autotel.log.level", "error");
354
+ },
355
+ getContext() {
356
+ return { ...contextState };
357
+ },
358
+ emitNow(overrides) {
359
+ const mergedContext = {
360
+ ...contextState,
361
+ ...overrides ?? {}
362
+ };
363
+ const flattened = flattenToAttributes(mergedContext);
364
+ activeContext.setAttributes(flattened);
365
+ const snapshot = {
366
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
367
+ traceId: activeContext.traceId,
368
+ spanId: activeContext.spanId,
369
+ correlationId: activeContext.correlationId,
370
+ context: mergedContext
371
+ };
372
+ activeContext.addEvent("log.emit.manual", {
373
+ ...flattened
374
+ });
375
+ if (options?.onEmit) {
376
+ Promise.resolve(options.onEmit(snapshot)).catch((error) => {
377
+ console.warn("[autotel] request logger onEmit failed:", error);
378
+ });
379
+ }
380
+ return snapshot;
381
+ }
382
+ };
383
+ }
384
+
385
+ export { createStructuredError, flattenToAttributes, flush, getRequestLogger, getStructuredErrorAttributes, recordStructuredError, runWithRequestContext, shutdown, toAttributeValue };
170
386
  //# sourceMappingURL=index.js.map
171
387
  //# sourceMappingURL=index.js.map