autotel 2.1.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.
Files changed (272) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1946 -0
  3. package/dist/chunk-2LNRY4QK.js +273 -0
  4. package/dist/chunk-2LNRY4QK.js.map +1 -0
  5. package/dist/chunk-3HENGDW2.js +587 -0
  6. package/dist/chunk-3HENGDW2.js.map +1 -0
  7. package/dist/chunk-4OAT42CA.cjs +73 -0
  8. package/dist/chunk-4OAT42CA.cjs.map +1 -0
  9. package/dist/chunk-5GWX5LFW.js +70 -0
  10. package/dist/chunk-5GWX5LFW.js.map +1 -0
  11. package/dist/chunk-5R2M36QB.js +195 -0
  12. package/dist/chunk-5R2M36QB.js.map +1 -0
  13. package/dist/chunk-5ZN622AO.js +73 -0
  14. package/dist/chunk-5ZN622AO.js.map +1 -0
  15. package/dist/chunk-77MSMAUQ.cjs +498 -0
  16. package/dist/chunk-77MSMAUQ.cjs.map +1 -0
  17. package/dist/chunk-ABPEQ6RK.cjs +596 -0
  18. package/dist/chunk-ABPEQ6RK.cjs.map +1 -0
  19. package/dist/chunk-BWYGJKRB.js +95 -0
  20. package/dist/chunk-BWYGJKRB.js.map +1 -0
  21. package/dist/chunk-BZHG5IZ4.js +73 -0
  22. package/dist/chunk-BZHG5IZ4.js.map +1 -0
  23. package/dist/chunk-G7VZBCD6.cjs +35 -0
  24. package/dist/chunk-G7VZBCD6.cjs.map +1 -0
  25. package/dist/chunk-GVLK7YUU.cjs +30 -0
  26. package/dist/chunk-GVLK7YUU.cjs.map +1 -0
  27. package/dist/chunk-HCCXC7XG.js +205 -0
  28. package/dist/chunk-HCCXC7XG.js.map +1 -0
  29. package/dist/chunk-HE6T6FIX.cjs +203 -0
  30. package/dist/chunk-HE6T6FIX.cjs.map +1 -0
  31. package/dist/chunk-KIXWPOCO.cjs +100 -0
  32. package/dist/chunk-KIXWPOCO.cjs.map +1 -0
  33. package/dist/chunk-KVGNW3FC.js +87 -0
  34. package/dist/chunk-KVGNW3FC.js.map +1 -0
  35. package/dist/chunk-LITNXTTT.js +3 -0
  36. package/dist/chunk-LITNXTTT.js.map +1 -0
  37. package/dist/chunk-M4ANN7RL.js +114 -0
  38. package/dist/chunk-M4ANN7RL.js.map +1 -0
  39. package/dist/chunk-NC52UBR2.cjs +32 -0
  40. package/dist/chunk-NC52UBR2.cjs.map +1 -0
  41. package/dist/chunk-NHCNRQD3.cjs +212 -0
  42. package/dist/chunk-NHCNRQD3.cjs.map +1 -0
  43. package/dist/chunk-NZ72VDNY.cjs +4 -0
  44. package/dist/chunk-NZ72VDNY.cjs.map +1 -0
  45. package/dist/chunk-P6JUDYNO.js +57 -0
  46. package/dist/chunk-P6JUDYNO.js.map +1 -0
  47. package/dist/chunk-RJYY7BWX.js +1349 -0
  48. package/dist/chunk-RJYY7BWX.js.map +1 -0
  49. package/dist/chunk-TRI4V5BF.cjs +126 -0
  50. package/dist/chunk-TRI4V5BF.cjs.map +1 -0
  51. package/dist/chunk-UL33I6IS.js +139 -0
  52. package/dist/chunk-UL33I6IS.js.map +1 -0
  53. package/dist/chunk-URRW6M2C.cjs +61 -0
  54. package/dist/chunk-URRW6M2C.cjs.map +1 -0
  55. package/dist/chunk-UY3UYPBZ.cjs +77 -0
  56. package/dist/chunk-UY3UYPBZ.cjs.map +1 -0
  57. package/dist/chunk-W3253FGB.cjs +277 -0
  58. package/dist/chunk-W3253FGB.cjs.map +1 -0
  59. package/dist/chunk-W7LHZVQF.js +26 -0
  60. package/dist/chunk-W7LHZVQF.js.map +1 -0
  61. package/dist/chunk-WBWNM6LB.cjs +1360 -0
  62. package/dist/chunk-WBWNM6LB.cjs.map +1 -0
  63. package/dist/chunk-WFJ7L2RV.js +494 -0
  64. package/dist/chunk-WFJ7L2RV.js.map +1 -0
  65. package/dist/chunk-X4RMFFMR.js +28 -0
  66. package/dist/chunk-X4RMFFMR.js.map +1 -0
  67. package/dist/chunk-Y4Y2S7BM.cjs +92 -0
  68. package/dist/chunk-Y4Y2S7BM.cjs.map +1 -0
  69. package/dist/chunk-YLPNXZFI.cjs +143 -0
  70. package/dist/chunk-YLPNXZFI.cjs.map +1 -0
  71. package/dist/chunk-YTXEZ4SD.cjs +77 -0
  72. package/dist/chunk-YTXEZ4SD.cjs.map +1 -0
  73. package/dist/chunk-Z6ZWNWWR.js +30 -0
  74. package/dist/chunk-Z6ZWNWWR.js.map +1 -0
  75. package/dist/config.cjs +26 -0
  76. package/dist/config.cjs.map +1 -0
  77. package/dist/config.d.cts +75 -0
  78. package/dist/config.d.ts +75 -0
  79. package/dist/config.js +5 -0
  80. package/dist/config.js.map +1 -0
  81. package/dist/db.cjs +233 -0
  82. package/dist/db.cjs.map +1 -0
  83. package/dist/db.d.cts +123 -0
  84. package/dist/db.d.ts +123 -0
  85. package/dist/db.js +228 -0
  86. package/dist/db.js.map +1 -0
  87. package/dist/decorators.cjs +67 -0
  88. package/dist/decorators.cjs.map +1 -0
  89. package/dist/decorators.d.cts +91 -0
  90. package/dist/decorators.d.ts +91 -0
  91. package/dist/decorators.js +65 -0
  92. package/dist/decorators.js.map +1 -0
  93. package/dist/event-subscriber.cjs +6 -0
  94. package/dist/event-subscriber.cjs.map +1 -0
  95. package/dist/event-subscriber.d.cts +116 -0
  96. package/dist/event-subscriber.d.ts +116 -0
  97. package/dist/event-subscriber.js +3 -0
  98. package/dist/event-subscriber.js.map +1 -0
  99. package/dist/event-testing.cjs +21 -0
  100. package/dist/event-testing.cjs.map +1 -0
  101. package/dist/event-testing.d.cts +110 -0
  102. package/dist/event-testing.d.ts +110 -0
  103. package/dist/event-testing.js +4 -0
  104. package/dist/event-testing.js.map +1 -0
  105. package/dist/event.cjs +30 -0
  106. package/dist/event.cjs.map +1 -0
  107. package/dist/event.d.cts +282 -0
  108. package/dist/event.d.ts +282 -0
  109. package/dist/event.js +13 -0
  110. package/dist/event.js.map +1 -0
  111. package/dist/exporters.cjs +17 -0
  112. package/dist/exporters.cjs.map +1 -0
  113. package/dist/exporters.d.cts +1 -0
  114. package/dist/exporters.d.ts +1 -0
  115. package/dist/exporters.js +4 -0
  116. package/dist/exporters.js.map +1 -0
  117. package/dist/functional.cjs +46 -0
  118. package/dist/functional.cjs.map +1 -0
  119. package/dist/functional.d.cts +478 -0
  120. package/dist/functional.d.ts +478 -0
  121. package/dist/functional.js +13 -0
  122. package/dist/functional.js.map +1 -0
  123. package/dist/http.cjs +189 -0
  124. package/dist/http.cjs.map +1 -0
  125. package/dist/http.d.cts +169 -0
  126. package/dist/http.d.ts +169 -0
  127. package/dist/http.js +184 -0
  128. package/dist/http.js.map +1 -0
  129. package/dist/index.cjs +333 -0
  130. package/dist/index.cjs.map +1 -0
  131. package/dist/index.d.cts +758 -0
  132. package/dist/index.d.ts +758 -0
  133. package/dist/index.js +143 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/instrumentation.cjs +182 -0
  136. package/dist/instrumentation.cjs.map +1 -0
  137. package/dist/instrumentation.d.cts +49 -0
  138. package/dist/instrumentation.d.ts +49 -0
  139. package/dist/instrumentation.js +179 -0
  140. package/dist/instrumentation.js.map +1 -0
  141. package/dist/logger.cjs +19 -0
  142. package/dist/logger.cjs.map +1 -0
  143. package/dist/logger.d.cts +146 -0
  144. package/dist/logger.d.ts +146 -0
  145. package/dist/logger.js +6 -0
  146. package/dist/logger.js.map +1 -0
  147. package/dist/metric-helpers.cjs +31 -0
  148. package/dist/metric-helpers.cjs.map +1 -0
  149. package/dist/metric-helpers.d.cts +13 -0
  150. package/dist/metric-helpers.d.ts +13 -0
  151. package/dist/metric-helpers.js +6 -0
  152. package/dist/metric-helpers.js.map +1 -0
  153. package/dist/metric-testing.cjs +21 -0
  154. package/dist/metric-testing.cjs.map +1 -0
  155. package/dist/metric-testing.d.cts +110 -0
  156. package/dist/metric-testing.d.ts +110 -0
  157. package/dist/metric-testing.js +4 -0
  158. package/dist/metric-testing.js.map +1 -0
  159. package/dist/metric.cjs +26 -0
  160. package/dist/metric.cjs.map +1 -0
  161. package/dist/metric.d.cts +240 -0
  162. package/dist/metric.d.ts +240 -0
  163. package/dist/metric.js +9 -0
  164. package/dist/metric.js.map +1 -0
  165. package/dist/processors.cjs +17 -0
  166. package/dist/processors.cjs.map +1 -0
  167. package/dist/processors.d.cts +1 -0
  168. package/dist/processors.d.ts +1 -0
  169. package/dist/processors.js +4 -0
  170. package/dist/processors.js.map +1 -0
  171. package/dist/sampling.cjs +40 -0
  172. package/dist/sampling.cjs.map +1 -0
  173. package/dist/sampling.d.cts +260 -0
  174. package/dist/sampling.d.ts +260 -0
  175. package/dist/sampling.js +7 -0
  176. package/dist/sampling.js.map +1 -0
  177. package/dist/semantic-helpers.cjs +35 -0
  178. package/dist/semantic-helpers.cjs.map +1 -0
  179. package/dist/semantic-helpers.d.cts +442 -0
  180. package/dist/semantic-helpers.d.ts +442 -0
  181. package/dist/semantic-helpers.js +14 -0
  182. package/dist/semantic-helpers.js.map +1 -0
  183. package/dist/tail-sampling-processor.cjs +13 -0
  184. package/dist/tail-sampling-processor.cjs.map +1 -0
  185. package/dist/tail-sampling-processor.d.cts +27 -0
  186. package/dist/tail-sampling-processor.d.ts +27 -0
  187. package/dist/tail-sampling-processor.js +4 -0
  188. package/dist/tail-sampling-processor.js.map +1 -0
  189. package/dist/testing.cjs +286 -0
  190. package/dist/testing.cjs.map +1 -0
  191. package/dist/testing.d.cts +291 -0
  192. package/dist/testing.d.ts +291 -0
  193. package/dist/testing.js +263 -0
  194. package/dist/testing.js.map +1 -0
  195. package/dist/trace-context-DRZdUvVY.d.cts +181 -0
  196. package/dist/trace-context-DRZdUvVY.d.ts +181 -0
  197. package/dist/trace-helpers.cjs +54 -0
  198. package/dist/trace-helpers.cjs.map +1 -0
  199. package/dist/trace-helpers.d.cts +524 -0
  200. package/dist/trace-helpers.d.ts +524 -0
  201. package/dist/trace-helpers.js +5 -0
  202. package/dist/trace-helpers.js.map +1 -0
  203. package/dist/tracer-provider.cjs +21 -0
  204. package/dist/tracer-provider.cjs.map +1 -0
  205. package/dist/tracer-provider.d.cts +169 -0
  206. package/dist/tracer-provider.d.ts +169 -0
  207. package/dist/tracer-provider.js +4 -0
  208. package/dist/tracer-provider.js.map +1 -0
  209. package/package.json +280 -0
  210. package/src/baggage-span-processor.test.ts +202 -0
  211. package/src/baggage-span-processor.ts +98 -0
  212. package/src/circuit-breaker.test.ts +341 -0
  213. package/src/circuit-breaker.ts +184 -0
  214. package/src/config.test.ts +94 -0
  215. package/src/config.ts +169 -0
  216. package/src/db.test.ts +252 -0
  217. package/src/db.ts +447 -0
  218. package/src/decorators.test.ts +203 -0
  219. package/src/decorators.ts +188 -0
  220. package/src/env-config.test.ts +246 -0
  221. package/src/env-config.ts +158 -0
  222. package/src/event-queue.test.ts +222 -0
  223. package/src/event-queue.ts +203 -0
  224. package/src/event-subscriber.ts +136 -0
  225. package/src/event-testing.ts +197 -0
  226. package/src/event.test.ts +718 -0
  227. package/src/event.ts +556 -0
  228. package/src/exporters.ts +96 -0
  229. package/src/functional.test.ts +1059 -0
  230. package/src/functional.ts +2295 -0
  231. package/src/http.test.ts +487 -0
  232. package/src/http.ts +424 -0
  233. package/src/index.ts +158 -0
  234. package/src/init.customization.test.ts +210 -0
  235. package/src/init.integrations.test.ts +366 -0
  236. package/src/init.openllmetry.test.ts +282 -0
  237. package/src/init.protocol.test.ts +215 -0
  238. package/src/init.ts +1426 -0
  239. package/src/instrumentation.test.ts +108 -0
  240. package/src/instrumentation.ts +308 -0
  241. package/src/logger.test.ts +117 -0
  242. package/src/logger.ts +246 -0
  243. package/src/metric-helpers.ts +47 -0
  244. package/src/metric-testing.ts +197 -0
  245. package/src/metric.ts +434 -0
  246. package/src/metrics.test.ts +205 -0
  247. package/src/operation-context.ts +93 -0
  248. package/src/processors.ts +106 -0
  249. package/src/rate-limiter.test.ts +199 -0
  250. package/src/rate-limiter.ts +98 -0
  251. package/src/sampling.test.ts +513 -0
  252. package/src/sampling.ts +428 -0
  253. package/src/semantic-helpers.test.ts +311 -0
  254. package/src/semantic-helpers.ts +584 -0
  255. package/src/shutdown.test.ts +311 -0
  256. package/src/shutdown.ts +222 -0
  257. package/src/stub.integration.test.ts +361 -0
  258. package/src/tail-sampling-processor.test.ts +226 -0
  259. package/src/tail-sampling-processor.ts +51 -0
  260. package/src/testing.ts +670 -0
  261. package/src/trace-context.ts +470 -0
  262. package/src/trace-helpers.new.test.ts +278 -0
  263. package/src/trace-helpers.test.ts +242 -0
  264. package/src/trace-helpers.ts +690 -0
  265. package/src/tracer-provider.test.ts +183 -0
  266. package/src/tracer-provider.ts +266 -0
  267. package/src/track.test.ts +153 -0
  268. package/src/track.ts +120 -0
  269. package/src/validation.test.ts +306 -0
  270. package/src/validation.ts +239 -0
  271. package/src/variable-name-inference.test.ts +178 -0
  272. package/src/variable-name-inference.ts +242 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/baggage-span-processor.ts","../src/env-config.ts","../src/init.ts"],"names":["propagation","otelContext","__require","resolve","string","url","optional","config","OTLPTraceExporterHTTP","OTLPMetricExporterHTTP","logger","PinoInstrumentation","WinstonInstrumentation","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","TailSamplingSpanProcessor","BatchSpanProcessor","SimpleSpanProcessor","ConsoleSpanExporter","PeriodicExportingMetricReader","NodeSDK","getNodeAutoInstrumentations"],"mappings":"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","file":"chunk-ABPEQ6RK.cjs","sourcesContent":["/**\n * Span processor that copies baggage entries to span attributes\n *\n * This makes baggage visible in trace UIs without manual attribute setting.\n * Enabled via init({ baggage: true }) or init({ baggage: 'custom-prefix' })\n */\n\nimport type { Span, Context } from '@opentelemetry/api';\nimport { propagation, context as otelContext } from '@opentelemetry/api';\nimport type { SpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-base';\n\nexport interface BaggageSpanProcessorOptions {\n /**\n * Prefix for baggage attributes\n * @default 'baggage.'\n */\n prefix?: string;\n}\n\n/**\n * Span processor that automatically copies baggage entries to span attributes\n *\n * This makes baggage visible in trace UIs (Jaeger, Grafana, DataDog, etc.)\n * without manually calling ctx.setAttribute() for each baggage entry.\n *\n * @example Enable in init()\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: true // Uses default 'baggage.' prefix\n * });\n *\n * // Now baggage automatically appears as span attributes\n * await withBaggage({\n * baggage: { 'tenant.id': 't1', 'user.id': 'u1' },\n * fn: async () => {\n * // Span has baggage.tenant.id and baggage.user.id attributes!\n * }\n * });\n * ```\n *\n * @example Custom prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: 'ctx' // Uses 'ctx.' prefix\n * });\n * // Creates attributes: ctx.tenant.id, ctx.user.id\n * ```\n */\nexport class BaggageSpanProcessor implements SpanProcessor {\n private readonly prefix: string;\n\n constructor(options: BaggageSpanProcessorOptions = {}) {\n this.prefix = options.prefix ?? 'baggage.';\n }\n\n onStart(span: Span, parentContext: Context): void {\n // Read baggage from parentContext first (spans created with explicit context)\n // Then fall back to active context (spans created without explicit context)\n // Also check getActiveContextWithBaggage() to see baggage set via ctx.setBaggage()\n let baggage = propagation.getBaggage(parentContext);\n if (!baggage) {\n baggage = propagation.getBaggage(otelContext.active());\n }\n // Check stored context from ctx.setBaggage() if still no baggage\n if (!baggage) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getActiveContextWithBaggage } = require('../trace-context');\n const storedContext = getActiveContextWithBaggage();\n baggage = propagation.getBaggage(storedContext);\n } catch {\n // Fallback if trace-context isn't available\n }\n }\n if (!baggage) return;\n\n // Copy all baggage entries to span attributes\n for (const [key, entry] of baggage.getAllEntries()) {\n span.setAttribute(`${this.prefix}${key}`, entry.value);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onEnd(_span: ReadableSpan): void {\n // No-op - required by SpanProcessor interface\n }\n\n async shutdown(): Promise<void> {\n // No-op\n }\n\n async forceFlush(): Promise<void> {\n // No-op\n }\n}\n","import { resolve } from 'node-env-resolver';\nimport { string, url, optional } from 'node-env-resolver/validators';\n\n/**\n * Standard OpenTelemetry environment variables\n */\nexport interface OtelEnvVars {\n OTEL_SERVICE_NAME?: string;\n OTEL_EXPORTER_OTLP_ENDPOINT?: string;\n OTEL_EXPORTER_OTLP_HEADERS?: string;\n OTEL_RESOURCE_ATTRIBUTES?: string;\n OTEL_EXPORTER_OTLP_PROTOCOL?: 'http' | 'grpc';\n}\n\n/**\n * Parsed resource attributes as key-value pairs\n */\nexport interface ResourceAttributes {\n [key: string]: string;\n}\n\n/**\n * Parsed OTLP headers as key-value pairs\n */\nexport interface OtlpHeaders {\n [key: string]: string;\n}\n\n/**\n * Environment-resolved configuration (subset of AutotelConfig)\n * Defined locally to avoid circular dependency with init.ts\n */\nexport interface EnvConfig {\n service?: string;\n endpoint?: string;\n protocol?: 'http' | 'grpc';\n otlpHeaders?: Record<string, string>;\n resourceAttributes?: Record<string, string>;\n}\n\n/**\n * Resolve OpenTelemetry environment variables using node-env-resolver\n */\nexport function resolveOtelEnv(): OtelEnvVars {\n return resolve({\n OTEL_SERVICE_NAME: string({ optional: true }),\n OTEL_EXPORTER_OTLP_ENDPOINT: url({ optional: true }),\n OTEL_EXPORTER_OTLP_HEADERS: string({ optional: true }),\n OTEL_RESOURCE_ATTRIBUTES: string({ optional: true }),\n OTEL_EXPORTER_OTLP_PROTOCOL: optional(['http', 'grpc'] as const),\n });\n}\n\n/**\n * Parse OTEL_RESOURCE_ATTRIBUTES from comma-separated key=value pairs\n * Example: \"service.version=1.0.0,deployment.environment=production\"\n */\nexport function parseResourceAttributes(\n input: string | undefined,\n): ResourceAttributes {\n if (!input || input.trim() === '') {\n return {};\n }\n\n const attributes: ResourceAttributes = {};\n const pairs = input.split(',');\n\n for (const pair of pairs) {\n const trimmedPair = pair.trim();\n if (!trimmedPair) continue;\n\n const equalIndex = trimmedPair.indexOf('=');\n if (equalIndex === -1) {\n // Invalid format, skip this pair\n continue;\n }\n\n const key = trimmedPair.slice(0, equalIndex).trim();\n const value = trimmedPair.slice(equalIndex + 1).trim();\n\n if (key && value) {\n attributes[key] = value;\n }\n }\n\n return attributes;\n}\n\n/**\n * Parse OTEL_EXPORTER_OTLP_HEADERS from comma-separated key=value pairs\n * Example: \"api-key=secret123,x-custom-header=value\"\n */\nexport function parseOtlpHeaders(input: string | undefined): OtlpHeaders {\n if (!input || input.trim() === '') {\n return {};\n }\n\n const headers: OtlpHeaders = {};\n const pairs = input.split(',');\n\n for (const pair of pairs) {\n const trimmedPair = pair.trim();\n if (!trimmedPair) continue;\n\n const equalIndex = trimmedPair.indexOf('=');\n if (equalIndex === -1) {\n // Invalid format, skip this pair\n continue;\n }\n\n const key = trimmedPair.slice(0, equalIndex).trim();\n const value = trimmedPair.slice(equalIndex + 1).trim();\n\n if (key && value) {\n headers[key] = value;\n }\n }\n\n return headers;\n}\n\n/**\n * Convert resolved environment variables to config\n */\nexport function envToConfig(env: OtelEnvVars): EnvConfig {\n const config: EnvConfig = {};\n\n if (env.OTEL_SERVICE_NAME) {\n config.service = env.OTEL_SERVICE_NAME;\n }\n\n if (env.OTEL_EXPORTER_OTLP_ENDPOINT) {\n config.endpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT;\n }\n\n if (env.OTEL_EXPORTER_OTLP_PROTOCOL) {\n config.protocol = env.OTEL_EXPORTER_OTLP_PROTOCOL;\n }\n\n if (env.OTEL_EXPORTER_OTLP_HEADERS) {\n config.otlpHeaders = parseOtlpHeaders(env.OTEL_EXPORTER_OTLP_HEADERS);\n }\n\n const resourceAttrs = parseResourceAttributes(env.OTEL_RESOURCE_ATTRIBUTES);\n if (Object.keys(resourceAttrs).length > 0) {\n config.resourceAttributes = resourceAttrs;\n }\n\n return config;\n}\n\n/**\n * Main function to resolve config from environment variables\n */\nexport function resolveConfigFromEnv(): EnvConfig {\n const env = resolveOtelEnv();\n return envToConfig(env);\n}\n","/**\n * Simplified initialization for autotel\n *\n * Single init() function with sensible defaults.\n * Replaces initInstrumentation() and separate events config.\n */\n\nimport { NodeSDK } from '@opentelemetry/sdk-node';\nimport type { NodeSDKConfiguration } from '@opentelemetry/sdk-node';\nimport {\n BatchSpanProcessor,\n type SpanProcessor,\n SimpleSpanProcessor,\n ConsoleSpanExporter,\n} from '@opentelemetry/sdk-trace-base';\nimport type { SpanExporter } from '@opentelemetry/sdk-trace-base';\nimport {\n resourceFromAttributes,\n type Resource,\n} from '@opentelemetry/resources';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions';\nimport type { Sampler } from './sampling';\nimport { AdaptiveSampler } from './sampling';\nimport type { EventSubscriber } from './event-subscriber';\nimport type { Logger } from './logger';\nimport type { Attributes } from '@opentelemetry/api';\nimport type { ValidationConfig } from './validation';\nimport {\n PeriodicExportingMetricReader,\n type MetricReader,\n} from '@opentelemetry/sdk-metrics';\nimport { OTLPMetricExporter as OTLPMetricExporterHTTP } from '@opentelemetry/exporter-metrics-otlp-http';\nimport { OTLPTraceExporter as OTLPTraceExporterHTTP } from '@opentelemetry/exporter-trace-otlp-http';\nimport type { PushMetricExporter } from '@opentelemetry/sdk-metrics';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { TailSamplingSpanProcessor } from './tail-sampling-processor';\nimport { BaggageSpanProcessor } from './baggage-span-processor';\nimport { resolveConfigFromEnv } from './env-config';\nimport { PinoInstrumentation } from '@opentelemetry/instrumentation-pino';\nimport { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\n\n// Type imports for exporters\ntype OTLPExporterConfig = {\n url?: string;\n headers?: Record<string, string>;\n timeoutMillis?: number;\n concurrencyLimit?: number;\n};\n\n// Lazy-load gRPC exporters (optional peer dependencies)\nlet OTLPTraceExporterGRPC:\n | (new (config: OTLPExporterConfig) => SpanExporter)\n | undefined;\nlet OTLPMetricExporterGRPC:\n | (new (config: OTLPExporterConfig) => PushMetricExporter)\n | undefined;\n\n/**\n * Helper: Lazy-load gRPC trace exporter\n */\nfunction loadGRPCTraceExporter(): new (\n config: OTLPExporterConfig,\n) => SpanExporter {\n if (OTLPTraceExporterGRPC) return OTLPTraceExporterGRPC;\n\n try {\n // Dynamic import for optional peer dependency\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const grpcModule = require('@opentelemetry/exporter-trace-otlp-grpc');\n OTLPTraceExporterGRPC = grpcModule.OTLPTraceExporter as new (\n config: OTLPExporterConfig,\n ) => SpanExporter;\n return OTLPTraceExporterGRPC;\n } catch {\n throw new Error(\n 'gRPC trace exporter not found. Install with: pnpm add @opentelemetry/exporter-trace-otlp-grpc',\n );\n }\n}\n\n/**\n * Helper: Lazy-load gRPC metric exporter\n */\nfunction loadGRPCMetricExporter(): new (\n config: OTLPExporterConfig,\n) => PushMetricExporter {\n if (OTLPMetricExporterGRPC) return OTLPMetricExporterGRPC;\n\n try {\n // Dynamic import for optional peer dependency\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const grpcModule = require('@opentelemetry/exporter-metrics-otlp-grpc');\n OTLPMetricExporterGRPC = grpcModule.OTLPMetricExporter as new (\n config: OTLPExporterConfig,\n ) => PushMetricExporter;\n return OTLPMetricExporterGRPC;\n } catch {\n throw new Error(\n 'gRPC metric exporter not found. Install with: pnpm add @opentelemetry/exporter-metrics-otlp-grpc',\n );\n }\n}\n\n/**\n * Helper: Create trace exporter based on protocol\n */\nfunction createTraceExporter(\n protocol: 'http' | 'grpc',\n config: OTLPExporterConfig,\n): SpanExporter {\n if (protocol === 'grpc') {\n const Exporter = loadGRPCTraceExporter();\n return new Exporter(config);\n }\n\n // Default: HTTP\n return new OTLPTraceExporterHTTP(config);\n}\n\n/**\n * Helper: Create metric exporter based on protocol\n */\nfunction createMetricExporter(\n protocol: 'http' | 'grpc',\n config: OTLPExporterConfig,\n): PushMetricExporter {\n if (protocol === 'grpc') {\n const Exporter = loadGRPCMetricExporter();\n return new Exporter(config);\n }\n\n // Default: HTTP\n return new OTLPMetricExporterHTTP(config);\n}\n\n/**\n * Helper: Resolve protocol from config and environment\n */\nfunction resolveProtocol(configProtocol?: 'http' | 'grpc'): 'http' | 'grpc' {\n // 1. Check config parameter (highest priority)\n if (configProtocol === 'grpc' || configProtocol === 'http') {\n return configProtocol;\n }\n\n // 2. Check OTEL_EXPORTER_OTLP_PROTOCOL env var\n const envProtocol = process.env.OTEL_EXPORTER_OTLP_PROTOCOL;\n if (envProtocol === 'grpc') return 'grpc';\n if (envProtocol === 'http/protobuf' || envProtocol === 'http') return 'http';\n\n // 3. Default to HTTP\n return 'http';\n}\n\n/**\n * Helper: Adjust endpoint URL for protocol\n * gRPC exporters don't need the /v1/traces or /v1/metrics path\n * HTTP exporters need the full path\n */\nfunction formatEndpointUrl(\n endpoint: string,\n signal: 'traces' | 'metrics',\n protocol: 'http' | 'grpc',\n): string {\n if (protocol === 'grpc') {\n // gRPC: strip any paths, return base endpoint\n return endpoint.replace(/\\/(v1\\/)?(traces|metrics|logs)$/, '');\n }\n\n // HTTP: append signal path if not present\n if (!endpoint.endsWith(`/v1/${signal}`)) {\n return `${endpoint}/v1/${signal}`;\n }\n\n return endpoint;\n}\n\n/**\n * Default silent logger (no-op) when user doesn't provide one\n */\nconst silentLogger: Logger = {\n info: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n};\n\nexport interface AutotelConfig {\n /** Service name (required) */\n service: string;\n\n /** Event subscribers - bring your own (PostHog, Mixpanel, etc.) */\n subscribers?: EventSubscriber[];\n\n /**\n * Additional OpenTelemetry instrumentations to register.\n * Useful when you want HTTP/Prisma/etc auto instrumentation alongside\n * the functional helpers.\n *\n * **Important:** If you need custom instrumentation configs (like `requireParentSpan: false`),\n * use EITHER manual instrumentations OR integrations, not both for the same library.\n * Manual instrumentations always take precedence over auto-instrumentations.\n *\n * @example Manual instrumentations with custom config\n * ```typescript\n * import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'\n *\n * init({\n * service: 'my-app',\n * integrations: false, // Disable auto-instrumentations\n * instrumentations: [\n * new MongoDBInstrumentation({\n * requireParentSpan: false // Custom config\n * })\n * ]\n * })\n * ```\n *\n * @example Mix auto + manual (auto for most, manual for specific configs)\n * ```typescript\n * import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'\n *\n * init({\n * service: 'my-app',\n * integrations: ['http', 'express'], // Auto for these\n * instrumentations: [\n * new MongoDBInstrumentation({\n * requireParentSpan: false // Manual config for MongoDB\n * })\n * ]\n * })\n * ```\n */\n instrumentations?: NodeSDKConfiguration['instrumentations'];\n\n /**\n * Simple integration names for auto-instrumentation.\n * Uses @opentelemetry/auto-instrumentations-node (peer dependency).\n *\n * **Important:** If you provide manual instrumentations for the same library,\n * the manual config takes precedence and auto-instrumentation for that library is disabled.\n *\n * @example Enable all integrations (simple approach)\n * ```typescript\n * init({\n * service: 'my-app',\n * integrations: true // Enable all with defaults\n * })\n * ```\n *\n * @example Enable specific integrations\n * ```typescript\n * init({\n * service: 'my-app',\n * integrations: ['express', 'pino', 'http']\n * })\n * ```\n *\n * @example Configure specific integrations\n * ```typescript\n * init({\n * service: 'my-app',\n * integrations: {\n * express: { enabled: true },\n * pino: { enabled: true },\n * http: { enabled: false }\n * }\n * })\n * ```\n *\n * @example Manual config when you need custom settings\n * ```typescript\n * import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'\n *\n * init({\n * service: 'my-app',\n * integrations: false, // Use manual control\n * instrumentations: [\n * new MongoDBInstrumentation({\n * requireParentSpan: false // Custom config not available with auto\n * })\n * ]\n * })\n * ```\n */\n integrations?: string[] | boolean | Record<string, { enabled?: boolean }>;\n\n /**\n * OTLP endpoint for traces/metrics/logs\n * Only used if you don't provide custom exporters/processors\n * @default process.env.OTLP_ENDPOINT || 'http://localhost:4318'\n */\n endpoint?: string;\n\n /**\n * Custom span processors for traces (supports multiple processors)\n * Allows you to use any backend: Jaeger, Zipkin, Datadog, New Relic, etc.\n * If not provided, defaults to OTLP with tail sampling\n *\n * @example Multiple processors\n * ```typescript\n * import { JaegerExporter } from '@opentelemetry/exporter-jaeger'\n * import { BatchSpanProcessor, SimpleSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base'\n *\n * init({\n * service: 'my-app',\n * spanProcessors: [\n * new BatchSpanProcessor(new JaegerExporter()),\n * new SimpleSpanProcessor(new ConsoleSpanExporter()) // Debug alongside production\n * ]\n * })\n * ```\n *\n * @example Single processor\n * ```typescript\n * import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\n *\n * init({\n * service: 'my-app',\n * spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())]\n * })\n * ```\n */\n spanProcessors?: SpanProcessor[];\n\n /**\n * Custom span exporters for traces (alternative to spanProcessors, supports multiple exporters)\n * Provide either spanProcessors OR spanExporters, not both\n * Each exporter will be wrapped in TailSamplingSpanProcessor + BatchSpanProcessor\n *\n * @example Multiple exporters\n * ```typescript\n * import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'\n * import { JaegerExporter } from '@opentelemetry/exporter-jaeger'\n *\n * init({\n * service: 'my-app',\n * spanExporters: [\n * new ZipkinExporter({ url: 'http://localhost:9411/api/v2/spans' }),\n * new JaegerExporter() // Send to multiple backends simultaneously\n * ]\n * })\n * ```\n *\n * @example Single exporter\n * ```typescript\n * import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'\n *\n * init({\n * service: 'my-app',\n * spanExporters: [new ZipkinExporter({ url: 'http://localhost:9411/api/v2/spans' })]\n * })\n * ```\n */\n spanExporters?: SpanExporter[];\n\n /**\n * Custom metric readers (supports multiple readers)\n * Allows sending metrics to multiple backends: OTLP, Prometheus, custom readers\n * Defaults to OTLP metrics exporter when metrics are enabled.\n *\n * @example Multiple metric readers\n * ```typescript\n * import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\n * import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'\n * import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'\n *\n * init({\n * service: 'my-app',\n * metricReaders: [\n * new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter() }),\n * new PrometheusExporter() // Export to multiple backends\n * ]\n * })\n * ```\n */\n metricReaders?: MetricReader[];\n\n /**\n * Custom log record processors. When omitted, logs are not configured.\n */\n logRecordProcessors?: LogRecordProcessor[];\n\n /** Additional resource attributes to merge with defaults. */\n resourceAttributes?: Attributes;\n\n /** Provide a fully custom Resource to merge (advanced use case). */\n resource?: Resource;\n\n /**\n * Headers for default OTLP exporters. Accepts either an object map or\n * a \"key=value\" comma separated string.\n */\n otlpHeaders?: Record<string, string> | string;\n\n /**\n * OTLP protocol to use for traces, metrics, and logs\n * - 'http': HTTP/protobuf (default, uses port 4318)\n * - 'grpc': gRPC (uses port 4317)\n *\n * Can be overridden with OTEL_EXPORTER_OTLP_PROTOCOL env var.\n *\n * Note: gRPC exporters are optional peer dependencies. Install them with:\n * ```bash\n * pnpm add @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/exporter-metrics-otlp-grpc\n * ```\n *\n * @example HTTP (default)\n * ```typescript\n * init({\n * service: 'my-app',\n * protocol: 'http', // or omit (defaults to http)\n * endpoint: 'http://localhost:4318'\n * })\n * ```\n *\n * @example gRPC\n * ```typescript\n * init({\n * service: 'my-app',\n * protocol: 'grpc',\n * endpoint: 'grpc://localhost:4317'\n * })\n * ```\n *\n * @default 'http'\n */\n protocol?: 'http' | 'grpc';\n\n /**\n * Optional factory to build a customised NodeSDK instance from our defaults.\n */\n sdkFactory?: (defaults: Partial<NodeSDKConfiguration>) => NodeSDK;\n\n /**\n * Infrastructure metrics configuration\n * - true: always enabled (default)\n * - false: always disabled\n * - 'auto': always enabled (same as true)\n *\n * Can be overridden with AUTOTELEMETRY_METRICS=on|off env var\n */\n metrics?: boolean | 'auto';\n\n /** Sampling strategy (default: AdaptiveSampler with 10% baseline) */\n sampler?: Sampler;\n\n /** Service version (default: auto-detect from package.json or '1.0.0') */\n version?: string;\n\n /** Environment (default: process.env.NODE_ENV || 'development') */\n environment?: string;\n\n /**\n * Logger instance for structured logging with automatic trace correlation\n *\n * **Recommended:** Bring your own Pino or Winston instance\n *\n * Autotel automatically instruments Pino and Winston loggers to:\n * - Inject trace context (traceId, spanId) into every log record\n * - Record errors in the active OpenTelemetry span\n * - Bridge logs to the OpenTelemetry Logs API for OTLP export to Grafana, Datadog, etc.\n *\n * Supports any logger with 4 methods: info/warn/error/debug\n * Default: silent logger (no-op)\n *\n * @example Using Pino (recommended)\n * ```typescript\n * import pino from 'pino' // npm install pino\n * import { init } from 'autotel'\n *\n * const logger = pino({ level: 'info' })\n * init({ service: 'my-app', logger })\n *\n * // Logs automatically include traceId/spanId and export via OTLP!\n * logger.info('User created', { userId: '123' })\n * ```\n *\n * @example Using Winston\n * ```typescript\n * import winston from 'winston' // npm install winston\n * import { init } from 'autotel'\n *\n * const logger = winston.createLogger({\n * level: 'info',\n * format: winston.format.json()\n * })\n * init({ service: 'my-app', logger })\n * ```\n *\n * @example Custom logger (any logger with 4 methods)\n * ```typescript\n * const logger = {\n * info: (msg, extra) => console.log(msg, extra),\n * warn: (msg, extra) => console.warn(msg, extra),\n * error: (msg, err, extra) => console.error(msg, err, extra),\n * debug: (msg, extra) => console.debug(msg, extra),\n * }\n * init({ service: 'my-app', logger })\n * ```\n */\n logger?: Logger;\n\n /**\n * Automatically flush events queue when root spans end\n * - true: Auto-flush on root span completion (default)\n * - false: Use batching (events flush every 10 seconds automatically)\n *\n * Only flushes on root spans to avoid excessive network calls.\n * Default is true for serverless/short-lived processes. Set to false\n * for long-running services where batching is more efficient.\n */\n autoFlushEvents?: boolean;\n\n /**\n * Include OpenTelemetry span flushing in auto-flush (default: false)\n *\n * When enabled, spans are force-flushed along with events events on root\n * span completion. This is useful for serverless/short-lived processes where\n * spans may not export before the process ends.\n *\n * - true: Force-flush spans on root span completion (~50-200ms latency)\n * - false: Spans export via normal batch processor (default behavior)\n *\n * Only applies when autoFlushEvents is also enabled.\n *\n * Note: For edge runtimes (Cloudflare Workers, Vercel Edge), use the\n * 'autotel-edge' package instead, which handles this automatically.\n *\n * @example Serverless with auto-flush\n * ```typescript\n * init({\n * service: 'my-lambda',\n * autoFlushEvents: true,\n * autoFlush: true, // Force-flush spans\n * });\n * ```\n */\n autoFlush?: boolean;\n\n /**\n * Automatically copy baggage entries to span attributes\n *\n * When enabled, all baggage entries are automatically added as span attributes,\n * making them visible in trace UIs (Jaeger, Grafana, DataDog, etc.) without\n * manually calling ctx.setAttribute() for each entry.\n *\n * - `true`: adds baggage with 'baggage.' prefix (e.g. baggage.tenant.id)\n * - `string`: uses custom prefix (e.g. 'ctx' → ctx.tenant.id, '' → tenant.id)\n * - `false` or omit: disabled (default)\n *\n * @default false\n *\n * @example Enable with default prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: true\n * });\n *\n * // Now baggage automatically appears as span attributes\n * await withBaggage({\n * baggage: { 'tenant.id': 't1', 'user.id': 'u1' },\n * fn: async () => {\n * // Span has baggage.tenant.id and baggage.user.id attributes!\n * }\n * });\n * ```\n *\n * @example Custom prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: 'ctx' // Uses 'ctx.' prefix\n * });\n * // Creates attributes: ctx.tenant.id, ctx.user.id\n * ```\n *\n * @example No prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: '' // No prefix\n * });\n * // Creates attributes: tenant.id, user.id\n * ```\n */\n baggage?: boolean | string;\n\n /**\n * Validation configuration for events events\n * - Override default sensitive field patterns for redaction\n * - Customize max lengths, nesting depth, etc.\n *\n * @example Disable redaction for development\n * ```typescript\n * init({\n * service: 'my-app',\n * validation: {\n * sensitivePatterns: [] // Disable all redaction\n * }\n * })\n * ```\n *\n * @example Add custom patterns\n * ```typescript\n * init({\n * service: 'my-app',\n * validation: {\n * sensitivePatterns: [\n * /password/i,\n * /apiKey/i,\n * /customSecret/i // Your custom pattern\n * ]\n * }\n * })\n * ```\n */\n validation?: Partial<ValidationConfig>;\n\n /**\n * Debug mode for local span inspection.\n * Enables console output to help you see spans as they're created.\n *\n * When true: Outputs spans to console AND sends to backend (if endpoint/exporter configured)\n * When false/undefined: Sends to backend only (default behavior)\n *\n * Perfect for progressive development:\n * - Start with debug: true (no endpoint) → console-only, see traces immediately\n * - Add endpoint later → console + backend, verify before choosing provider\n * - Remove debug in production → backend only, clean production config\n *\n * Can be overridden with AUTOLEMETRY_DEBUG environment variable.\n *\n * @example Getting started - see spans immediately\n * ```typescript\n * init({\n * service: 'my-app',\n * debug: true // No endpoint yet - console only!\n * })\n * ```\n *\n * @example Testing with local collector\n * ```typescript\n * init({\n * service: 'my-app',\n * debug: true,\n * endpoint: 'http://localhost:4318' // Console + OTLP\n * })\n * ```\n *\n * @example Production debugging\n * ```typescript\n * init({\n * service: 'my-app',\n * debug: true, // See what's being sent\n * endpoint: 'https://api.honeycomb.io'\n * })\n * ```\n *\n * @example Environment variable\n * ```bash\n * AUTOLEMETRY_DEBUG=true node server.js\n * ```\n */\n debug?: boolean;\n\n /**\n * OpenLLMetry integration for LLM observability.\n * Requires @traceloop/node-server-sdk as an optional peer dependency.\n *\n * @example Enable OpenLLMetry with default settings\n * ```typescript\n * init({\n * service: 'my-app',\n * openllmetry: { enabled: true }\n * })\n * ```\n *\n * @example Enable with custom options\n * ```typescript\n * init({\n * service: 'my-app',\n * openllmetry: {\n * enabled: true,\n * options: {\n * disableBatch: process.env.NODE_ENV !== 'production',\n * apiKey: process.env.TRACELOOP_API_KEY\n * }\n * }\n * })\n * ```\n */\n openllmetry?: {\n enabled: boolean;\n options?: Record<string, unknown>;\n };\n}\n\n// Internal state\nlet initialized = false;\nlet config: AutotelConfig | null = null;\nlet sdk: NodeSDK | null = null;\nlet warnedOnce = false;\nlet logger: Logger = silentLogger;\nlet validationConfig: Partial<ValidationConfig> | null = null;\n\n/**\n * Resolve metrics flag with env var override support\n */\nexport function resolveMetricsFlag(\n configFlag: boolean | 'auto' = 'auto',\n): boolean {\n // 1. Check env var override (highest priority)\n const envFlag = process.env.AUTOTELEMETRY_METRICS;\n if (envFlag === 'on' || envFlag === 'true') return true;\n if (envFlag === 'off' || envFlag === 'false') return false;\n\n // 2. Check config flag\n if (configFlag === true) return true;\n if (configFlag === false) return false;\n\n // 3. Default: enabled in all environments (simpler)\n return true;\n}\n\n/**\n * Resolve debug flag with env var override support\n */\nexport function resolveDebugFlag(configFlag?: boolean): boolean {\n // 1. Check env var override (highest priority)\n const envFlag = process.env.AUTOLEMETRY_DEBUG;\n if (envFlag === 'true' || envFlag === '1') return true;\n if (envFlag === 'false' || envFlag === '0') return false;\n\n // 2. Return config flag (defaults to false)\n return configFlag ?? false;\n}\n\nfunction normalizeOtlpHeaders(\n headers?: Record<string, string> | string,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n if (typeof headers !== 'string') return headers;\n\n const parsed: Record<string, string> = {};\n for (const pair of headers.split(',')) {\n const [key, ...valueParts] = pair.split('=');\n if (!key || valueParts.length === 0) continue;\n parsed[key.trim()] = valueParts.join('=').trim();\n }\n return parsed;\n}\n\n/**\n * Initialize autotel - Write Once, Observe Everywhere\n *\n * Follows OpenTelemetry standards: opinionated defaults with full flexibility\n * Idempotent: multiple calls are safe, last one wins\n *\n * @example Minimal setup (OTLP default)\n * ```typescript\n * init({ service: 'my-app' })\n * ```\n *\n * @example With events (observe in PostHog, Mixpanel, etc.)\n * ```typescript\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * init({\n * service: 'my-app',\n * subscribers: [new PostHogSubscriber({ apiKey: '...' })]\n * })\n * ```\n *\n * @example Observe in Jaeger\n * ```typescript\n * import { JaegerExporter } from '@opentelemetry/exporter-jaeger'\n *\n * init({\n * service: 'my-app',\n * spanExporter: new JaegerExporter({ endpoint: 'http://localhost:14268/api/traces' })\n * })\n * ```\n *\n * @example Observe in Zipkin\n * ```typescript\n * import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'\n *\n * init({\n * service: 'my-app',\n * spanExporter: new ZipkinExporter({ url: 'http://localhost:9411/api/v2/spans' })\n * })\n * ```\n *\n * @example Observe in Datadog\n * ```typescript\n * import { DatadogSpanProcessor } from '@opentelemetry/exporter-datadog'\n *\n * init({\n * service: 'my-app',\n * spanProcessor: new DatadogSpanProcessor({ ... })\n * })\n * ```\n *\n * @example Console output (dev)\n * ```typescript\n * import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\n *\n * init({\n * service: 'my-app',\n * spanProcessor: new SimpleSpanProcessor(new ConsoleSpanExporter())\n * })\n * ```\n */\n\n/**\n * Auto-detect logger type and return appropriate instrumentation\n * Detects Pino and Winston loggers based on their unique properties\n */\nfunction createLoggerInstrumentation(\n logger: Logger,\n): PinoInstrumentation | WinstonInstrumentation | null {\n // Type guard: check for Pino-specific properties\n // Pino has 'child' and 'bindings' methods\n if (\n 'child' in logger &&\n 'bindings' in logger &&\n typeof logger.child === 'function'\n ) {\n return new PinoInstrumentation();\n }\n\n // Type guard: check for Winston-specific properties\n // Winston has 'transports' array or 'defaultMeta' property\n if ('transports' in logger || 'defaultMeta' in logger) {\n return new WinstonInstrumentation();\n }\n\n // Unknown logger type - no instrumentation\n return null;\n}\n\nexport function init(cfg: AutotelConfig): void {\n // Resolve environment variables (standard OTEL env vars)\n const envConfig = resolveConfigFromEnv();\n\n // Merge configs: explicit config > env vars > defaults\n // Note: We merge envConfig first, then cfg overrides it\n const mergedConfig: AutotelConfig = {\n ...envConfig,\n ...cfg,\n // Deep merge for resourceAttributes\n resourceAttributes: {\n ...envConfig.resourceAttributes,\n ...cfg.resourceAttributes,\n },\n // Handle otlpHeaders merge (can be string or object)\n otlpHeaders:\n cfg.otlpHeaders === undefined\n ? envConfig.otlpHeaders === undefined\n ? undefined\n : envConfig.otlpHeaders\n : cfg.otlpHeaders,\n } as AutotelConfig;\n\n // Set logger (use provided or default to silent)\n logger = mergedConfig.logger || silentLogger;\n\n // Warn if re-initializing (same behavior in all environments)\n if (initialized) {\n logger.warn(\n '[autotel] init() called again - last config wins. This may cause unexpected behavior.',\n );\n }\n\n config = mergedConfig;\n validationConfig = mergedConfig.validation || null;\n\n // Initialize OpenTelemetry\n // Only use endpoint if explicitly configured (no default fallback)\n const endpoint = mergedConfig.endpoint;\n const otlpHeaders = normalizeOtlpHeaders(mergedConfig.otlpHeaders);\n const version = mergedConfig.version || detectVersion();\n const environment =\n mergedConfig.environment || process.env.NODE_ENV || 'development';\n const metricsEnabled = resolveMetricsFlag(mergedConfig.metrics);\n\n // Detect hostname for proper Datadog correlation and Service Catalog discovery\n const hostname = detectHostname();\n\n let resource = resourceFromAttributes({\n [ATTR_SERVICE_NAME]: cfg.service,\n [ATTR_SERVICE_VERSION]: version,\n // Support both old and new OpenTelemetry semantic conventions for environment\n 'deployment.environment': environment, // Deprecated but widely supported\n 'deployment.environment.name': environment, // OTel v1.27.0+ standard\n });\n\n // Add hostname attributes for Datadog Service Catalog and infrastructure correlation\n if (hostname) {\n resource = resource.merge(\n resourceFromAttributes({\n 'host.name': hostname, // OpenTelemetry standard\n 'datadog.host.name': hostname, // Datadog-specific, highest priority for Datadog\n }),\n );\n }\n\n if (cfg.resource) {\n resource = resource.merge(cfg.resource);\n }\n\n if (cfg.resourceAttributes) {\n resource = resource.merge(resourceFromAttributes(cfg.resourceAttributes));\n }\n\n // Resolve OTLP protocol (http or grpc)\n const protocol = resolveProtocol(cfg.protocol);\n\n // Build array of span processors (supports multiple)\n const spanProcessors: SpanProcessor[] = [];\n\n if (cfg.spanProcessors && cfg.spanProcessors.length > 0) {\n // User provided custom processors (full control)\n spanProcessors.push(...cfg.spanProcessors);\n } else if (cfg.spanExporters && cfg.spanExporters.length > 0) {\n // User provided custom exporters (wrap each with tail sampling)\n for (const exporter of cfg.spanExporters) {\n spanProcessors.push(\n new TailSamplingSpanProcessor(new BatchSpanProcessor(exporter)),\n );\n }\n } else if (endpoint) {\n // Default: OTLP with tail sampling (only if endpoint is configured)\n const traceExporter = createTraceExporter(protocol, {\n url: formatEndpointUrl(endpoint, 'traces', protocol),\n headers: otlpHeaders,\n });\n\n spanProcessors.push(\n new TailSamplingSpanProcessor(new BatchSpanProcessor(traceExporter)),\n );\n }\n // If no endpoint and no custom processors/exporters, array remains empty\n // SDK will still work but won't export traces\n\n // Add baggage span processor if enabled\n if (cfg.baggage) {\n const prefix =\n typeof cfg.baggage === 'string'\n ? cfg.baggage\n ? `${cfg.baggage}.`\n : ''\n : 'baggage.';\n spanProcessors.push(new BaggageSpanProcessor({ prefix }));\n }\n\n // Apply debug mode configuration\n const debugMode = resolveDebugFlag(cfg.debug);\n\n if (debugMode) {\n // Debug enabled: add console processor\n spanProcessors.push(new SimpleSpanProcessor(new ConsoleSpanExporter()));\n }\n\n // Build array of metric readers (supports multiple)\n const metricReaders: MetricReader[] = [];\n\n if (cfg.metricReaders && cfg.metricReaders.length > 0) {\n // User provided custom metric readers\n metricReaders.push(...cfg.metricReaders);\n } else if (metricsEnabled && endpoint) {\n // Default: OTLP metrics exporter (only if endpoint is configured)\n const metricExporter = createMetricExporter(protocol, {\n url: formatEndpointUrl(endpoint, 'metrics', protocol),\n headers: otlpHeaders,\n });\n\n metricReaders.push(\n new PeriodicExportingMetricReader({\n exporter: metricExporter,\n }),\n );\n }\n\n let logRecordProcessors: LogRecordProcessor[] | undefined;\n if (cfg.logRecordProcessors && cfg.logRecordProcessors.length > 0) {\n logRecordProcessors = [...cfg.logRecordProcessors];\n }\n\n // Handle instrumentations: merge manual instrumentations with auto-integrations\n let finalInstrumentations: NodeSDKConfiguration['instrumentations'] =\n cfg.instrumentations ? [...cfg.instrumentations] : [];\n\n // Auto-enable logger instrumentation if a logger is provided\n if (cfg.logger) {\n const loggerInstrumentation = createLoggerInstrumentation(cfg.logger);\n if (loggerInstrumentation) {\n finalInstrumentations = [...finalInstrumentations, loggerInstrumentation];\n logger.debug(\n `[autotel] Auto-enabled ${loggerInstrumentation.constructor.name} for logger`,\n );\n }\n }\n\n if (cfg.integrations !== undefined) {\n try {\n // Detect manual instrumentations to avoid conflicts\n const manualInstrumentationNames = getInstrumentationNames(\n cfg.instrumentations ?? [],\n );\n\n // Warn if both integrations and manual instrumentations are provided\n if (\n manualInstrumentationNames.size > 0 &&\n cfg.integrations !== false &&\n cfg.integrations !== undefined\n ) {\n const manualNames = [...manualInstrumentationNames].join(', ');\n logger.info(\n `[autotel] Detected manual instrumentations (${manualNames}). ` +\n 'These will take precedence over auto-instrumentations. ' +\n 'Tip: Set integrations:false if you want full manual control, or remove manual configs to use auto-instrumentations.',\n );\n }\n\n const autoInstrumentations = getAutoInstrumentations(\n cfg.integrations,\n manualInstrumentationNames,\n );\n if (autoInstrumentations && autoInstrumentations.length > 0) {\n // Cast to proper type - getNodeAutoInstrumentations returns the correct type\n finalInstrumentations = [\n ...finalInstrumentations,\n ...(autoInstrumentations as NodeSDKConfiguration['instrumentations']),\n ];\n }\n } catch (error) {\n logger.warn(\n `[autotel] Failed to configure auto-instrumentations: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n const sdkOptions: Partial<NodeSDKConfiguration> = {\n resource,\n instrumentations: finalInstrumentations,\n };\n\n if (spanProcessors.length > 0) {\n sdkOptions.spanProcessors = spanProcessors;\n }\n\n if (metricReaders.length > 0) {\n sdkOptions.metricReaders = metricReaders;\n }\n\n if (logRecordProcessors && logRecordProcessors.length > 0) {\n sdkOptions.logRecordProcessors = logRecordProcessors;\n }\n\n sdk = cfg.sdkFactory ? cfg.sdkFactory(sdkOptions) : new NodeSDK(sdkOptions);\n\n if (!sdk) {\n throw new Error('[autotel] sdkFactory must return a NodeSDK instance');\n }\n\n sdk.start();\n\n // Initialize OpenLLMetry if enabled (after SDK starts to reuse tracer provider)\n if (cfg.openllmetry?.enabled) {\n // Try synchronous initialization first (for require-based modules)\n let initializedSync = false;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const traceloop = require('@traceloop/node-server-sdk');\n const initOptions: Record<string, unknown> = {\n ...cfg.openllmetry.options,\n };\n\n // Reuse autotel's tracer provider\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 tracerProvider = (sdk as any).getTracerProvider();\n initOptions.tracerProvider = tracerProvider;\n } catch {\n // Ignore if tracer provider not available\n }\n\n if (typeof traceloop.initialize === 'function') {\n traceloop.initialize(initOptions);\n logger.info('[autotel] OpenLLMetry initialized successfully');\n initializedSync = true;\n }\n } catch (error) {\n // If require fails, try async import (for ESM modules or when module not found)\n if (\n error instanceof Error &&\n (error.message.includes('Cannot find module') ||\n error.message.includes('Module not found') ||\n error.message.includes('Cannot resolve module') ||\n error.message.includes('Dynamic require'))\n ) {\n // Try async import as fallback - this will work with ESM/tsx and mocks in tests\n initializeOpenLLMetry(\n cfg.openllmetry.options,\n sdk,\n cfg.spanExporters?.[0], // Pass first exporter if available\n ).catch((error_) => {\n logger.warn(\n `[autotel] OpenLLMetry initialization error: ${error_ instanceof Error ? error_.message : String(error_)}`,\n );\n });\n } else if (!initializedSync) {\n logger.warn(\n `[autotel] Failed to initialize OpenLLMetry: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n initialized = true;\n}\n\n/**\n * Initialize OpenLLMetry integration\n * Dynamically imports @traceloop/node-server-sdk and initializes it\n * Returns a promise but can be called without awaiting (fire-and-forget)\n */\nasync function initializeOpenLLMetry(\n options?: Record<string, unknown>,\n sdkInstance?: NodeSDK,\n spanExporter?: SpanExporter,\n): Promise<void> {\n try {\n // Try synchronous require first (for testing/mocking), then fall back to dynamic import\n let traceloop: {\n initialize?: (options?: Record<string, unknown>) => void;\n instrumentations?: unknown[];\n };\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n traceloop = require('@traceloop/node-server-sdk');\n } catch {\n // Fall back to dynamic import if require fails (ESM modules)\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - optional peer dependency\n traceloop = await import('@traceloop/node-server-sdk');\n }\n\n // Prepare initialization options\n const initOptions: Record<string, unknown> = {\n ...options,\n };\n\n // Pass span exporter to OpenLLMetry if provided\n // This ensures OpenLLMetry uses the same exporter as autotel\n if (spanExporter) {\n initOptions.exporter = spanExporter;\n }\n\n // Reuse autotel's tracer provider if SDK is available\n if (sdkInstance) {\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 tracerProvider = (sdkInstance as any).getTracerProvider();\n initOptions.tracerProvider = tracerProvider;\n } catch (error) {\n logger.debug(\n `[autotel] Could not get tracer provider for OpenLLMetry: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n // Initialize OpenLLMetry\n if (typeof traceloop.initialize === 'function') {\n traceloop.initialize(initOptions);\n logger.info('[autotel] OpenLLMetry initialized successfully');\n } else {\n logger.warn(\n '[autotel] OpenLLMetry initialize function not found. Check @traceloop/node-server-sdk version.',\n );\n }\n } catch (error) {\n // Gracefully handle missing dependency\n if (\n error instanceof Error &&\n (error.message.includes('Cannot find module') ||\n error.message.includes('Module not found') ||\n error.message.includes('Cannot resolve module'))\n ) {\n logger.warn(\n '[autotel] OpenLLMetry enabled but @traceloop/node-server-sdk is not installed. ' +\n 'Install it as a peer dependency to use OpenLLMetry integration.',\n );\n } else {\n logger.warn(\n `[autotel] Failed to initialize OpenLLMetry: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n}\n\n/**\n * Extract instrumentation class names from instrumentation instances\n * Used to detect duplicates between manual and auto instrumentations\n */\nfunction getInstrumentationNames(\n instrumentations: NodeSDKConfiguration['instrumentations'],\n): Set<string> {\n const names = new Set<string>();\n\n if (!instrumentations) return names;\n\n for (const instrumentation of instrumentations) {\n if (instrumentation && typeof instrumentation === 'object') {\n names.add(instrumentation.constructor.name);\n }\n }\n\n return names;\n}\n\n/**\n * Map common instrumentation class names to their package names\n * Used to disable auto-instrumentations when user provides manual configs\n */\nconst INSTRUMENTATION_CLASS_TO_PACKAGE: Record<string, string> = {\n HttpInstrumentation: '@opentelemetry/instrumentation-http',\n HttpsInstrumentation: '@opentelemetry/instrumentation-http',\n ExpressInstrumentation: '@opentelemetry/instrumentation-express',\n FastifyInstrumentation: '@opentelemetry/instrumentation-fastify',\n MongoDBInstrumentation: '@opentelemetry/instrumentation-mongodb',\n MongooseInstrumentation: '@opentelemetry/instrumentation-mongoose',\n PrismaInstrumentation: '@opentelemetry/instrumentation-prisma',\n PinoInstrumentation: '@opentelemetry/instrumentation-pino',\n WinstonInstrumentation: '@opentelemetry/instrumentation-winston',\n RedisInstrumentation: '@opentelemetry/instrumentation-redis',\n GraphQLInstrumentation: '@opentelemetry/instrumentation-graphql',\n GrpcInstrumentation: '@opentelemetry/instrumentation-grpc',\n IORedisInstrumentation: '@opentelemetry/instrumentation-ioredis',\n KnexInstrumentation: '@opentelemetry/instrumentation-knex',\n NestJsInstrumentation: '@opentelemetry/instrumentation-nestjs-core',\n PgInstrumentation: '@opentelemetry/instrumentation-pg',\n MySQLInstrumentation: '@opentelemetry/instrumentation-mysql',\n MySQL2Instrumentation: '@opentelemetry/instrumentation-mysql2',\n};\n\n/**\n * Get auto-instrumentations based on simple integration names\n * Excludes instrumentations that are manually provided to avoid conflicts\n */\nfunction getAutoInstrumentations(\n integrations: string[] | boolean | Record<string, { enabled?: boolean }>,\n manualInstrumentationNames: Set<string> = new Set(),\n): unknown[] {\n if (integrations === false) {\n return [];\n }\n\n // Build exclusion config for manual instrumentations\n const exclusionConfig: Record<string, { enabled: boolean }> = {};\n for (const className of manualInstrumentationNames) {\n const packageName = INSTRUMENTATION_CLASS_TO_PACKAGE[className];\n if (packageName) {\n exclusionConfig[packageName] = { enabled: false };\n }\n }\n\n if (integrations === true) {\n // If exclusions exist, pass them to getNodeAutoInstrumentations\n if (Object.keys(exclusionConfig).length > 0) {\n return getNodeAutoInstrumentations(exclusionConfig);\n }\n return getNodeAutoInstrumentations();\n }\n\n if (Array.isArray(integrations)) {\n const config: Record<string, { enabled: boolean }> = { ...exclusionConfig };\n for (const name of integrations) {\n const packageName = `@opentelemetry/instrumentation-${name}`;\n // Don't override exclusions\n if (!exclusionConfig[packageName]) {\n config[packageName] = { enabled: true };\n }\n }\n return getNodeAutoInstrumentations(config);\n }\n\n const config: Record<string, { enabled?: boolean }> = {\n ...exclusionConfig,\n ...integrations,\n };\n\n // Override any integrations that conflict with manual instrumentations\n for (const packageName of Object.keys(exclusionConfig)) {\n const integrationsKey = Object.keys(integrations).find((key) =>\n packageName.includes(key),\n );\n if (integrationsKey) {\n // Manual instrumentation takes precedence\n config[packageName] = { enabled: false };\n }\n }\n\n return getNodeAutoInstrumentations(config);\n}\n\n/**\n * Check if autotel has been initialized\n */\nexport function isInitialized(): boolean {\n return initialized;\n}\n\n/**\n * Get current config (internal use)\n */\nexport function getConfig(): AutotelConfig | null {\n return config;\n}\n\n/**\n * Get current logger (internal use)\n */\nexport function getLogger(): Logger {\n return logger;\n}\n\n/**\n * Get validation config (internal use)\n */\nexport function getValidationConfig(): Partial<ValidationConfig> | null {\n return validationConfig;\n}\n\n/**\n * Warn once if not initialized (same behavior in all environments)\n */\nexport function warnIfNotInitialized(context: string): void {\n if (!initialized && !warnedOnce) {\n logger.warn(\n `[autotel] ${context} used before init() called. ` +\n 'Call init({ service: \"...\" }) first. See: https://docs.autotel.dev/quickstart',\n );\n warnedOnce = true;\n }\n}\n\n/**\n * Get default sampler\n */\nexport function getDefaultSampler(): Sampler {\n return (\n config?.sampler ||\n new AdaptiveSampler({\n baselineSampleRate: 0.1,\n alwaysSampleErrors: true,\n alwaysSampleSlow: true,\n })\n );\n}\n\n/**\n * Auto-detect version from package.json\n */\nfunction detectVersion(): string {\n try {\n // Try to read package.json from cwd using fs\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fs = require('node:fs');\n const pkg = JSON.parse(\n fs.readFileSync(`${process.cwd()}/package.json`, 'utf8'),\n );\n return pkg.version || '1.0.0';\n } catch {\n return '1.0.0';\n }\n}\n\n/**\n * Detect hostname for resource attributes.\n * Supports Datadog conventions (DD_HOSTNAME) and falls back to system hostname.\n *\n * Priority order:\n * 1. DD_HOSTNAME environment variable (Datadog convention)\n * 2. HOSTNAME environment variable (common Unix convention)\n * 3. os.hostname() (system hostname)\n *\n * @returns hostname string or undefined if detection fails\n */\nfunction detectHostname(): string | undefined {\n // Priority 1: DD_HOSTNAME (Datadog convention)\n if (process.env.DD_HOSTNAME) {\n return process.env.DD_HOSTNAME;\n }\n\n // Priority 2: HOSTNAME (common in containers and Unix systems)\n if (process.env.HOSTNAME) {\n return process.env.HOSTNAME;\n }\n\n // Priority 3: System hostname\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const os = require('node:os') as typeof import('node:os');\n return os.hostname();\n } catch {\n // os module not available (edge runtime, browser, etc.)\n return undefined;\n }\n}\n\n/**\n * Get SDK instance (for shutdown)\n */\nexport function getSdk(): NodeSDK | null {\n return sdk;\n}\n"]}
