autotel 4.3.0 → 5.0.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 (381) hide show
  1. package/README.md +125 -103
  2. package/dist/analysis.cjs +87 -0
  3. package/dist/analysis.cjs.map +1 -0
  4. package/dist/analysis.d.cts +87 -0
  5. package/dist/analysis.d.cts.map +1 -0
  6. package/dist/analysis.d.ts +87 -0
  7. package/dist/analysis.d.ts.map +1 -0
  8. package/dist/analysis.js +85 -0
  9. package/dist/analysis.js.map +1 -0
  10. package/dist/{attribute-redacting-processor-DtTS9xxh.d.ts → attribute-redacting-processor-Pk7lAzWd.d.cts} +13 -8
  11. package/dist/attribute-redacting-processor-Pk7lAzWd.d.cts.map +1 -0
  12. package/dist/{attribute-redacting-processor-DtTS9xxh.d.cts → attribute-redacting-processor-Pk7lAzWd.d.ts} +13 -8
  13. package/dist/attribute-redacting-processor-Pk7lAzWd.d.ts.map +1 -0
  14. package/dist/attribute-redacting-processor.cjs +4 -4
  15. package/dist/attribute-redacting-processor.cjs.map +1 -1
  16. package/dist/attribute-redacting-processor.d.cts +1 -1
  17. package/dist/attribute-redacting-processor.d.ts +1 -1
  18. package/dist/attribute-redacting-processor.js +4 -4
  19. package/dist/attribute-redacting-processor.js.map +1 -1
  20. package/dist/attributes.d.cts +1 -1
  21. package/dist/attributes.d.ts +1 -1
  22. package/dist/auto.cjs +1 -1
  23. package/dist/auto.cjs.map +1 -1
  24. package/dist/auto.d.cts +1 -1
  25. package/dist/auto.d.ts +1 -1
  26. package/dist/auto.js +1 -1
  27. package/dist/auto.js.map +1 -1
  28. package/dist/business-baggage.d.cts +2 -3
  29. package/dist/business-baggage.d.cts.map +1 -1
  30. package/dist/business-baggage.d.ts +2 -3
  31. package/dist/business-baggage.d.ts.map +1 -1
  32. package/dist/{canonical-log-line-processor-xvjMgtpF.d.cts → canonical-log-line-processor-B4WgG-VS.d.cts} +2 -3
  33. package/dist/canonical-log-line-processor-B4WgG-VS.d.cts.map +1 -0
  34. package/dist/{canonical-log-line-processor-BcRuAdRk.d.ts → canonical-log-line-processor-CL_J7gb5.d.ts} +2 -3
  35. package/dist/canonical-log-line-processor-CL_J7gb5.d.ts.map +1 -0
  36. package/dist/{canonical-log-line-processor-CcrDi6TO.cjs → canonical-log-line-processor-DOjb6Kxy.cjs} +5 -5
  37. package/dist/canonical-log-line-processor-DOjb6Kxy.cjs.map +1 -0
  38. package/dist/{canonical-log-line-processor-FLezvFCB.js → canonical-log-line-processor-mKABvGP0.js} +5 -5
  39. package/dist/canonical-log-line-processor-mKABvGP0.js.map +1 -0
  40. package/dist/config.d.cts +12 -7
  41. package/dist/config.d.cts.map +1 -1
  42. package/dist/config.d.ts +12 -7
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/correlation-id.cjs +1 -1
  45. package/dist/correlation-id.d.cts +0 -1
  46. package/dist/correlation-id.d.cts.map +1 -1
  47. package/dist/correlation-id.d.ts +0 -1
  48. package/dist/correlation-id.d.ts.map +1 -1
  49. package/dist/correlation-id.js +1 -1
  50. package/dist/db.d.cts.map +1 -1
  51. package/dist/db.d.ts.map +1 -1
  52. package/dist/decorators.cjs +1 -1
  53. package/dist/decorators.cjs.map +1 -1
  54. package/dist/decorators.d.cts +1 -2
  55. package/dist/decorators.d.cts.map +1 -1
  56. package/dist/decorators.d.ts +1 -2
  57. package/dist/decorators.d.ts.map +1 -1
  58. package/dist/decorators.js +1 -1
  59. package/dist/decorators.js.map +1 -1
  60. package/dist/{define-event-CreknLm3.d.ts → define-event-B2z1SBe7.d.ts} +2 -3
  61. package/dist/define-event-B2z1SBe7.d.ts.map +1 -0
  62. package/dist/{define-event-HZRizPwz.d.cts → define-event-CGG048HE.d.cts} +2 -3
  63. package/dist/define-event-CGG048HE.d.cts.map +1 -0
  64. package/dist/diagnostics.cjs +10 -1
  65. package/dist/diagnostics.cjs.map +1 -1
  66. package/dist/diagnostics.d.cts +0 -1
  67. package/dist/diagnostics.d.cts.map +1 -1
  68. package/dist/diagnostics.d.ts +0 -1
  69. package/dist/diagnostics.d.ts.map +1 -1
  70. package/dist/diagnostics.js +10 -1
  71. package/dist/diagnostics.js.map +1 -1
  72. package/dist/drain-pipeline.d.cts +12 -5
  73. package/dist/drain-pipeline.d.cts.map +1 -1
  74. package/dist/drain-pipeline.d.ts +12 -5
  75. package/dist/drain-pipeline.d.ts.map +1 -1
  76. package/dist/enrichers.d.cts.map +1 -1
  77. package/dist/enrichers.d.ts.map +1 -1
  78. package/dist/{event-rzA1X5h3.cjs → event-CwIpFdoY.cjs} +3 -3
  79. package/dist/event-CwIpFdoY.cjs.map +1 -0
  80. package/dist/{event-BEm5IJ8U.js → event-pLMF5b3d.js} +4 -4
  81. package/dist/event-pLMF5b3d.js.map +1 -0
  82. package/dist/{event-subscriber-D1XLkPzi.d.ts → event-subscriber-CWh8sTGh.d.cts} +2 -2
  83. package/dist/event-subscriber-CWh8sTGh.d.cts.map +1 -0
  84. package/dist/{event-subscriber-D1XLkPzi.d.cts → event-subscriber-CWh8sTGh.d.ts} +2 -2
  85. package/dist/event-subscriber-CWh8sTGh.d.ts.map +1 -0
  86. package/dist/event-subscriber.d.cts +1 -1
  87. package/dist/event-subscriber.d.ts +1 -1
  88. package/dist/{event-testing-CfFs3to2.d.ts → event-testing-CA2mIx1E.d.ts} +2 -3
  89. package/dist/event-testing-CA2mIx1E.d.ts.map +1 -0
  90. package/dist/{event-testing-BqRnI0z4.d.cts → event-testing-D0qWfqAy.d.cts} +2 -3
  91. package/dist/event-testing-D0qWfqAy.d.cts.map +1 -0
  92. package/dist/event-testing.d.cts +1 -1
  93. package/dist/event-testing.d.ts +1 -1
  94. package/dist/event.cjs +1 -1
  95. package/dist/event.d.cts +3 -4
  96. package/dist/event.d.cts.map +1 -1
  97. package/dist/event.d.ts +3 -4
  98. package/dist/event.d.ts.map +1 -1
  99. package/dist/event.js +1 -1
  100. package/dist/exporters.d.cts +0 -4
  101. package/dist/exporters.d.cts.map +1 -1
  102. package/dist/exporters.d.ts +0 -4
  103. package/dist/exporters.d.ts.map +1 -1
  104. package/dist/{filtering-span-processor-B8R8B7Uk.d.ts → filtering-span-processor-BpDagWNa.d.cts} +1 -2
  105. package/dist/filtering-span-processor-BpDagWNa.d.cts.map +1 -0
  106. package/dist/{filtering-span-processor-B8R8B7Uk.d.cts → filtering-span-processor-BpDagWNa.d.ts} +1 -2
  107. package/dist/filtering-span-processor-BpDagWNa.d.ts.map +1 -0
  108. package/dist/filtering-span-processor.d.cts +1 -1
  109. package/dist/filtering-span-processor.d.ts +1 -1
  110. package/dist/functional-Bit6noRu.js +840 -0
  111. package/dist/functional-Bit6noRu.js.map +1 -0
  112. package/dist/functional-Cj7PSItS.cjs +890 -0
  113. package/dist/functional-Cj7PSItS.cjs.map +1 -0
  114. package/dist/functional.cjs +2 -2
  115. package/dist/functional.d.cts +79 -130
  116. package/dist/functional.d.cts.map +1 -1
  117. package/dist/functional.d.ts +79 -130
  118. package/dist/functional.d.ts.map +1 -1
  119. package/dist/functional.js +2 -2
  120. package/dist/http.cjs +5 -5
  121. package/dist/http.cjs.map +1 -1
  122. package/dist/http.d.cts +4 -5
  123. package/dist/http.d.cts.map +1 -1
  124. package/dist/http.d.ts +4 -5
  125. package/dist/http.d.ts.map +1 -1
  126. package/dist/http.js +5 -5
  127. package/dist/http.js.map +1 -1
  128. package/dist/{index-eKuioqT1.d.cts → index-BPcxVucm.d.cts} +2 -3
  129. package/dist/index-BPcxVucm.d.cts.map +1 -0
  130. package/dist/{index-Ck06vlW2.d.ts → index-DolOVX6F.d.ts} +2 -3
  131. package/dist/index-DolOVX6F.d.ts.map +1 -0
  132. package/dist/index.cjs +7 -8
  133. package/dist/index.cjs.map +1 -1
  134. package/dist/index.d.cts +14 -14
  135. package/dist/index.d.cts.map +1 -1
  136. package/dist/index.d.ts +14 -14
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +7 -8
  139. package/dist/index.js.map +1 -1
  140. package/dist/{init-BxJEJ9Tn.cjs → init-B2uvZReD.cjs} +19 -10
  141. package/dist/init-B2uvZReD.cjs.map +1 -0
  142. package/dist/{init-B7u-DjxM.d.ts → init-CTyqG9qR.d.ts} +24 -17
  143. package/dist/init-CTyqG9qR.d.ts.map +1 -0
  144. package/dist/{init-BvBB45-T.js → init-CdEWjhvl.js} +20 -11
  145. package/dist/init-CdEWjhvl.js.map +1 -0
  146. package/dist/{init-DSrRmVnz.d.cts → init-a4yPDYqC.d.cts} +24 -17
  147. package/dist/init-a4yPDYqC.d.cts.map +1 -0
  148. package/dist/instrumentation.cjs +7 -13
  149. package/dist/instrumentation.cjs.map +1 -1
  150. package/dist/instrumentation.d.cts +0 -1
  151. package/dist/instrumentation.d.cts.map +1 -1
  152. package/dist/instrumentation.d.ts +0 -1
  153. package/dist/instrumentation.d.ts.map +1 -1
  154. package/dist/instrumentation.js +8 -14
  155. package/dist/instrumentation.js.map +1 -1
  156. package/dist/{logger-BauSUhUv.d.ts → logger-CN4xpzMd.d.cts} +1 -2
  157. package/dist/logger-CN4xpzMd.d.cts.map +1 -0
  158. package/dist/{logger-BauSUhUv.d.cts → logger-CN4xpzMd.d.ts} +1 -2
  159. package/dist/logger-CN4xpzMd.d.ts.map +1 -0
  160. package/dist/logger-D3Ej3DII.js.map +1 -1
  161. package/dist/logger-thMPLpOG.cjs.map +1 -1
  162. package/dist/logger.d.cts +1 -1
  163. package/dist/logger.d.ts +1 -1
  164. package/dist/messaging-adapters.cjs.map +1 -1
  165. package/dist/messaging-adapters.d.cts +0 -1
  166. package/dist/messaging-adapters.d.cts.map +1 -1
  167. package/dist/messaging-adapters.d.ts +0 -1
  168. package/dist/messaging-adapters.d.ts.map +1 -1
  169. package/dist/messaging-adapters.js.map +1 -1
  170. package/dist/messaging-testing.d.cts +0 -1
  171. package/dist/messaging-testing.d.cts.map +1 -1
  172. package/dist/messaging-testing.d.ts +0 -1
  173. package/dist/messaging-testing.d.ts.map +1 -1
  174. package/dist/messaging.cjs +27 -10
  175. package/dist/messaging.cjs.map +1 -1
  176. package/dist/messaging.d.cts +6 -7
  177. package/dist/messaging.d.cts.map +1 -1
  178. package/dist/messaging.d.ts +6 -7
  179. package/dist/messaging.d.ts.map +1 -1
  180. package/dist/messaging.js +27 -10
  181. package/dist/messaging.js.map +1 -1
  182. package/dist/metric-helpers.d.cts +0 -1
  183. package/dist/metric-helpers.d.cts.map +1 -1
  184. package/dist/metric-helpers.d.ts +0 -1
  185. package/dist/metric-helpers.d.ts.map +1 -1
  186. package/dist/{metric-testing-DXdK3-Q3.d.ts → metric-testing-CWm6UhaR.d.ts} +2 -3
  187. package/dist/metric-testing-CWm6UhaR.d.ts.map +1 -0
  188. package/dist/{metric-testing-MxvzChDp.d.cts → metric-testing-CpvP3ZIa.d.cts} +2 -3
  189. package/dist/metric-testing-CpvP3ZIa.d.cts.map +1 -0
  190. package/dist/metric-testing.d.cts +1 -1
  191. package/dist/metric-testing.d.ts +1 -1
  192. package/dist/metric.d.cts +3 -4
  193. package/dist/metric.d.cts.map +1 -1
  194. package/dist/metric.d.ts +3 -4
  195. package/dist/metric.d.ts.map +1 -1
  196. package/dist/parse-error.d.cts.map +1 -1
  197. package/dist/parse-error.d.ts.map +1 -1
  198. package/dist/processors.cjs +1 -1
  199. package/dist/processors.d.cts +1 -1
  200. package/dist/processors.d.ts +1 -1
  201. package/dist/processors.js +1 -1
  202. package/dist/register.d.cts +1 -1
  203. package/dist/register.d.ts +1 -1
  204. package/dist/{sampling-DfYhDJij.d.cts → sampling-BR9fkSwx.d.cts} +127 -10
  205. package/dist/sampling-BR9fkSwx.d.cts.map +1 -0
  206. package/dist/{sampling-CR0Va1VB.d.ts → sampling-CP3e7-Yr.d.ts} +127 -10
  207. package/dist/sampling-CP3e7-Yr.d.ts.map +1 -0
  208. package/dist/sampling.cjs +160 -12
  209. package/dist/sampling.cjs.map +1 -1
  210. package/dist/sampling.d.cts +2 -2
  211. package/dist/sampling.d.ts +2 -2
  212. package/dist/sampling.js +157 -13
  213. package/dist/sampling.js.map +1 -1
  214. package/dist/security-schema.d.cts +9 -4
  215. package/dist/security-schema.d.cts.map +1 -1
  216. package/dist/security-schema.d.ts +9 -4
  217. package/dist/security-schema.d.ts.map +1 -1
  218. package/dist/semantic-conventions-FhSxv-bK.d.cts.map +1 -1
  219. package/dist/semantic-conventions-FhSxv-bK.d.ts.map +1 -1
  220. package/dist/semantic-conventions.cjs.map +1 -1
  221. package/dist/semantic-conventions.js.map +1 -1
  222. package/dist/semantic-helpers.cjs +85 -304
  223. package/dist/semantic-helpers.cjs.map +1 -1
  224. package/dist/semantic-helpers.d.cts +21 -12
  225. package/dist/semantic-helpers.d.cts.map +1 -1
  226. package/dist/semantic-helpers.d.ts +21 -12
  227. package/dist/semantic-helpers.d.ts.map +1 -1
  228. package/dist/semantic-helpers.js +85 -304
  229. package/dist/semantic-helpers.js.map +1 -1
  230. package/dist/slo.cjs +225 -0
  231. package/dist/slo.cjs.map +1 -0
  232. package/dist/slo.d.cts +97 -0
  233. package/dist/slo.d.cts.map +1 -0
  234. package/dist/slo.d.ts +97 -0
  235. package/dist/slo.d.ts.map +1 -0
  236. package/dist/slo.js +223 -0
  237. package/dist/slo.js.map +1 -0
  238. package/dist/{span-name-normalizer-8ZOGJuwv.d.ts → span-name-normalizer-CN1-8C76.d.cts} +1 -2
  239. package/dist/span-name-normalizer-CN1-8C76.d.cts.map +1 -0
  240. package/dist/{span-name-normalizer-8ZOGJuwv.d.cts → span-name-normalizer-CN1-8C76.d.ts} +1 -2
  241. package/dist/span-name-normalizer-CN1-8C76.d.ts.map +1 -0
  242. package/dist/span-name-normalizer.cjs.map +1 -1
  243. package/dist/span-name-normalizer.d.cts +1 -1
  244. package/dist/span-name-normalizer.d.ts +1 -1
  245. package/dist/span-name-normalizer.js.map +1 -1
  246. package/dist/tail-sampling-processor.d.cts +0 -1
  247. package/dist/tail-sampling-processor.d.cts.map +1 -1
  248. package/dist/tail-sampling-processor.d.ts +0 -1
  249. package/dist/tail-sampling-processor.d.ts.map +1 -1
  250. package/dist/test-span-collector.cjs.map +1 -1
  251. package/dist/test-span-collector.d.cts +0 -1
  252. package/dist/test-span-collector.d.cts.map +1 -1
  253. package/dist/test-span-collector.d.ts +0 -1
  254. package/dist/test-span-collector.d.ts.map +1 -1
  255. package/dist/test-span-collector.js.map +1 -1
  256. package/dist/testing.cjs +76 -11
  257. package/dist/testing.cjs.map +1 -1
  258. package/dist/testing.d.cts +30 -5
  259. package/dist/testing.d.cts.map +1 -1
  260. package/dist/testing.d.ts +30 -5
  261. package/dist/testing.d.ts.map +1 -1
  262. package/dist/testing.js +73 -12
  263. package/dist/testing.js.map +1 -1
  264. package/dist/{trace-context-Cijqoi6e.d.ts → trace-context-IuyoPyNq.d.cts} +9 -9
  265. package/dist/trace-context-IuyoPyNq.d.cts.map +1 -0
  266. package/dist/{trace-context-Cijqoi6e.d.cts → trace-context-IuyoPyNq.d.ts} +9 -9
  267. package/dist/trace-context-IuyoPyNq.d.ts.map +1 -0
  268. package/dist/trace-factory-validation-BjVAinz6.js +13 -0
  269. package/dist/trace-factory-validation-BjVAinz6.js.map +1 -0
  270. package/dist/trace-factory-validation-Dc8epn87.cjs +19 -0
  271. package/dist/trace-factory-validation-Dc8epn87.cjs.map +1 -0
  272. package/dist/trace-helpers.cjs +7 -7
  273. package/dist/trace-helpers.cjs.map +1 -1
  274. package/dist/trace-helpers.d.cts +6 -7
  275. package/dist/trace-helpers.d.cts.map +1 -1
  276. package/dist/trace-helpers.d.ts +6 -7
  277. package/dist/trace-helpers.d.ts.map +1 -1
  278. package/dist/trace-helpers.js +7 -7
  279. package/dist/trace-helpers.js.map +1 -1
  280. package/dist/tracer-provider.d.cts +0 -1
  281. package/dist/tracer-provider.d.cts.map +1 -1
  282. package/dist/tracer-provider.d.ts +0 -1
  283. package/dist/tracer-provider.d.ts.map +1 -1
  284. package/dist/{track-D7O7oIZa.js → track-BBcxEJEC.js} +7 -12
  285. package/dist/track-BBcxEJEC.js.map +1 -0
  286. package/dist/{track-eovhCJ-I.cjs → track-BI6dmZ2X.cjs} +6 -17
  287. package/dist/track-BI6dmZ2X.cjs.map +1 -0
  288. package/dist/validate.cjs.map +1 -1
  289. package/dist/validate.d.cts +1 -2
  290. package/dist/validate.d.cts.map +1 -1
  291. package/dist/validate.d.ts +1 -2
  292. package/dist/validate.d.ts.map +1 -1
  293. package/dist/validate.js.map +1 -1
  294. package/dist/validation-attributes.d.cts +17 -8
  295. package/dist/validation-attributes.d.cts.map +1 -1
  296. package/dist/validation-attributes.d.ts +17 -8
  297. package/dist/validation-attributes.d.ts.map +1 -1
  298. package/dist/webhook.cjs +5 -4
  299. package/dist/webhook.cjs.map +1 -1
  300. package/dist/webhook.d.cts +4 -4
  301. package/dist/webhook.d.cts.map +1 -1
  302. package/dist/webhook.d.ts +4 -4
  303. package/dist/webhook.d.ts.map +1 -1
  304. package/dist/webhook.js +5 -4
  305. package/dist/webhook.js.map +1 -1
  306. package/dist/workflow-distributed.cjs +5 -5
  307. package/dist/workflow-distributed.cjs.map +1 -1
  308. package/dist/workflow-distributed.d.cts +25 -15
  309. package/dist/workflow-distributed.d.cts.map +1 -1
  310. package/dist/workflow-distributed.d.ts +25 -15
  311. package/dist/workflow-distributed.d.ts.map +1 -1
  312. package/dist/workflow-distributed.js +5 -5
  313. package/dist/workflow-distributed.js.map +1 -1
  314. package/dist/workflow.cjs +24 -30
  315. package/dist/workflow.cjs.map +1 -1
  316. package/dist/workflow.d.cts +11 -6
  317. package/dist/workflow.d.cts.map +1 -1
  318. package/dist/workflow.d.ts +11 -6
  319. package/dist/workflow.d.ts.map +1 -1
  320. package/dist/workflow.js +24 -30
  321. package/dist/workflow.js.map +1 -1
  322. package/dist/yaml-config.d.cts +2 -3
  323. package/dist/yaml-config.d.cts.map +1 -1
  324. package/dist/yaml-config.d.ts +2 -3
  325. package/dist/yaml-config.d.ts.map +1 -1
  326. package/package.json +23 -14
  327. package/skills/analyze-traces/SKILL.md +42 -13
  328. package/skills/autotel-core/SKILL.md +24 -17
  329. package/skills/autotel-events/SKILL.md +1 -1
  330. package/skills/autotel-frameworks/SKILL.md +41 -6
  331. package/skills/autotel-instrumentation/SKILL.md +14 -9
  332. package/skills/autotel-request-logging/SKILL.md +19 -14
  333. package/skills/autotel-structured-errors/SKILL.md +2 -2
  334. package/skills/build-audit-trails/SKILL.md +11 -11
  335. package/skills/build-audit-trails/references/audit-queries.md +3 -3
  336. package/skills/debug-missing-spans/SKILL.md +12 -12
  337. package/skills/migrate-to-autotel/SKILL.md +20 -20
  338. package/skills/review-otel-patterns/SKILL.md +44 -42
  339. package/skills/review-otel-patterns/references/code-review.md +4 -4
  340. package/skills/review-otel-patterns/references/processor-pipeline.md +3 -3
  341. package/skills/review-otel-patterns/references/structured-errors.md +1 -1
  342. package/skills/review-otel-patterns/references/wide-spans.md +2 -2
  343. package/skills/tune-sampling/SKILL.md +91 -16
  344. package/dist/attribute-redacting-processor-DtTS9xxh.d.cts.map +0 -1
  345. package/dist/attribute-redacting-processor-DtTS9xxh.d.ts.map +0 -1
  346. package/dist/canonical-log-line-processor-BcRuAdRk.d.ts.map +0 -1
  347. package/dist/canonical-log-line-processor-CcrDi6TO.cjs.map +0 -1
  348. package/dist/canonical-log-line-processor-FLezvFCB.js.map +0 -1
  349. package/dist/canonical-log-line-processor-xvjMgtpF.d.cts.map +0 -1
  350. package/dist/define-event-CreknLm3.d.ts.map +0 -1
  351. package/dist/define-event-HZRizPwz.d.cts.map +0 -1
  352. package/dist/event-BEm5IJ8U.js.map +0 -1
  353. package/dist/event-rzA1X5h3.cjs.map +0 -1
  354. package/dist/event-subscriber-D1XLkPzi.d.cts.map +0 -1
  355. package/dist/event-subscriber-D1XLkPzi.d.ts.map +0 -1
  356. package/dist/event-testing-BqRnI0z4.d.cts.map +0 -1
  357. package/dist/event-testing-CfFs3to2.d.ts.map +0 -1
  358. package/dist/filtering-span-processor-B8R8B7Uk.d.cts.map +0 -1
  359. package/dist/filtering-span-processor-B8R8B7Uk.d.ts.map +0 -1
  360. package/dist/functional-CwsPyc4l.cjs +0 -1298
  361. package/dist/functional-CwsPyc4l.cjs.map +0 -1
  362. package/dist/functional-dAYhXQPA.js +0 -1248
  363. package/dist/functional-dAYhXQPA.js.map +0 -1
  364. package/dist/index-Ck06vlW2.d.ts.map +0 -1
  365. package/dist/index-eKuioqT1.d.cts.map +0 -1
  366. package/dist/init-B7u-DjxM.d.ts.map +0 -1
  367. package/dist/init-BvBB45-T.js.map +0 -1
  368. package/dist/init-BxJEJ9Tn.cjs.map +0 -1
  369. package/dist/init-DSrRmVnz.d.cts.map +0 -1
  370. package/dist/logger-BauSUhUv.d.cts.map +0 -1
  371. package/dist/logger-BauSUhUv.d.ts.map +0 -1
  372. package/dist/metric-testing-DXdK3-Q3.d.ts.map +0 -1
  373. package/dist/metric-testing-MxvzChDp.d.cts.map +0 -1
  374. package/dist/sampling-CR0Va1VB.d.ts.map +0 -1
  375. package/dist/sampling-DfYhDJij.d.cts.map +0 -1
  376. package/dist/span-name-normalizer-8ZOGJuwv.d.cts.map +0 -1
  377. package/dist/span-name-normalizer-8ZOGJuwv.d.ts.map +0 -1
  378. package/dist/trace-context-Cijqoi6e.d.cts.map +0 -1
  379. package/dist/trace-context-Cijqoi6e.d.ts.map +0 -1
  380. package/dist/track-D7O7oIZa.js.map +0 -1
  381. package/dist/track-eovhCJ-I.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"sampling.js","names":[],"sources":["../src/sampling.ts"],"sourcesContent":["/**\n * Sampling Strategies\n *\n * Provides intelligent sampling beyond simple random rates.\n * Helps reduce telemetry costs while capturing critical data.\n *\n * Key strategies:\n * - Always trace errors and slow requests (critical for debugging)\n * - Sample by user ID for consistent request tracing\n * - Adaptive sampling based on load\n * - Sample by feature flags for A/B testing correlation\n *\n * @example\n * ```typescript\n * import { AlwaysOnErrorSampler, UserIdSampler } from './sampling'\n *\n * @Instrumented({\n * serviceName: 'user',\n * sampler: new AlwaysOnErrorSampler(0.1) // 10% baseline, 100% on errors\n * })\n * class UserService { }\n * ```\n */\n\nimport type { Link, Attributes } from '@opentelemetry/api';\nimport { TraceFlags } from '@opentelemetry/api';\nimport { type Logger } from './logger';\n\n/**\n * Tail sampling attribute keys (autotel-internal, not OTel semconv)\n */\nexport const AUTOTEL_SAMPLING_TAIL_KEEP = 'autotel.sampling.tail.keep';\nexport const AUTOTEL_SAMPLING_TAIL_EVALUATED =\n 'autotel.sampling.tail.evaluated';\n\n/**\n * Sampler interface - return true to trace, false to skip\n */\nexport interface Sampler {\n /**\n * Decide whether to trace this operation\n *\n * @param context - Sampling context\n * @returns true to trace, false to skip\n */\n shouldSample(context: SamplingContext): boolean;\n\n /**\n * Whether this sampler needs tail sampling (post-execution decision)\n * If true, spans are always created and shouldKeepTrace() is called after execution\n *\n * @returns true if this sampler needs to evaluate after operation completes\n */\n needsTailSampling?(): boolean;\n\n /**\n * Re-evaluate sampling decision after operation completes (tail sampling)\n * Only called if needsTailSampling() returns true\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this trace should be kept, false to drop it\n */\n shouldKeepTrace?(context: SamplingContext, result: OperationResult): boolean;\n}\n\n/**\n * Context information for sampling decisions\n */\nexport interface SamplingContext {\n /** Operation name */\n operationName: string;\n /** Method arguments (for extracting user IDs, etc.) */\n args: unknown[];\n /** Optional metadata (e.g., feature flags, request headers) */\n metadata?: Record<string, unknown>;\n /** Optional span links for links-based sampling */\n links?: Link[];\n}\n\n/**\n * Result of a trace operation (for post-execution sampling)\n */\nexport interface OperationResult {\n /** Whether the operation succeeded */\n success: boolean;\n /** Duration in milliseconds */\n duration: number;\n /** Error if operation failed */\n error?: Error;\n}\n\n/**\n * Simple random sampler\n *\n * @example\n * ```typescript\n * new RandomSampler(0.1) // Sample 10% of requests\n * ```\n */\nexport class RandomSampler implements Sampler {\n constructor(private readonly sampleRate: number) {\n if (sampleRate < 0 || sampleRate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldSample(_context: SamplingContext): boolean {\n return Math.random() < this.sampleRate;\n }\n}\n\n/**\n * Always sample (100% tracing)\n */\nexport class AlwaysSampler implements Sampler {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldSample(_context: SamplingContext): boolean {\n return true;\n }\n}\n\n/**\n * Never sample (0% tracing)\n */\nexport class NeverSampler implements Sampler {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldSample(_context: SamplingContext): boolean {\n return false;\n }\n}\n\n/**\n * Adaptive sampler that always traces errors and slow requests\n *\n * This is the recommended sampler for production use.\n * It ensures you never miss critical issues while keeping costs down.\n *\n * Strategy:\n * - Always trace errors (critical for debugging)\n * - Always trace slow requests (performance issues)\n * - Use baseline sample rate for successful fast requests\n *\n * **IMPORTANT - Tail Sampling Requirement:**\n * This sampler uses tail sampling (makes decisions AFTER execution).\n * You MUST use TailSamplingSpanProcessor for it to work correctly:\n *\n * - If using initInstrumentation(): TailSamplingSpanProcessor is auto-configured\n * - If using custom TracerProvider: You MUST manually register TailSamplingSpanProcessor\n *\n * Without TailSamplingSpanProcessor, ALL spans are exported (defeating the cost savings).\n *\n * @see TailSamplingSpanProcessor\n * @see README.md \"Tail Sampling with Custom Providers\" section\n *\n * @example\n * ```typescript\n * new AdaptiveSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * alwaysSampleErrors: true, // Always trace errors\n * alwaysSampleSlow: true // Always trace slow requests\n * })\n * ```\n */\nexport class AdaptiveSampler implements Sampler {\n private baselineSampleRate: number;\n private slowThresholdMs: number;\n private alwaysSampleErrors: boolean;\n private alwaysSampleSlow: boolean;\n private linksBased: boolean;\n private linksRate: number;\n private logger?: Logger;\n\n // Track whether we should sample this request\n private readonly samplingDecisions = new WeakMap<unknown[], boolean>();\n // Track operation results to enable post-execution decision\n private readonly operationResults = new WeakMap<unknown[], OperationResult>();\n\n constructor(\n options: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n /** Enable links-based sampling for event-driven architectures */\n linksBased?: boolean;\n /** Sampling rate for spans linked to sampled spans (0.0-1.0) */\n linksRate?: number;\n logger?: Logger;\n } = {},\n ) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.slowThresholdMs = options.slowThresholdMs ?? 1000;\n this.alwaysSampleErrors = options.alwaysSampleErrors ?? true;\n this.alwaysSampleSlow = options.alwaysSampleSlow ?? true;\n this.linksBased = options.linksBased ?? false;\n this.linksRate = options.linksRate ?? 1;\n this.logger = options.logger;\n\n if (this.baselineSampleRate < 0 || this.baselineSampleRate > 1) {\n throw new Error('Baseline sample rate must be between 0 and 1');\n }\n if (this.linksRate < 0 || this.linksRate > 1) {\n throw new Error('Links rate must be between 0 and 1');\n }\n }\n\n needsTailSampling(): boolean {\n // AdaptiveSampler ALWAYS needs tail sampling to implement error/slow capture\n return true;\n }\n\n shouldSample(context: SamplingContext): boolean {\n // For tail sampling, we optimistically create spans for all requests\n // The real decision happens in shouldKeepTrace() after execution\n // We still store the baseline decision for shouldKeepTrace() to use\n const baselineDecision = Math.random() < this.baselineSampleRate;\n this.samplingDecisions.set(context.args, baselineDecision);\n\n // Always return true to create the span (tail sampling will decide if we keep it)\n return true;\n }\n\n /**\n * Check if any links point to sampled spans.\n *\n * A span is considered linked to a sampled span if any of its links\n * have trace_flags with the sampled bit set (0x01).\n *\n * @param links - Array of span links to check\n * @returns true if any linked span is sampled, false otherwise\n */\n hasSampledLink(links: Link[]): boolean {\n if (!links || links.length === 0) {\n return false;\n }\n return links.some(\n (link) =>\n link.context && (link.context.traceFlags & TraceFlags.SAMPLED) !== 0,\n );\n }\n\n /**\n * Re-evaluate sampling decision after operation completes\n *\n * This allows us to always capture errors and slow requests,\n * even if they weren't initially sampled.\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this operation should be kept (not discarded)\n */\n shouldKeepTrace(context: SamplingContext, result: OperationResult): boolean {\n const baselineDecision = this.samplingDecisions.get(context.args) ?? false;\n\n // Always keep errors\n if (this.alwaysSampleErrors && !result.success) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n error: result.error?.message,\n },\n 'Adaptive sampling: Keeping error trace',\n );\n }\n return true;\n }\n\n // Always keep slow requests\n if (this.alwaysSampleSlow && result.duration >= this.slowThresholdMs) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n duration: result.duration,\n },\n 'Adaptive sampling: Keeping slow trace',\n );\n }\n return true;\n }\n\n // Check for sampled links (links-based sampling for event-driven systems)\n if (\n this.linksBased &&\n context.links &&\n this.hasSampledLink(context.links)\n ) {\n // Use linksRate to decide whether to keep the linked span\n const keepLinked = Math.random() < this.linksRate;\n if (keepLinked && !baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n linkCount: context.links.length,\n },\n 'Adaptive sampling: Keeping trace due to sampled link',\n );\n }\n return keepLinked;\n }\n\n // Otherwise, use baseline decision\n return baselineDecision;\n }\n}\n\n/**\n * User-based sampler for consistent tracing\n *\n * Always samples requests from specific user IDs.\n * Useful for debugging specific user issues or monitoring VIP users.\n *\n * @example\n * ```typescript\n * new UserIdSampler({\n * baselineSampleRate: 0.01, // 1% of normal users\n * alwaysSampleUsers: ['vip_123'], // Always trace VIP users\n * extractUserId: (args) => args[0]?.userId // Extract user ID from first arg\n * })\n * ```\n */\nexport class UserIdSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleUsers: Set<string>;\n private extractUserId: (args: unknown[]) => string | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleUsers?: string[];\n extractUserId: (args: unknown[]) => string | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleUsers = new Set(options.alwaysSampleUsers || []);\n this.extractUserId = options.extractUserId;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const userId = this.extractUserId(context.args);\n\n // Always sample specific users\n if (userId && this.alwaysSampleUsers.has(userId)) {\n this.logger?.debug(\n {\n operation: context.operationName,\n userId,\n },\n 'Sampling user request',\n );\n return true;\n }\n\n // For consistent per-user sampling, hash the user ID\n if (userId) {\n const hash = this.hashString(userId);\n return hash < this.baselineSampleRate;\n }\n\n // Fallback to random sampling if no user ID\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add user IDs to always-sample list\n */\n addAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.add(userId);\n }\n }\n\n /**\n * Remove user IDs from always-sample list\n */\n removeAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.delete(userId);\n }\n }\n\n /**\n * Simple hash function for consistent user sampling\n */\n private hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.codePointAt(i) ?? 0;\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash) / 2_147_483_647; // Normalize to 0-1\n }\n}\n\n/**\n * Composite sampler that combines multiple samplers\n *\n * Samples if ANY of the child samplers returns true.\n *\n * @example\n * ```typescript\n * new CompositeSampler([\n * new UserIdSampler({ extractUserId: (args) => args[0]?.userId }),\n * new AdaptiveSampler({ baselineSampleRate: 0.1 })\n * ])\n * ```\n */\nexport class CompositeSampler implements Sampler {\n constructor(private readonly samplers: Sampler[]) {\n if (samplers.length === 0) {\n throw new Error('CompositeSampler requires at least one child sampler');\n }\n }\n\n shouldSample(context: SamplingContext): boolean {\n return this.samplers.some((sampler) => sampler.shouldSample(context));\n }\n}\n\n/**\n * Feature flag sampler\n *\n * Always samples requests with specific feature flags enabled.\n * Perfect for correlating A/B test experiments with metrics.\n *\n * @example\n * ```typescript\n * new FeatureFlagSampler({\n * baselineSampleRate: 0.01,\n * alwaysSampleFlags: ['new_checkout', 'experimental_ui'],\n * extractFlags: (args, metadata) => metadata?.featureFlags\n * })\n * ```\n */\nexport class FeatureFlagSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleFlags: Set<string>;\n private extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleFlags?: string[];\n extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleFlags = new Set(options.alwaysSampleFlags || []);\n this.extractFlags = options.extractFlags;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const flags = this.extractFlags(context.args, context.metadata);\n\n // Always sample if any monitored flag is enabled\n if (flags && flags.some((flag) => this.alwaysSampleFlags.has(flag))) {\n this.logger?.debug(\n {\n operation: context.operationName,\n flags,\n },\n 'Sampling feature flag request',\n );\n return true;\n }\n\n // Fallback to random sampling\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add feature flags to always-sample list\n */\n addAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.add(flag);\n }\n }\n\n /**\n * Remove feature flags from always-sample list\n */\n removeAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.delete(flag);\n }\n }\n}\n\n// ============================================================================\n// Sampling Presets\n// ============================================================================\n\n/**\n * Named sampling presets for common environments.\n * Use with `init({ sampling: 'production' })` or directly via factories.\n */\nexport type SamplingPreset =\n | 'development'\n | 'errors-only'\n | 'production'\n | 'off';\n\n/**\n * Sampling preset factories.\n *\n * For most users, the string shorthand on `init()` is simpler:\n * ```typescript\n * init({ service: 'my-app', sampling: 'production' })\n * ```\n *\n * Use factories when you need to customize:\n * ```typescript\n * init({ service: 'my-app', sampler: samplingPresets.production({ baselineSampleRate: 0.05 }) })\n * ```\n */\nexport const samplingPresets = {\n /** Capture everything — best for local development and debugging */\n development: () => new AlwaysSampler(),\n\n /** Only bad outcomes — zero baseline, errors always kept */\n errorsOnly: () =>\n new AdaptiveSampler({\n baselineSampleRate: 0,\n alwaysSampleErrors: true,\n }),\n\n /**\n * Balanced production defaults — 10% baseline + errors + slow traces.\n * Pass overrides to tune (uses the same option names as AdaptiveSampler).\n */\n production: (overrides?: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n }) =>\n new AdaptiveSampler({\n baselineSampleRate: 0.1,\n alwaysSampleErrors: true,\n alwaysSampleSlow: true,\n slowThresholdMs: 1000,\n ...overrides,\n }),\n\n /** Disable sampling entirely */\n off: () => new NeverSampler(),\n};\n\n/**\n * Resolve a preset string to a Sampler instance.\n * Used internally by `init()` when `sampling` string is provided.\n *\n * @throws Error if preset is not recognized\n */\nexport function resolveSamplingPreset(preset: SamplingPreset): Sampler {\n switch (preset) {\n case 'development':\n return samplingPresets.development();\n case 'errors-only':\n return samplingPresets.errorsOnly();\n case 'production':\n return samplingPresets.production();\n case 'off':\n return samplingPresets.off();\n default:\n throw new Error(\n `Unknown sampling preset: \"${preset}\". Valid presets: development, errors-only, production, off`,\n );\n }\n}\n\n// ============================================================================\n// Link Helper Functions\n// ============================================================================\n\n/**\n * Create a Link from W3C trace context headers (e.g., from a message queue).\n *\n * This is useful for message consumers that need to link to the producer span.\n * The headers should contain at least a `traceparent` header in W3C format.\n *\n * @param headers - Dictionary containing traceparent/tracestate headers\n * @param attributes - Optional attributes for the link\n * @returns Link object if context could be extracted, null otherwise\n *\n * @example\n * ```typescript\n * // In a Kafka consumer\n * const headers = { traceparent: '00-abc123...-def456...-01' };\n * const link = createLinkFromHeaders(headers);\n * if (link) {\n * // Use with tracer.startActiveSpan options or ctx.addLink()\n * tracer.startActiveSpan('process.message', { links: [link] }, span => { ... });\n * }\n * ```\n */\nexport function createLinkFromHeaders(\n headers: Record<string, string>,\n attributes?: Attributes,\n): Link | null {\n // Parse W3C traceparent header directly for reliability\n // Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n const traceparent = headers.traceparent || headers['traceparent'];\n if (!traceparent) {\n return null;\n }\n\n const spanContext = parseTraceparent(traceparent);\n if (!spanContext || !isValidSpanContext(spanContext)) {\n return null;\n }\n\n return {\n context: spanContext,\n attributes: attributes ?? {},\n };\n}\n\n/**\n * Extract Links from a batch of messages for fan-in scenarios.\n *\n * Useful for batch processing where multiple producer spans should be linked.\n * This enables tracing causality in event-driven architectures where a single\n * consumer processes messages from multiple producers.\n *\n * @param messages - List of message objects\n * @param headersKey - Key in each message containing trace headers (default: 'headers')\n * @returns List of Link objects for all valid trace contexts\n *\n * @example\n * ```typescript\n * // Processing a batch of SQS/Kafka messages\n * const messages = [\n * { body: '...', headers: { traceparent: '...' } },\n * { body: '...', headers: { traceparent: '...' } },\n * ];\n * const links = extractLinksFromBatch(messages);\n *\n * tracer.startActiveSpan('process.batch', { links }, span => {\n * for (const msg of messages) {\n * processMessage(msg);\n * }\n * });\n * ```\n */\nexport function extractLinksFromBatch(\n messages: Array<{ [key: string]: unknown }>,\n headersKey: string = 'headers',\n): Link[] {\n const links: Link[] = [];\n\n for (const msg of messages) {\n const msgHeaders = msg[headersKey];\n if (msgHeaders && typeof msgHeaders === 'object' && msgHeaders !== null) {\n const link = createLinkFromHeaders(msgHeaders as Record<string, string>, {\n 'messaging.batch.message_index': links.length,\n });\n if (link) {\n links.push(link);\n }\n }\n }\n\n return links;\n}\n\n/**\n * Parse W3C traceparent header into SpanContext\n * Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n *\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nfunction parseTraceparent(\n traceparent: string,\n): import('@opentelemetry/api').SpanContext | null {\n // W3C traceparent format: version-traceId-parentId-traceFlags\n // Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\n const TRACEPARENT_REGEX =\n /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;\n\n const match = traceparent.match(TRACEPARENT_REGEX);\n if (!match || match.length < 5) {\n return null;\n }\n\n const version = match[1];\n const traceId = match[2];\n const spanId = match[3];\n const flags = match[4];\n\n // Validate all parts are present (TypeScript narrowing)\n if (!version || !traceId || !spanId || !flags) {\n return null;\n }\n\n // Version 00 is currently the only version, but we should be forward compatible\n if (version === 'ff') {\n // Version ff is invalid according to spec\n return null;\n }\n\n return {\n traceId,\n spanId,\n traceFlags: Number.parseInt(flags, 16),\n isRemote: true,\n };\n}\n\n/**\n * Check if a SpanContext is valid (has non-zero trace and span IDs)\n */\nfunction isValidSpanContext(\n spanContext: import('@opentelemetry/api').SpanContext | null,\n): spanContext is import('@opentelemetry/api').SpanContext {\n if (!spanContext) return false;\n // TraceId should not be all zeros (00000000000000000000000000000000)\n // SpanId should not be all zeros (0000000000000000)\n return (\n spanContext.traceId !== '00000000000000000000000000000000' &&\n spanContext.spanId !== '0000000000000000'\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sampling.js","names":[],"sources":["../src/sampling.ts"],"sourcesContent":["/**\n * Sampling Strategies\n *\n * Provides intelligent sampling beyond simple random rates.\n * Helps reduce telemetry costs while capturing critical data.\n *\n * Key strategies:\n * - Always trace errors and slow requests (critical for debugging)\n * - Sample by user ID for consistent request tracing\n * - Adaptive sampling based on load\n * - Sample by feature flags for A/B testing correlation\n *\n * @example\n * ```typescript\n * import { AlwaysOnErrorSampler, UserIdSampler } from './sampling'\n *\n * @Instrumented({\n * serviceName: 'user',\n * sampler: new AlwaysOnErrorSampler(0.1) // 10% baseline, 100% on errors\n * })\n * class UserService { }\n * ```\n */\n\nimport type { Link, Attributes } from '@opentelemetry/api';\nimport { TraceFlags } from '@opentelemetry/api';\nimport { type Logger } from './logger';\n\n/**\n * Tail sampling attribute keys (autotel-internal, not OTel semconv)\n */\nexport const AUTOTEL_SAMPLING_TAIL_KEEP = 'autotel.sampling.tail.keep';\nexport const AUTOTEL_SAMPLING_TAIL_EVALUATED =\n 'autotel.sampling.tail.evaluated';\n\n/**\n * How many events each kept event stands for, expressed as \"1 in N\".\n *\n * A query that counts sampled spans undercounts the population. Multiplying\n * each kept event by this rate restores the estimate. Autotel records the\n * attribute only when N exceeds 1, so fully captured spans stay clean.\n */\nexport const AUTOTEL_SAMPLING_RATE = 'autotel.sampling.rate';\n\n/**\n * Convert a keep probability into the \"1 in N\" rate reported on spans.\n *\n * Keeping 10% of traces means each survivor stands for 10, so the two numbers\n * are reciprocals and easy to publish the wrong way round.\n */\nfunction toSampleRate(probability: number): number {\n return probability > 0 ? 1 / probability : 0;\n}\n\n/**\n * Map a string to a stable, evenly spread position in the unit interval.\n *\n * Two processes that hash the same key reach the same number, which is what\n * lets independent services agree on one trace's sampling decision.\n *\n * The spread matters as much as the stability. Real sampling keys share long\n * prefixes: `user_1000`, `user_1001`, `checkout-trace-0001`. A plain\n * multiply-and-add hash lets that shared prefix dominate the high bits, so a\n * whole key family lands in one narrow band and a rate of 0.1 keeps all of\n * them or none of them. FNV-1a followed by the murmur3 finalizer mixes the\n * low bits back through the word, so keys that differ in one character land\n * far apart.\n */\nexport function hashUnitInterval(value: string): number {\n let hash = 0x81_1c_9d_c5; // FNV-1a 32-bit offset basis\n for (let i = 0; i < value.length; i++) {\n hash ^= value.codePointAt(i) ?? 0;\n hash = Math.imul(hash, 0x01_00_01_93); // FNV prime\n }\n\n // murmur3 fmix32 avalanche\n hash ^= hash >>> 16;\n hash = Math.imul(hash, 0x85_eb_ca_6b);\n hash ^= hash >>> 13;\n hash = Math.imul(hash, 0xc2_b2_ae_35);\n hash ^= hash >>> 16;\n\n return (hash >>> 0) / 4_294_967_296;\n}\n\n/**\n * Sampler interface - return true to trace, false to skip\n */\nexport interface Sampler {\n /**\n * Decide whether to trace this operation\n *\n * @param context - Sampling context\n * @returns true to trace, false to skip\n */\n shouldSample(context: SamplingContext): boolean;\n\n /**\n * Whether this sampler needs tail sampling (post-execution decision)\n * If true, spans are always created and shouldKeepTrace() is called after execution\n *\n * @returns true if this sampler needs to evaluate after operation completes\n */\n needsTailSampling?(): boolean;\n\n /**\n * Re-evaluate sampling decision after operation completes (tail sampling)\n * Only called if needsTailSampling() returns true\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this trace should be kept, false to drop it\n */\n shouldKeepTrace?(context: SamplingContext, result: OperationResult): boolean;\n\n /**\n * How many events a kept event represents, as \"1 in N\".\n *\n * Autotel writes the result to {@link AUTOTEL_SAMPLING_RATE} so an analyst\n * can reweight counts. Return 1 when the sampler keeps everything.\n *\n * @param context - Sampling context\n * @returns Events represented per kept event\n */\n sampleRate?(context: SamplingContext): number;\n}\n\n/**\n * Context information for sampling decisions\n */\nexport interface SamplingContext {\n /** Operation name */\n operationName: string;\n /** Method arguments (for extracting user IDs, etc.) */\n args: unknown[];\n /** Optional metadata (e.g., feature flags, request headers) */\n metadata?: Record<string, unknown>;\n /** Optional span links for links-based sampling */\n links?: Link[];\n}\n\n/**\n * Result of a trace operation (for post-execution sampling)\n */\nexport interface OperationResult {\n /** Whether the operation succeeded */\n success: boolean;\n /** Duration in milliseconds */\n duration: number;\n /** Error if operation failed */\n error?: Error;\n}\n\n/**\n * Simple random sampler\n *\n * @example\n * ```typescript\n * new RandomSampler(0.1) // Sample 10% of requests\n * ```\n */\nexport class RandomSampler implements Sampler {\n constructor(private readonly rate: number) {\n if (rate < 0 || rate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n }\n\n shouldSample(_context: SamplingContext): boolean {\n return Math.random() < this.rate;\n }\n\n sampleRate(): number {\n return toSampleRate(this.rate);\n }\n}\n\n/**\n * Always sample (100% tracing)\n */\nexport class AlwaysSampler implements Sampler {\n shouldSample(_context: SamplingContext): boolean {\n return true;\n }\n}\n\n/**\n * Never sample (0% tracing)\n */\nexport class NeverSampler implements Sampler {\n shouldSample(_context: SamplingContext): boolean {\n return false;\n }\n}\n\n/**\n * Adaptive sampler that always traces errors and slow requests\n *\n * This is the recommended sampler for production use.\n * It ensures you never miss critical issues while keeping costs down.\n *\n * Strategy:\n * - Always trace errors (critical for debugging)\n * - Always trace slow requests (performance issues)\n * - Use baseline sample rate for successful fast requests\n *\n * **IMPORTANT - Tail Sampling Requirement:**\n * This sampler uses tail sampling (makes decisions AFTER execution).\n * You MUST use TailSamplingSpanProcessor for it to work correctly:\n *\n * - If using initInstrumentation(): TailSamplingSpanProcessor is auto-configured\n * - If using custom TracerProvider: You MUST manually register TailSamplingSpanProcessor\n *\n * Without TailSamplingSpanProcessor, ALL spans are exported (defeating the cost savings).\n *\n * @see TailSamplingSpanProcessor\n * @see README.md \"Tail Sampling with Custom Providers\" section\n *\n * @example\n * ```typescript\n * new AdaptiveSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * alwaysSampleErrors: true, // Always trace errors\n * alwaysSampleSlow: true // Always trace slow requests\n * })\n * ```\n */\nexport class AdaptiveSampler implements Sampler {\n private baselineSampleRate: number;\n private slowThresholdMs: number;\n private alwaysSampleErrors: boolean;\n private alwaysSampleSlow: boolean;\n private linksBased: boolean;\n private linksRate: number;\n private logger?: Logger;\n\n // Track whether we should sample this request\n private readonly samplingDecisions = new WeakMap<unknown[], boolean>();\n // Track operation results to enable post-execution decision\n private readonly operationResults = new WeakMap<unknown[], OperationResult>();\n\n constructor(\n options: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n /** Enable links-based sampling for event-driven architectures */\n linksBased?: boolean;\n /** Sampling rate for spans linked to sampled spans (0.0-1.0) */\n linksRate?: number;\n logger?: Logger;\n } = {},\n ) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.slowThresholdMs = options.slowThresholdMs ?? 1000;\n this.alwaysSampleErrors = options.alwaysSampleErrors ?? true;\n this.alwaysSampleSlow = options.alwaysSampleSlow ?? true;\n this.linksBased = options.linksBased ?? false;\n this.linksRate = options.linksRate ?? 1;\n this.logger = options.logger;\n\n if (this.baselineSampleRate < 0 || this.baselineSampleRate > 1) {\n throw new Error('Baseline sample rate must be between 0 and 1');\n }\n if (this.linksRate < 0 || this.linksRate > 1) {\n throw new Error('Links rate must be between 0 and 1');\n }\n }\n\n needsTailSampling(): boolean {\n // AdaptiveSampler ALWAYS needs tail sampling to implement error/slow capture\n return true;\n }\n\n shouldSample(context: SamplingContext): boolean {\n // For tail sampling, we optimistically create spans for all requests\n // The real decision happens in shouldKeepTrace() after execution\n // We still store the baseline decision for shouldKeepTrace() to use\n const baselineDecision = Math.random() < this.baselineSampleRate;\n this.samplingDecisions.set(context.args, baselineDecision);\n\n // Always return true to create the span (tail sampling will decide if we keep it)\n return true;\n }\n\n /**\n * Check if any links point to sampled spans.\n *\n * A span is considered linked to a sampled span if any of its links\n * have trace_flags with the sampled bit set (0x01).\n *\n * @param links - Array of span links to check\n * @returns true if any linked span is sampled, false otherwise\n */\n hasSampledLink(links: Link[]): boolean {\n if (!links || links.length === 0) {\n return false;\n }\n return links.some(\n (link) =>\n link.context && (link.context.traceFlags & TraceFlags.SAMPLED) !== 0,\n );\n }\n\n /**\n * Re-evaluate sampling decision after operation completes\n *\n * This allows us to always capture errors and slow requests,\n * even if they weren't initially sampled.\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this operation should be kept (not discarded)\n */\n shouldKeepTrace(context: SamplingContext, result: OperationResult): boolean {\n const baselineDecision = this.samplingDecisions.get(context.args) ?? false;\n\n // Always keep errors\n if (this.alwaysSampleErrors && !result.success) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n error: result.error?.message,\n },\n 'Adaptive sampling: Keeping error trace',\n );\n }\n return true;\n }\n\n // Always keep slow requests\n if (this.alwaysSampleSlow && result.duration >= this.slowThresholdMs) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n duration: result.duration,\n },\n 'Adaptive sampling: Keeping slow trace',\n );\n }\n return true;\n }\n\n // Check for sampled links (links-based sampling for event-driven systems)\n if (\n this.linksBased &&\n context.links &&\n this.hasSampledLink(context.links)\n ) {\n // Use linksRate to decide whether to keep the linked span\n const keepLinked = Math.random() < this.linksRate;\n if (keepLinked && !baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n linkCount: context.links.length,\n },\n 'Adaptive sampling: Keeping trace due to sampled link',\n );\n }\n return keepLinked;\n }\n\n // Otherwise, use baseline decision\n return baselineDecision;\n }\n}\n\n/**\n * User-based sampler for consistent tracing\n *\n * Always samples requests from specific user IDs.\n * Useful for debugging specific user issues or monitoring VIP users.\n *\n * @example\n * ```typescript\n * new UserIdSampler({\n * baselineSampleRate: 0.01, // 1% of normal users\n * alwaysSampleUsers: ['vip_123'], // Always trace VIP users\n * extractUserId: (args) => args[0]?.userId // Extract user ID from first arg\n * })\n * ```\n */\nexport class UserIdSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleUsers: Set<string>;\n private extractUserId: (args: unknown[]) => string | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleUsers?: string[];\n extractUserId: (args: unknown[]) => string | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleUsers = new Set(options.alwaysSampleUsers || []);\n this.extractUserId = options.extractUserId;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const userId = this.extractUserId(context.args);\n\n // Always sample specific users\n if (userId && this.alwaysSampleUsers.has(userId)) {\n this.logger?.debug(\n {\n operation: context.operationName,\n userId,\n },\n 'Sampling user request',\n );\n return true;\n }\n\n // For consistent per-user sampling, hash the user ID\n if (userId) {\n const hash = this.hashString(userId);\n return hash < this.baselineSampleRate;\n }\n\n // Fallback to random sampling if no user ID\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add user IDs to always-sample list\n */\n addAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.add(userId);\n }\n }\n\n /**\n * Remove user IDs from always-sample list\n */\n removeAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.delete(userId);\n }\n }\n\n /**\n * Simple hash function for consistent user sampling\n */\n private hashString(str: string): number {\n return hashUnitInterval(str);\n }\n}\n\n/**\n * Consistent sampler: every service reaches the same verdict for one trace.\n *\n * `RandomSampler` rolls the dice per process, so an upstream service can keep\n * a trace that its downstream drops, leaving a waterfall with holes in it.\n * Hashing a key that travels with the request removes the disagreement. Pass\n * the trace id, or any identifier every hop already shares.\n *\n * @example\n * ```typescript\n * new DeterministicSampler({\n * sampleRate: 0.1,\n * key: (context) => trace.getActiveSpan()?.spanContext().traceId,\n * })\n * ```\n */\nexport class DeterministicSampler implements Sampler {\n private readonly rate: number;\n private readonly key: (context: SamplingContext) => string | undefined;\n\n constructor(options: {\n /** Fraction of traces to keep, 0-1. */\n sampleRate: number;\n /** Identifier shared by every hop of the trace. */\n key: (context: SamplingContext) => string | undefined;\n }) {\n if (options.sampleRate < 0 || options.sampleRate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n this.rate = options.sampleRate;\n this.key = options.key;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const key = this.key(context);\n // No shared key means no agreement to preserve, so fall back to chance.\n if (key === undefined) {\n return Math.random() < this.rate;\n }\n return hashUnitInterval(key) < this.rate;\n }\n\n sampleRate(): number {\n return toSampleRate(this.rate);\n }\n}\n\n/** Bucket for keys seen after the tracked map fills up. */\nconst OVERFLOW_KEY = '__overflow__';\n\n/**\n * Per-key target-rate sampler for workloads with uneven traffic.\n *\n * A single rate serves a skewed workload badly: 1% floods storage with the\n * busiest endpoint and still loses the rare tenant whose failures you need.\n * This sampler counts traffic per key over a rolling window, then sets each\n * key its own rate so every key contributes roughly `targetPerKey` events.\n * Quiet keys survive intact; loud keys get thinned.\n *\n * The first window keeps everything, because no traffic history exists yet.\n * Rates take effect from the second window onward.\n *\n * @example\n * ```typescript\n * new KeyTargetRateSampler({\n * key: (context) => context.operationName,\n * targetPerKey: 10, // ~10 events per key per window\n * windowMs: 30_000,\n * })\n * ```\n */\nexport class KeyTargetRateSampler implements Sampler {\n private readonly key: (context: SamplingContext) => string | undefined;\n private readonly targetPerKey: number;\n private readonly windowMs: number;\n private readonly maxKeys: number;\n private counts = new Map<string, number>();\n private rates = new Map<string, number>();\n private windowStart = Date.now();\n\n constructor(options: {\n /** Groups traffic. Use the operation, route, tenant, or status. */\n key: (context: SamplingContext) => string | undefined;\n /** Events to keep per key per window. Default 10. */\n targetPerKey?: number;\n /** Length of the counting window in milliseconds. Default 30000. */\n windowMs?: number;\n /** Distinct keys to track before overflowing into one bucket. Default 1000. */\n maxKeys?: number;\n }) {\n this.key = options.key;\n this.targetPerKey = options.targetPerKey ?? 10;\n this.windowMs = options.windowMs ?? 30_000;\n this.maxKeys = options.maxKeys ?? 1000;\n\n if (this.targetPerKey <= 0) {\n throw new Error('Target per key must be greater than 0');\n }\n if (this.windowMs <= 0) {\n throw new Error('Window must be greater than 0');\n }\n }\n\n /** Turn the window's observed counts into the next window's rates. */\n private roll(now: number): void {\n if (now - this.windowStart < this.windowMs) {\n return;\n }\n const rates = new Map<string, number>();\n for (const [key, count] of this.counts) {\n rates.set(key, Math.max(1, count / this.targetPerKey));\n }\n this.rates = rates;\n this.counts = new Map();\n this.windowStart = now;\n }\n\n /**\n * Resolve the key, collapsing into one bucket once the map is full.\n *\n * An unbounded key function would otherwise grow the map without limit,\n * which turns a sampler meant to cut cost into a memory leak.\n */\n private resolveKey(context: SamplingContext): string {\n const key = this.key(context) ?? OVERFLOW_KEY;\n if (this.counts.has(key) || this.counts.size < this.maxKeys) {\n return key;\n }\n return OVERFLOW_KEY;\n }\n\n shouldSample(context: SamplingContext): boolean {\n this.roll(Date.now());\n const key = this.resolveKey(context);\n this.counts.set(key, (this.counts.get(key) ?? 0) + 1);\n const rate = this.rates.get(key) ?? 1;\n return rate <= 1 || Math.random() < 1 / rate;\n }\n\n sampleRate(context: SamplingContext): number {\n return this.rates.get(this.resolveKey(context)) ?? 1;\n }\n}\n\n/**\n * Composite sampler that combines multiple samplers\n *\n * Samples if ANY of the child samplers returns true.\n *\n * @example\n * ```typescript\n * new CompositeSampler([\n * new UserIdSampler({ extractUserId: (args) => args[0]?.userId }),\n * new AdaptiveSampler({ baselineSampleRate: 0.1 })\n * ])\n * ```\n */\nexport class CompositeSampler implements Sampler {\n constructor(private readonly samplers: Sampler[]) {\n if (samplers.length === 0) {\n throw new Error('CompositeSampler requires at least one child sampler');\n }\n }\n\n shouldSample(context: SamplingContext): boolean {\n return this.samplers.some((sampler) => sampler.shouldSample(context));\n }\n}\n\n/**\n * Feature flag sampler\n *\n * Always samples requests with specific feature flags enabled.\n * Perfect for correlating A/B test experiments with metrics.\n *\n * @example\n * ```typescript\n * new FeatureFlagSampler({\n * baselineSampleRate: 0.01,\n * alwaysSampleFlags: ['new_checkout', 'experimental_ui'],\n * extractFlags: (args, metadata) => metadata?.featureFlags\n * })\n * ```\n */\nexport class FeatureFlagSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleFlags: Set<string>;\n private extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleFlags?: string[];\n extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleFlags = new Set(options.alwaysSampleFlags || []);\n this.extractFlags = options.extractFlags;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const flags = this.extractFlags(context.args, context.metadata);\n\n // Always sample if any monitored flag is enabled\n if (flags && flags.some((flag) => this.alwaysSampleFlags.has(flag))) {\n this.logger?.debug(\n {\n operation: context.operationName,\n flags,\n },\n 'Sampling feature flag request',\n );\n return true;\n }\n\n // Fallback to random sampling\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add feature flags to always-sample list\n */\n addAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.add(flag);\n }\n }\n\n /**\n * Remove feature flags from always-sample list\n */\n removeAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.delete(flag);\n }\n }\n}\n\n// ============================================================================\n// Sampling Presets\n// ============================================================================\n\n/**\n * Named sampling presets for common environments.\n * Use with `init({ sampling: 'production' })` or directly via factories.\n */\nexport type SamplingPreset =\n 'development' | 'errors-only' | 'production' | 'off';\n\n/**\n * Sampling preset factories.\n *\n * For most users, the string shorthand on `init()` is simpler:\n * ```typescript\n * init({ service: 'my-app', sampling: 'production' })\n * ```\n *\n * Use factories when you need to customize:\n * ```typescript\n * init({ service: 'my-app', sampler: samplingPresets.production({ baselineSampleRate: 0.05 }) })\n * ```\n */\nexport const samplingPresets = {\n /** Capture everything — best for local development and debugging */\n development: () => new AlwaysSampler(),\n\n /** Only bad outcomes — zero baseline, errors always kept */\n errorsOnly: () =>\n new AdaptiveSampler({\n baselineSampleRate: 0,\n alwaysSampleErrors: true,\n }),\n\n /**\n * Balanced production defaults — 10% baseline + errors + slow traces.\n * Pass overrides to tune (uses the same option names as AdaptiveSampler).\n */\n production: (overrides?: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n }) =>\n new AdaptiveSampler({\n baselineSampleRate: 0.1,\n alwaysSampleErrors: true,\n alwaysSampleSlow: true,\n slowThresholdMs: 1000,\n ...overrides,\n }),\n\n /** Disable sampling entirely */\n off: () => new NeverSampler(),\n};\n\n/**\n * Resolve a preset string to a Sampler instance.\n * Used internally by `init()` when `sampling` string is provided.\n *\n * @throws Error if preset is not recognized\n */\nexport function resolveSamplingPreset(preset: SamplingPreset): Sampler {\n switch (preset) {\n case 'development': {\n return samplingPresets.development();\n }\n case 'errors-only': {\n return samplingPresets.errorsOnly();\n }\n case 'production': {\n return samplingPresets.production();\n }\n case 'off': {\n return samplingPresets.off();\n }\n default: {\n throw new Error(\n `Unknown sampling preset: \"${preset}\". Valid presets: development, errors-only, production, off`,\n );\n }\n }\n}\n\n// ============================================================================\n// Link Helper Functions\n// ============================================================================\n\n/**\n * Create a Link from W3C trace context headers (e.g., from a message queue).\n *\n * This is useful for message consumers that need to link to the producer span.\n * The headers should contain at least a `traceparent` header in W3C format.\n *\n * @param headers - Dictionary containing traceparent/tracestate headers\n * @param attributes - Optional attributes for the link\n * @returns Link object if context could be extracted, null otherwise\n *\n * @example\n * ```typescript\n * // In a Kafka consumer\n * const headers = { traceparent: '00-abc123...-def456...-01' };\n * const link = createLinkFromHeaders(headers);\n * if (link) {\n * // Use with tracer.startActiveSpan options or ctx.addLink()\n * tracer.startActiveSpan('process.message', { links: [link] }, span => { ... });\n * }\n * ```\n */\nexport function createLinkFromHeaders(\n headers: Record<string, string>,\n attributes?: Attributes,\n): Link | null {\n // Parse W3C traceparent header directly for reliability\n // Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n const traceparent = headers.traceparent || headers['traceparent'];\n if (!traceparent) {\n return null;\n }\n\n const spanContext = parseTraceparent(traceparent);\n if (!spanContext || !isValidSpanContext(spanContext)) {\n return null;\n }\n\n return {\n context: spanContext,\n attributes: attributes ?? {},\n };\n}\n\n/**\n * Extract Links from a batch of messages for fan-in scenarios.\n *\n * Useful for batch processing where multiple producer spans should be linked.\n * This enables tracing causality in event-driven architectures where a single\n * consumer processes messages from multiple producers.\n *\n * @param messages - List of message objects\n * @param headersKey - Key in each message containing trace headers (default: 'headers')\n * @returns List of Link objects for all valid trace contexts\n *\n * @example\n * ```typescript\n * // Processing a batch of SQS/Kafka messages\n * const messages = [\n * { body: '...', headers: { traceparent: '...' } },\n * { body: '...', headers: { traceparent: '...' } },\n * ];\n * const links = extractLinksFromBatch(messages);\n *\n * tracer.startActiveSpan('process.batch', { links }, span => {\n * for (const msg of messages) {\n * processMessage(msg);\n * }\n * });\n * ```\n */\nexport function extractLinksFromBatch(\n messages: Array<{ [key: string]: unknown }>,\n headersKey: string = 'headers',\n): Link[] {\n const links: Link[] = [];\n\n for (const msg of messages) {\n const msgHeaders = msg[headersKey];\n if (msgHeaders && typeof msgHeaders === 'object' && msgHeaders !== null) {\n const link = createLinkFromHeaders(msgHeaders as Record<string, string>, {\n 'messaging.batch.message_index': links.length,\n });\n if (link) {\n links.push(link);\n }\n }\n }\n\n return links;\n}\n\n/**\n * Parse W3C traceparent header into SpanContext\n * Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n *\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nfunction parseTraceparent(\n traceparent: string,\n): import('@opentelemetry/api').SpanContext | null {\n // W3C traceparent format: version-traceId-parentId-traceFlags\n // Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\n const TRACEPARENT_REGEX =\n /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;\n\n const match = traceparent.match(TRACEPARENT_REGEX);\n if (!match || match.length < 5) {\n return null;\n }\n\n const version = match[1];\n const traceId = match[2];\n const spanId = match[3];\n const flags = match[4];\n\n // Validate all parts are present (TypeScript narrowing)\n if (!version || !traceId || !spanId || !flags) {\n return null;\n }\n\n // Version 00 is currently the only version, but we should be forward compatible\n if (version === 'ff') {\n // Version ff is invalid according to spec\n return null;\n }\n\n return {\n traceId,\n spanId,\n traceFlags: Number.parseInt(flags, 16),\n isRemote: true,\n };\n}\n\n/**\n * Check if a SpanContext is valid (has non-zero trace and span IDs)\n */\nfunction isValidSpanContext(\n spanContext: import('@opentelemetry/api').SpanContext | null,\n): spanContext is import('@opentelemetry/api').SpanContext {\n if (!spanContext) return false;\n // TraceId should not be all zeros (00000000000000000000000000000000)\n // SpanId should not be all zeros (0000000000000000)\n return (\n spanContext.traceId !== '00000000000000000000000000000000' &&\n spanContext.spanId !== '0000000000000000'\n );\n}\n"],"mappings":"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"}