@@ -0,0 +1,95 @@
1
+ import { trace } from './chunk-RJYY7BWX.js';
2
+
3
+ // src/semantic-helpers.ts
4
+ function traceLLM(config) {
5
+ return (fnFactory) => {
6
+ return trace((ctx) => {
7
+ ctx.setAttribute("gen.ai.request.model", config.model);
8
+ ctx.setAttribute("gen.ai.operation.name", config.operation || "chat");
9
+ if (config.system) {
10
+ ctx.setAttribute("gen.ai.system", config.system);
11
+ }
12
+ if (config.attributes) {
13
+ for (const [key, value] of Object.entries(config.attributes)) {
14
+ if (value !== void 0 && value !== null) {
15
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
16
+ ctx.setAttribute(key, attrValue);
17
+ }
18
+ }
19
+ }
20
+ return fnFactory(ctx);
21
+ });
22
+ };
23
+ }
24
+ function traceDB(config) {
25
+ return (fnFactory) => {
26
+ return trace((ctx) => {
27
+ ctx.setAttribute("db.system", config.system);
28
+ if (config.operation) {
29
+ ctx.setAttribute("db.operation", config.operation);
30
+ }
31
+ if (config.dbName) {
32
+ ctx.setAttribute("db.name", config.dbName);
33
+ }
34
+ if (config.collection) {
35
+ ctx.setAttribute("db.collection.name", config.collection);
36
+ }
37
+ if (config.attributes) {
38
+ for (const [key, value] of Object.entries(config.attributes)) {
39
+ if (value !== void 0 && value !== null) {
40
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
41
+ ctx.setAttribute(key, attrValue);
42
+ }
43
+ }
44
+ }
45
+ return fnFactory(ctx);
46
+ });
47
+ };
48
+ }
49
+ function traceHTTP(config) {
50
+ return (fnFactory) => {
51
+ return trace((ctx) => {
52
+ if (config.method) {
53
+ ctx.setAttribute("http.request.method", config.method);
54
+ }
55
+ if (config.url) {
56
+ ctx.setAttribute("url.full", config.url);
57
+ }
58
+ if (config.attributes) {
59
+ for (const [key, value] of Object.entries(config.attributes)) {
60
+ if (value !== void 0 && value !== null) {
61
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
62
+ ctx.setAttribute(key, attrValue);
63
+ }
64
+ }
65
+ }
66
+ return fnFactory(ctx);
67
+ });
68
+ };
69
+ }
70
+ function traceMessaging(config) {
71
+ return (fnFactory) => {
72
+ return trace((ctx) => {
73
+ ctx.setAttribute("messaging.system", config.system);
74
+ if (config.operation) {
75
+ ctx.setAttribute("messaging.operation", config.operation);
76
+ }
77
+ if (config.destination) {
78
+ ctx.setAttribute("messaging.destination.name", config.destination);
79
+ }
80
+ if (config.attributes) {
81
+ for (const [key, value] of Object.entries(config.attributes)) {
82
+ if (value !== void 0 && value !== null) {
83
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
84
+ ctx.setAttribute(key, attrValue);
85
+ }
86
+ }
87
+ }
88
+ return fnFactory(ctx);
89
+ });
90
+ };
91
+ }
92
+
93
+ export { traceDB, traceHTTP, traceLLM, traceMessaging };
94
+ //# sourceMappingURL=chunk-BWYGJKRB.js.map
95
+ //# sourceMappingURL=chunk-BWYGJKRB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/semantic-helpers.ts"],"names":[],"mappings":"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","file":"chunk-BWYGJKRB.js","sourcesContent":["/**\n * Semantic convention helpers for OpenTelemetry\n *\n * Pre-configured trace helpers that follow OpenTelemetry semantic conventions\n * for common operation types. Reduces boilerplate and ensures consistency.\n *\n * Based on: https://opentelemetry.io/docs/specs/semconv/\n */\n\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport type { Attributes } from '@opentelemetry/api';\n\n/**\n * Configuration for LLM (Large Language Model) operations\n *\n * Follows Gen AI semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/gen-ai/\n */\nexport interface LLMConfig {\n /** Model name (e.g., 'gpt-4', 'claude-3-opus') */\n model: string;\n /** Operation type */\n operation?: 'chat' | 'completion' | 'embedding';\n /** Model provider (e.g., 'openai', 'anthropic', 'cohere') */\n system?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for database operations\n *\n * Follows DB semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/database/\n */\nexport interface DBConfig {\n /** Database system (e.g., 'postgresql', 'mongodb', 'redis') */\n system: string;\n /** Operation type (e.g., 'SELECT', 'INSERT', 'find', 'get') */\n operation?: string;\n /** Database name */\n dbName?: string;\n /** Collection/table name */\n collection?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for HTTP client operations\n *\n * Follows HTTP semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/http/\n */\nexport interface HTTPConfig {\n /** HTTP method (e.g., 'GET', 'POST') */\n method?: string;\n /** Target URL or URL template */\n url?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for messaging operations\n *\n * Follows Messaging semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/messaging/\n */\nexport interface MessagingConfig {\n /** Messaging system (e.g., 'kafka', 'rabbitmq', 'sqs') */\n system: string;\n /** Operation type */\n operation?: 'publish' | 'receive' | 'process';\n /** Destination name (queue/topic) */\n destination?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Trace LLM operations with Gen AI semantic conventions\n *\n * Automatically adds standard attributes for LLM operations:\n * - gen.ai.request.model\n * - gen.ai.operation.name\n * - gen.ai.system\n *\n * **Use Cases:**\n * - Chat completions\n * - Text generation\n * - Embeddings\n * - Multi-step LLM workflows\n *\n * @param config - LLM operation configuration\n * @returns Traced function factory with Gen AI attributes\n *\n * @example Chat completion with OpenAI\n * ```typescript\n * import { traceLLM } from 'autotel/semantic-helpers'\n * import OpenAI from 'openai'\n *\n * const openai = new OpenAI()\n *\n * export const generateResponse = traceLLM({\n * model: 'gpt-4-turbo',\n * operation: 'chat',\n * system: 'openai'\n * })(ctx => async (prompt: string) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [{ role: 'user', content: prompt }]\n * })\n *\n * // Add usage metrics to span\n * ctx.setAttribute('gen.ai.usage.completion_tokens', response.usage?.completion_tokens)\n * ctx.setAttribute('gen.ai.usage.prompt_tokens', response.usage?.prompt_tokens)\n *\n * return response.choices[0].message.content\n * })\n * ```\n *\n * @example Anthropic Claude with streaming\n * ```typescript\n * import { traceLLM } from 'autotel/semantic-helpers'\n * import Anthropic from '@anthropic-ai/sdk'\n *\n * const anthropic = new Anthropic()\n *\n * export const streamResponse = traceLLM({\n * model: 'claude-3-opus-20240229',\n * operation: 'chat',\n * system: 'anthropic'\n * })(ctx => async function* (prompt: string) {\n * const stream = await anthropic.messages.create({\n * model: 'claude-3-opus-20240229',\n * messages: [{ role: 'user', content: prompt }],\n * stream: true,\n * max_tokens: 1024\n * })\n *\n * let totalTokens = 0\n * for await (const event of stream) {\n * if (event.type === 'content_block_delta') {\n * yield event.delta.text\n * }\n * if (event.type === 'message_stop') {\n * ctx.setAttribute('gen.ai.usage.completion_tokens', event.message.usage.output_tokens)\n * totalTokens = event.message.usage.output_tokens\n * }\n * }\n *\n * return totalTokens\n * })\n * ```\n *\n * @example Embeddings\n * ```typescript\n * import { traceLLM } from 'autotel/semantic-helpers'\n * import { OpenAIEmbeddings } from '@langchain/openai'\n *\n * const embeddings = new OpenAIEmbeddings()\n *\n * export const embed = traceLLM({\n * model: 'text-embedding-3-small',\n * operation: 'embedding',\n * system: 'openai'\n * })(ctx => async (text: string) => {\n * const result = await embeddings.embedQuery(text)\n * ctx.setAttribute('gen.ai.response.embedding_length', result.length)\n * return result\n * })\n * ```\n *\n * @public\n */\nexport function traceLLM<TArgs extends unknown[], TReturn>(config: LLMConfig) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('gen.ai.request.model', config.model);\n ctx.setAttribute('gen.ai.operation.name', config.operation || 'chat');\n if (config.system) {\n ctx.setAttribute('gen.ai.system', config.system);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n\n/**\n * Trace database operations with DB semantic conventions\n *\n * Automatically adds standard attributes for database operations:\n * - db.system\n * - db.operation\n * - db.name\n * - db.collection.name (for NoSQL)\n *\n * **Use Cases:**\n * - SQL queries (PostgreSQL, MySQL, SQLite)\n * - NoSQL operations (MongoDB, DynamoDB, Redis)\n * - ORM queries (Prisma, TypeORM, Drizzle)\n *\n * @param config - Database operation configuration\n * @returns Traced function factory with DB attributes\n *\n * @example PostgreSQL query\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { pool } from './db'\n *\n * export const getUser = traceDB({\n * system: 'postgresql',\n * operation: 'SELECT',\n * dbName: 'app_db',\n * collection: 'users'\n * })(ctx => async (userId: string) => {\n * const query = 'SELECT * FROM users WHERE id = $1'\n * ctx.setAttribute('db.statement', query)\n *\n * const result = await pool.query(query, [userId])\n * ctx.setAttribute('db.rows_affected', result.rowCount)\n *\n * return result.rows[0]\n * })\n * ```\n *\n * @example MongoDB with Mongoose\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { User } from './models/User'\n *\n * export const findUsers = traceDB({\n * system: 'mongodb',\n * operation: 'find',\n * dbName: 'app_db',\n * collection: 'users'\n * })(ctx => async (filter: object) => {\n * ctx.setAttribute('db.mongodb.filter', JSON.stringify(filter))\n *\n * const users = await User.find(filter).limit(100)\n * ctx.setAttribute('db.response.count', users.length)\n *\n * return users\n * })\n * ```\n *\n * @example Redis operations\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { redis } from './redis'\n *\n * export const cacheGet = traceDB({\n * system: 'redis',\n * operation: 'GET'\n * })(ctx => async (key: string) => {\n * ctx.setAttribute('db.redis.key', key)\n *\n * const value = await redis.get(key)\n * ctx.setAttribute('db.response.cache_hit', value !== null)\n *\n * return value\n * })\n * ```\n *\n * @example Prisma with detailed query info\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { prisma } from './prisma'\n *\n * export const createPost = traceDB({\n * system: 'postgresql',\n * operation: 'INSERT',\n * dbName: 'app_db',\n * collection: 'posts'\n * })(ctx => async (data: { title: string; content: string; authorId: string }) => {\n * ctx.setAttribute('db.prisma.model', 'Post')\n * ctx.setAttribute('db.prisma.action', 'create')\n *\n * const post = await prisma.post.create({ data })\n *\n * ctx.setAttribute('db.response.id', post.id)\n * return post\n * })\n * ```\n *\n * @public\n */\nexport function traceDB<TArgs extends unknown[], TReturn>(config: DBConfig) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('db.system', config.system);\n if (config.operation) {\n ctx.setAttribute('db.operation', config.operation);\n }\n if (config.dbName) {\n ctx.setAttribute('db.name', config.dbName);\n }\n if (config.collection) {\n ctx.setAttribute('db.collection.name', config.collection);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n\n/**\n * Trace HTTP client operations with HTTP semantic conventions\n *\n * Automatically adds standard attributes for HTTP requests:\n * - http.request.method\n * - url.full\n *\n * **Use Cases:**\n * - External API calls\n * - Microservice communication\n * - Third-party integrations\n *\n * @param config - HTTP operation configuration\n * @returns Traced function factory with HTTP attributes\n *\n * @example Fetch API\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n *\n * export const fetchUser = traceHTTP({\n * method: 'GET',\n * url: 'https://api.example.com/users/:id'\n * })(ctx => async (userId: string) => {\n * const url = `https://api.example.com/users/${userId}`\n * ctx.setAttribute('url.full', url)\n *\n * const response = await fetch(url)\n * ctx.setAttribute('http.response.status_code', response.status)\n *\n * if (!response.ok) {\n * ctx.setAttribute('error', true)\n * throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n * }\n *\n * return response.json()\n * })\n * ```\n *\n * @example Axios with retry logic\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n * import axios from 'axios'\n *\n * export const sendWebhook = traceHTTP({\n * method: 'POST',\n * url: 'https://webhook.example.com/events'\n * })(ctx => async (payload: object) => {\n * let attempts = 0\n * const maxAttempts = 3\n *\n * while (attempts < maxAttempts) {\n * try {\n * attempts++\n * ctx.setAttribute('http.request.resend_count', attempts - 1)\n *\n * const response = await axios.post('https://webhook.example.com/events', payload)\n * ctx.setAttribute('http.response.status_code', response.status)\n * return response.data\n * } catch (error) {\n * if (attempts >= maxAttempts) throw error\n * await new Promise(resolve => setTimeout(resolve, 1000 * attempts))\n * }\n * }\n * })\n * ```\n *\n * @public\n */\nexport function traceHTTP<TArgs extends unknown[], TReturn>(\n config: HTTPConfig,\n) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n if (config.method) {\n ctx.setAttribute('http.request.method', config.method);\n }\n if (config.url) {\n ctx.setAttribute('url.full', config.url);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n\n/**\n * Trace messaging operations with Messaging semantic conventions\n *\n * Automatically adds standard attributes for messaging:\n * - messaging.system\n * - messaging.operation\n * - messaging.destination.name\n *\n * **Use Cases:**\n * - Publishing messages to queues/topics\n * - Consuming messages from queues/topics\n * - Event-driven architectures\n *\n * @param config - Messaging operation configuration\n * @returns Traced function factory with Messaging attributes\n *\n * @example Publishing to Kafka\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { kafka } from './kafka'\n *\n * const producer = kafka.producer()\n *\n * export const publishEvent = traceMessaging({\n * system: 'kafka',\n * operation: 'publish',\n * destination: 'user-events'\n * })(ctx => async (event: { type: string; userId: string; data: object }) => {\n * ctx.setAttribute('messaging.message.type', event.type)\n * ctx.setAttribute('messaging.kafka.partition', 0)\n *\n * await producer.send({\n * topic: 'user-events',\n * messages: [\n * {\n * key: event.userId,\n * value: JSON.stringify(event.data)\n * }\n * ]\n * })\n *\n * ctx.setAttribute('messaging.message.id', event.userId)\n * })\n * ```\n *\n * @example Consuming from RabbitMQ\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { channel } from './rabbitmq'\n *\n * export const processOrder = traceMessaging({\n * system: 'rabbitmq',\n * operation: 'process',\n * destination: 'orders'\n * })(ctx => async (message: { orderId: string; items: object[] }) => {\n * ctx.setAttribute('messaging.message.id', message.orderId)\n * ctx.setAttribute('messaging.message.body.size', JSON.stringify(message).length)\n *\n * // Process order logic\n * const result = await processOrderInternal(message)\n *\n * ctx.setAttribute('messaging.operation.result', 'success')\n * return result\n * })\n * ```\n *\n * @example AWS SQS with batch processing\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { SQS } from '@aws-sdk/client-sqs'\n *\n * const sqs = new SQS()\n *\n * export const sendBatch = traceMessaging({\n * system: 'aws_sqs',\n * operation: 'publish',\n * destination: 'notifications-queue'\n * })(ctx => async (messages: Array<{ id: string; body: object }>) => {\n * ctx.setAttribute('messaging.batch.message_count', messages.length)\n *\n * const result = await sqs.sendMessageBatch({\n * QueueUrl: process.env.QUEUE_URL,\n * Entries: messages.map(msg => ({\n * Id: msg.id,\n * MessageBody: JSON.stringify(msg.body)\n * }))\n * })\n *\n * ctx.setAttribute('messaging.operation.success_count', result.Successful?.length || 0)\n * ctx.setAttribute('messaging.operation.failed_count', result.Failed?.length || 0)\n *\n * return result\n * })\n * ```\n *\n * @public\n */\nexport function traceMessaging<TArgs extends unknown[], TReturn>(\n config: MessagingConfig,\n) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('messaging.system', config.system);\n if (config.operation) {\n ctx.setAttribute('messaging.operation', config.operation);\n }\n if (config.destination) {\n ctx.setAttribute('messaging.destination.name', config.destination);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n"]}
@@ -0,0 +1,73 @@
1
+ // src/event-testing.ts
2
+ function createEventCollector() {
3
+ const events = [];
4
+ const funnelSteps = [];
5
+ const outcomes = [];
6
+ const values = [];
7
+ return {
8
+ getEvents() {
9
+ return [...events];
10
+ },
11
+ getFunnelSteps() {
12
+ return [...funnelSteps];
13
+ },
14
+ getOutcomes() {
15
+ return [...outcomes];
16
+ },
17
+ getValues() {
18
+ return [...values];
19
+ },
20
+ clear() {
21
+ events.length = 0;
22
+ funnelSteps.length = 0;
23
+ outcomes.length = 0;
24
+ values.length = 0;
25
+ },
26
+ recordEvent(event) {
27
+ events.push(event);
28
+ },
29
+ recordFunnelStep(step) {
30
+ funnelSteps.push(step);
31
+ },
32
+ recordOutcome(outcome) {
33
+ outcomes.push(outcome);
34
+ },
35
+ recordValue(value) {
36
+ values.push(value);
37
+ }
38
+ };
39
+ }
40
+ function assertEventTracked(options) {
41
+ const events = options.collector.getEvents();
42
+ const matching = events.filter((e) => e.event === options.eventName);
43
+ if (matching.length === 0) {
44
+ throw new Error(`No events found with name: ${options.eventName}`);
45
+ }
46
+ if (options.attributes) {
47
+ const matchingWithAttrs = matching.filter(
48
+ (e) => Object.entries(options.attributes).every(
49
+ ([key, value]) => e.attributes && e.attributes[key] === value
50
+ )
51
+ );
52
+ if (matchingWithAttrs.length === 0) {
53
+ throw new Error(
54
+ `Event ${options.eventName} found but attributes don't match: ${JSON.stringify(options.attributes)}`
55
+ );
56
+ }
57
+ }
58
+ }
59
+ function assertOutcomeTracked(options) {
60
+ const outcomes = options.collector.getOutcomes();
61
+ const matching = outcomes.filter(
62
+ (o) => o.operation === options.operation && o.status === options.status
63
+ );
64
+ if (matching.length === 0) {
65
+ throw new Error(
66
+ `No outcomes found with operation: ${options.operation} and status: ${options.status}`
67
+ );
68
+ }
69
+ }
70
+
71
+ export { assertEventTracked, assertOutcomeTracked, createEventCollector };
72
+ //# sourceMappingURL=chunk-BZHG5IZ4.js.map
73
+ //# sourceMappingURL=chunk-BZHG5IZ4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/event-testing.ts"],"names":[],"mappings":"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","file":"chunk-BZHG5IZ4.js","sourcesContent":["/**\n * Testing utilities for Events\n *\n * Provides in-memory collection of events for testing purposes.\n */\n\nimport type {\n EventAttributes,\n FunnelStatus,\n OutcomeStatus,\n} from './event-subscriber';\n\nexport interface EventData {\n event: string;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\nexport interface EventsFunnelStep {\n funnel: string;\n status: FunnelStatus;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\nexport interface EventsOutcome {\n operation: string;\n status: OutcomeStatus;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\nexport interface EventsValue {\n metric: string;\n value: number;\n attributes?: EventAttributes;\n service: string;\n timestamp: number;\n}\n\n/**\n * In-memory events collector for testing\n */\nexport interface EventCollector {\n /** Get all collected events */\n getEvents(): EventData[];\n /** Get all collected funnel steps */\n getFunnelSteps(): EventsFunnelStep[];\n /** Get all collected outcomes */\n getOutcomes(): EventsOutcome[];\n /** Get all collected values */\n getValues(): EventsValue[];\n /** Clear all collected events */\n clear(): void;\n /** Record an event (internal use) */\n recordEvent(event: EventData): void;\n /** Record a funnel step (internal use) */\n recordFunnelStep(step: EventsFunnelStep): void;\n /** Record an outcome (internal use) */\n recordOutcome(outcome: EventsOutcome): void;\n /** Record a value (internal use) */\n recordValue(value: EventsValue): void;\n}\n\n/**\n * Create an in-memory events collector for testing\n *\n * @example\n * ```typescript\n * const collector = createEventCollector()\n *\n * const events = new Event('test-service', { collector })\n * events.trackEvent('application.submitted', { jobId: '123' })\n *\n * const event =collector.getEvents()\n * expect(events).toHaveLength(1)\n * expect(events[0].event).toBe('application.submitted')\n * ```\n */\nexport function createEventCollector(): EventCollector {\n const events: EventData[] = [];\n const funnelSteps: EventsFunnelStep[] = [];\n const outcomes: EventsOutcome[] = [];\n const values: EventsValue[] = [];\n\n return {\n getEvents(): EventData[] {\n return [...events];\n },\n\n getFunnelSteps(): EventsFunnelStep[] {\n return [...funnelSteps];\n },\n\n getOutcomes(): EventsOutcome[] {\n return [...outcomes];\n },\n\n getValues(): EventsValue[] {\n return [...values];\n },\n\n clear(): void {\n events.length = 0;\n funnelSteps.length = 0;\n outcomes.length = 0;\n values.length = 0;\n },\n\n recordEvent(event: EventData): void {\n events.push(event);\n },\n\n recordFunnelStep(step: EventsFunnelStep): void {\n funnelSteps.push(step);\n },\n\n recordOutcome(outcome: EventsOutcome): void {\n outcomes.push(outcome);\n },\n\n recordValue(value: EventsValue): void {\n values.push(value);\n },\n };\n}\n\n/**\n * Assert that an events event was tracked\n *\n * @example\n * ```typescript\n * assertEventTracked({\n * collector,\n * eventName: 'application.submitted',\n * attributes: { jobId: '123' }\n * })\n * ```\n */\nexport function assertEventTracked(options: {\n collector: EventCollector;\n eventName: string;\n attributes?: Record<string, unknown>;\n}): void {\n const events = options.collector.getEvents();\n const matching = events.filter((e) => e.event === options.eventName);\n\n if (matching.length === 0) {\n throw new Error(`No events found with name: ${options.eventName}`);\n }\n\n if (options.attributes) {\n const matchingWithAttrs = matching.filter((e) =>\n Object.entries(options.attributes!).every(\n ([key, value]) => e.attributes && e.attributes[key] === value,\n ),\n );\n\n if (matchingWithAttrs.length === 0) {\n throw new Error(\n `Event ${options.eventName} found but attributes don't match: ${JSON.stringify(options.attributes)}`,\n );\n }\n }\n}\n\n/**\n * Assert that an outcome was tracked\n *\n * @example\n * ```typescript\n * assertOutcomeTracked({\n * collector,\n * operation: 'email.delivery',\n * status: 'success'\n * })\n * ```\n */\nexport function assertOutcomeTracked(options: {\n collector: EventCollector;\n operation: string;\n status: 'success' | 'failure' | 'partial';\n}): void {\n const outcomes = options.collector.getOutcomes();\n const matching = outcomes.filter(\n (o) => o.operation === options.operation && o.status === options.status,\n );\n\n if (matching.length === 0) {\n throw new Error(\n `No outcomes found with operation: ${options.operation} and status: ${options.status}`,\n );\n }\n}\n"]}
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x + '" is not supported');
12
+ });
13
+ var __esm = (fn, res) => function __init() {
14
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ };
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ exports.__esm = __esm;
31
+ exports.__export = __export;
32
+ exports.__require = __require;
33
+ exports.__toCommonJS = __toCommonJS;
34
+ //# sourceMappingURL=chunk-G7VZBCD6.cjs.map
35
+ //# sourceMappingURL=chunk-G7VZBCD6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-G7VZBCD6.cjs"}
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ // src/tail-sampling-processor.ts
4
+ var TailSamplingSpanProcessor = class {
5
+ wrappedProcessor;
6
+ constructor(wrappedProcessor) {
7
+ this.wrappedProcessor = wrappedProcessor;
8
+ }
9
+ onStart(span, parentContext) {
10
+ this.wrappedProcessor.onStart(span, parentContext);
11
+ }
12
+ onEnd(span) {
13
+ const tailEvaluated = span.attributes["sampling.tail.evaluated"];
14
+ const shouldKeep = span.attributes["sampling.tail.keep"];
15
+ if (tailEvaluated === true && shouldKeep === false) {
16
+ return;
17
+ }
18
+ this.wrappedProcessor.onEnd(span);
19
+ }
20
+ forceFlush() {
21
+ return this.wrappedProcessor.forceFlush();
22
+ }
23
+ shutdown() {
24
+ return this.wrappedProcessor.shutdown();
25
+ }
26
+ };
27
+
28
+ exports.TailSamplingSpanProcessor = TailSamplingSpanProcessor;
29
+ //# sourceMappingURL=chunk-GVLK7YUU.cjs.map
30
+ //# sourceMappingURL=chunk-GVLK7YUU.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tail-sampling-processor.ts"],"names":[],"mappings":";;;AAqBO,IAAM,4BAAN,MAAyD;AAAA,EACtD,gBAAA;AAAA,EAER,YAAY,gBAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,gBAAA,GAAmB,gBAAA;AAAA,EAC1B;AAAA,EAEA,OAAA,CAAQ,MAAY,aAAA,EAA8B;AAChD,IAAA,IAAA,CAAK,gBAAA,CAAiB,OAAA,CAAQ,IAAA,EAAM,aAAa,CAAA;AAAA,EACnD;AAAA,EAEA,MAAM,IAAA,EAA0B;AAC9B,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,UAAA,CAAW,yBAAyB,CAAA;AAC/D,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,CAAW,oBAAoB,CAAA;AAEvD,IAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,UAAA,KAAe,KAAA,EAAO;AAClD,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,gBAAA,CAAiB,MAAM,IAAI,CAAA;AAAA,EAClC;AAAA,EAEA,UAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,iBAAiB,UAAA,EAAW;AAAA,EAC1C;AAAA,EAEA,QAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,iBAAiB,QAAA,EAAS;AAAA,EACxC;AACF","file":"chunk-GVLK7YUU.cjs","sourcesContent":["/**\n * Tail Sampling Span Processor\n *\n * Filters spans based on the `sampling.tail.keep` attribute set during execution.\n * This enables adaptive sampling where we decide whether to keep a span AFTER\n * the operation completes, based on criteria like errors, duration, etc.\n *\n * How it works:\n * 1. Decorator creates span optimistically (head sampling returns true)\n * 2. Operation executes and completes\n * 3. Decorator calls shouldKeepTrace() and sets sampling.tail.keep attribute\n * 4. This processor checks the attribute and drops spans marked as false\n */\n\nimport type {\n SpanProcessor,\n ReadableSpan,\n} from '@opentelemetry/sdk-trace-base';\nimport type { Context } from '@opentelemetry/api';\nimport type { Span } from '@opentelemetry/sdk-trace-base';\n\nexport class TailSamplingSpanProcessor implements SpanProcessor {\n private wrappedProcessor: SpanProcessor;\n\n constructor(wrappedProcessor: SpanProcessor) {\n this.wrappedProcessor = wrappedProcessor;\n }\n\n onStart(span: Span, parentContext: Context): void {\n this.wrappedProcessor.onStart(span, parentContext);\n }\n\n onEnd(span: ReadableSpan): void {\n const tailEvaluated = span.attributes['sampling.tail.evaluated'];\n const shouldKeep = span.attributes['sampling.tail.keep'];\n\n if (tailEvaluated === true && shouldKeep === false) {\n return;\n }\n\n this.wrappedProcessor.onEnd(span);\n }\n\n forceFlush(): Promise<void> {\n return this.wrappedProcessor.forceFlush();\n }\n\n shutdown(): Promise<void> {\n return this.wrappedProcessor.shutdown();\n }\n}\n"]}