@@ -29,7 +29,9 @@ declare function escalateSecuritySeverity(severity: SecuritySeverity, floor: Sec
29
29
  * reference these instead of re-typing the strings.
30
30
  */
31
31
  declare const SECURITY_ATTR: {
32
- /** Marker set on every span carrying a security event. */readonly marker: "autotel.security"; /** Set when the event was force-kept through tail sampling. */
32
+ /** Marker set on every span carrying a security event. */
33
+ readonly marker: "autotel.security";
34
+ /** Set when the event was force-kept through tail sampling. */
33
35
  readonly forceKeep: "autotel.security.force_keep";
34
36
  readonly event: "security.event";
35
37
  readonly category: "security.category";
@@ -39,9 +41,12 @@ declare const SECURITY_ATTR: {
39
41
  readonly targetType: "security.target_type";
40
42
  readonly targetId: "security.target_id";
41
43
  readonly tenantId: "security.tenant_id";
42
- readonly reason: "security.reason"; /** Custom metadata keys dropped because they looked credential-shaped. */
43
- readonly droppedKeys: "security.dropped_keys"; /** Set by the signal processor on suspicious request paths. */
44
- readonly suspiciousRequest: "security.suspicious_request"; /** Pattern name that flagged a suspicious request, e.g. `path_traversal`. */
44
+ readonly reason: "security.reason";
45
+ /** Custom metadata keys dropped because they looked credential-shaped. */
46
+ readonly droppedKeys: "security.dropped_keys";
47
+ /** Set by the signal processor on suspicious request paths. */
48
+ readonly suspiciousRequest: "security.suspicious_request";
49
+ /** Pattern name that flagged a suspicious request, e.g. `path_traversal`. */
45
50
  readonly signal: "security.signal";
46
51
  };
47
52
  /** Metric names emitted by the security instrumentation. */
@@ -1 +1 @@
1
- {"version":3,"file":"security-schema.d.cts","names":[],"sources":["../src/security-schema.ts"],"mappings":";;AAYA;;;;AAA4B;AAG5B;;;;AAA2D;KAH/C,gBAAA;;cAGC,mBAAA,WAA8B,gBAAgB;;cAQ9C,sBAAA,EAAwB,MAAM,CAAC,gBAAA;AAW5C;;;;AAAA,iBAAgB,qBAAA,CACd,KAAA,WACA,QAAA,GAAU,gBAAA,GACT,gBAAgB;;iBAOH,uBAAA,CACd,QAAA,EAAU,gBAAA,EACV,GAAA,EAAK,gBAAgB;;iBAMP,wBAAA,CACd,QAAA,EAAU,gBAAA,EACV,KAAA,EAAO,gBAAA,GACN,gBAAA;AAlBgB;AAOnB;;;AAPmB,cA4BN,aAAA;EApBD,+FACL;EAAA;;;;;;;;;sCASY;EAAA,+CAFjB;EAAA,2DACA;EAAA;;AACiB;AAAA,cAiCN,gBAAA;EAAA;;;;;;;cASA,wBAAA;;;;;cAMA,sBAAA"}
1
+ {"version":3,"file":"security-schema.d.cts","names":[],"sources":["../src/security-schema.ts"],"mappings":";;;;;;;;;;;;KAYY;;cAGC,8BAA8B;;cAQ9B,wBAAwB,OAAO;;;;;iBAW5B,sBACd,gBACA,WAAU,mBACT;;iBAOa,wBACd,UAAU,kBACV,KAAK;;iBAMS,yBACd,UAAU,kBACV,OAAO,mBACN;;;;;cAUU;;;;;;;;;;;;;;;;;;;;;;cAuBA;;;;;;;;cASA;;;;;cAMA"}
@@ -29,7 +29,9 @@ declare function escalateSecuritySeverity(severity: SecuritySeverity, floor: Sec
29
29
  * reference these instead of re-typing the strings.
30
30
  */
31
31
  declare const SECURITY_ATTR: {
32
- /** Marker set on every span carrying a security event. */readonly marker: "autotel.security"; /** Set when the event was force-kept through tail sampling. */
32
+ /** Marker set on every span carrying a security event. */
33
+ readonly marker: "autotel.security";
34
+ /** Set when the event was force-kept through tail sampling. */
33
35
  readonly forceKeep: "autotel.security.force_keep";
34
36
  readonly event: "security.event";
35
37
  readonly category: "security.category";
@@ -39,9 +41,12 @@ declare const SECURITY_ATTR: {
39
41
  readonly targetType: "security.target_type";
40
42
  readonly targetId: "security.target_id";
41
43
  readonly tenantId: "security.tenant_id";
42
- readonly reason: "security.reason"; /** Custom metadata keys dropped because they looked credential-shaped. */
43
- readonly droppedKeys: "security.dropped_keys"; /** Set by the signal processor on suspicious request paths. */
44
- readonly suspiciousRequest: "security.suspicious_request"; /** Pattern name that flagged a suspicious request, e.g. `path_traversal`. */
44
+ readonly reason: "security.reason";
45
+ /** Custom metadata keys dropped because they looked credential-shaped. */
46
+ readonly droppedKeys: "security.dropped_keys";
47
+ /** Set by the signal processor on suspicious request paths. */
48
+ readonly suspiciousRequest: "security.suspicious_request";
49
+ /** Pattern name that flagged a suspicious request, e.g. `path_traversal`. */
45
50
  readonly signal: "security.signal";
46
51
  };
47
52
  /** Metric names emitted by the security instrumentation. */
@@ -1 +1 @@
1
- {"version":3,"file":"security-schema.d.ts","names":[],"sources":["../src/security-schema.ts"],"mappings":";;AAYA;;;;AAA4B;AAG5B;;;;AAA2D;KAH/C,gBAAA;;cAGC,mBAAA,WAA8B,gBAAgB;;cAQ9C,sBAAA,EAAwB,MAAM,CAAC,gBAAA;AAW5C;;;;AAAA,iBAAgB,qBAAA,CACd,KAAA,WACA,QAAA,GAAU,gBAAA,GACT,gBAAgB;;iBAOH,uBAAA,CACd,QAAA,EAAU,gBAAA,EACV,GAAA,EAAK,gBAAgB;;iBAMP,wBAAA,CACd,QAAA,EAAU,gBAAA,EACV,KAAA,EAAO,gBAAA,GACN,gBAAA;AAlBgB;AAOnB;;;AAPmB,cA4BN,aAAA;EApBD,+FACL;EAAA;;;;;;;;;sCASY;EAAA,+CAFjB;EAAA,2DACA;EAAA;;AACiB;AAAA,cAiCN,gBAAA;EAAA;;;;;;;cASA,wBAAA;;;;;cAMA,sBAAA"}
1
+ {"version":3,"file":"security-schema.d.ts","names":[],"sources":["../src/security-schema.ts"],"mappings":";;;;;;;;;;;;KAYY;;cAGC,8BAA8B;;cAQ9B,wBAAwB,OAAO;;;;;iBAW5B,sBACd,gBACA,WAAU,mBACT;;iBAOa,wBACd,UAAU,kBACV,KAAK;;iBAMS,yBACd,UAAU,kBACV,OAAO,mBACN;;;;;cAUU;;;;;;;;;;;;;;;;;;;;;;cAuBA;;;;;;;;cASA;;;;;cAMA"}
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-conventions-FhSxv-bK.d.cts","names":[],"sources":["../src/attributes/registry.ts","../src/semantic-conventions.ts"],"mappings":";cA0Ba,cAAA;EAAA;;;;;;;;;;;cA4BA,iBAAA;EAAA;;;;cAqBA,aAAA;EAAA;;;;;;;;iBCnEG,0BAAA,CAA2B,IAAY;AAAA,iBAIvC,2BAAA,CAA4B,IAAY"}
1
+ {"version":3,"file":"semantic-conventions-FhSxv-bK.d.cts","names":[],"sources":["../src/attributes/registry.ts","../src/semantic-conventions.ts"],"mappings":";cA0Ba;;;;;;;;;;;;cA4BA;;;;;cAqBA;;;;;;;;;iBC3EG,2BAA2B;iBAI3B,4BAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-conventions-FhSxv-bK.d.ts","names":[],"sources":["../src/attributes/registry.ts","../src/semantic-conventions.ts"],"mappings":";cA0Ba,cAAA;EAAA;;;;;;;;;;;cA4BA,iBAAA;EAAA;;;;cAqBA,aAAA;EAAA;;;;;;;;iBCnEG,0BAAA,CAA2B,IAAY;AAAA,iBAIvC,2BAAA,CAA4B,IAAY"}
1
+ {"version":3,"file":"semantic-conventions-FhSxv-bK.d.ts","names":[],"sources":["../src/attributes/registry.ts","../src/semantic-conventions.ts"],"mappings":";cA0Ba;;;;;;;;;;;;cA4BA;;;;;cAqBA;;;;;;;;;iBC3EG,2BAA2B;iBAI3B,4BAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-conventions.cjs","names":[],"sources":["../src/semantic-conventions.ts"],"sourcesContent":["import {\n HTTPAttributes,\n ServiceAttributes,\n URLAttributes,\n} from './attributes/registry';\n\nexport { HTTPAttributes, ServiceAttributes, URLAttributes };\n\nexport function httpRequestHeaderAttribute(name: string): string {\n return `http.request.header.${name.toLowerCase()}`;\n}\n\nexport function httpResponseHeaderAttribute(name: string): string {\n return `http.response.header.${name.toLowerCase()}`;\n}\n"],"mappings":";;;;AAQA,SAAgB,2BAA2B,MAAsB;CAC/D,OAAO,uBAAuB,KAAK,YAAY;AACjD;AAEA,SAAgB,4BAA4B,MAAsB;CAChE,OAAO,wBAAwB,KAAK,YAAY;AAClD"}
1
+ {"version":3,"file":"semantic-conventions.cjs","names":[],"sources":["../src/semantic-conventions.ts"],"sourcesContent":["export function httpRequestHeaderAttribute(name: string): string {\n return `http.request.header.${name.toLowerCase()}`;\n}\n\nexport function httpResponseHeaderAttribute(name: string): string {\n return `http.response.header.${name.toLowerCase()}`;\n}\n\nexport {\n HTTPAttributes,\n ServiceAttributes,\n URLAttributes,\n} from './attributes/registry';\n"],"mappings":";;;;AAAA,SAAgB,2BAA2B,MAAsB;CAC/D,OAAO,uBAAuB,KAAK,YAAY;AACjD;AAEA,SAAgB,4BAA4B,MAAsB;CAChE,OAAO,wBAAwB,KAAK,YAAY;AAClD"}
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-conventions.js","names":[],"sources":["../src/semantic-conventions.ts"],"sourcesContent":["import {\n HTTPAttributes,\n ServiceAttributes,\n URLAttributes,\n} from './attributes/registry';\n\nexport { HTTPAttributes, ServiceAttributes, URLAttributes };\n\nexport function httpRequestHeaderAttribute(name: string): string {\n return `http.request.header.${name.toLowerCase()}`;\n}\n\nexport function httpResponseHeaderAttribute(name: string): string {\n return `http.response.header.${name.toLowerCase()}`;\n}\n"],"mappings":";;;AAQA,SAAgB,2BAA2B,MAAsB;CAC/D,OAAO,uBAAuB,KAAK,YAAY;AACjD;AAEA,SAAgB,4BAA4B,MAAsB;CAChE,OAAO,wBAAwB,KAAK,YAAY;AAClD"}
1
+ {"version":3,"file":"semantic-conventions.js","names":[],"sources":["../src/semantic-conventions.ts"],"sourcesContent":["export function httpRequestHeaderAttribute(name: string): string {\n return `http.request.header.${name.toLowerCase()}`;\n}\n\nexport function httpResponseHeaderAttribute(name: string): string {\n return `http.response.header.${name.toLowerCase()}`;\n}\n\nexport {\n HTTPAttributes,\n ServiceAttributes,\n URLAttributes,\n} from './attributes/registry';\n"],"mappings":";;;AAAA,SAAgB,2BAA2B,MAAsB;CAC/D,OAAO,uBAAuB,KAAK,YAAY;AACjD;AAEA,SAAgB,4BAA4B,MAAsB;CAChE,OAAO,wBAAwB,KAAK,YAAY;AAClD"}