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
package/README.md CHANGED
@@ -142,20 +142,20 @@ Replace `NODE_OPTIONS` and 30+ lines of SDK boilerplate with `init()`, wrap func
142
142
 
143
143
  `autotel` has ~35 subpath exports. For most scenarios you only need one or two. Cloudflare Workers and other edge runtimes should use [`autotel-cloudflare`](../autotel-cloudflare) or [`autotel-edge`](../autotel-edge), not `autotel` (which expects Node).
144
144
 
145
- | Scenario | Package | Import |
146
- | --------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------- |
147
- | Node service — init + spans | `autotel` | `import { init, trace, span } from 'autotel'` |
148
- | Node service — pino-style logger with trace context | `autotel` | `import { createLogger } from 'autotel/logger'` |
149
- | Node service — class decorators | `autotel` | `import { Trace, Span } from 'autotel/decorators'` |
150
- | Node service — Drizzle ORM spans | `autotel-drizzle` | `import { instrumentDrizzleClient } from 'autotel-drizzle'` |
151
- | Node service — testing assertions | `autotel` | `import { createTraceCollector } from 'autotel/testing'` |
152
- | Cloudflare Worker — fetch with spans | `autotel-cloudflare` | `import { wrapModule, trace } from 'autotel-cloudflare'` |
153
- | Cloudflare Worker — logs only, no `nodejs_compat` | `autotel-cloudflare` | `import { createEdgeLogger } from 'autotel-cloudflare/logger'` |
154
- | Cloudflare Worker — queue consumer | `autotel-cloudflare` | `import { wrapModule, getQueueLogger } from 'autotel-cloudflare'` |
155
- | Cloudflare Worker — Durable Object | `autotel-cloudflare` | `import { wrapDurableObject } from 'autotel-cloudflare'` |
156
- | Hono on Workers | `autotel-cloudflare` + `autotel-hono` | `wrapModule` from `autotel-cloudflare`, middleware from `autotel-hono` |
157
- | Vercel Edge / Netlify Edge / Deno Deploy | `autotel-edge` | `import { init, trace } from 'autotel-edge'` |
158
- | Edge runtime — logs only | `autotel-edge` | `import { createEdgeLogger } from 'autotel-edge/logger'` |
145
+ | Scenario | Package | Import |
146
+ | -------------------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------- |
147
+ | Node service: init + spans | `autotel` | `import { init, trace, span, withTracing, span } from 'autotel'` |
148
+ | Node service: pino-style logger with trace context | `autotel` | `import { createLogger } from 'autotel/logger'` |
149
+ | Node service: class decorators | `autotel` | `import { Trace, Span } from 'autotel/decorators'` |
150
+ | Node service: Drizzle ORM spans | `autotel-drizzle` | `import { instrumentDrizzleClient } from 'autotel-drizzle'` |
151
+ | Node service: testing assertions | `autotel` | `import { createTraceCollector } from 'autotel/testing'` |
152
+ | Cloudflare Worker: fetch with spans | `autotel-cloudflare` | `import { wrapModule, trace, span, withTracing } from 'autotel-cloudflare'` |
153
+ | Cloudflare Worker: logs only, no `nodejs_compat` | `autotel-cloudflare` | `import { createEdgeLogger } from 'autotel-cloudflare/logger'` |
154
+ | Cloudflare Worker: queue consumer | `autotel-cloudflare` | `import { wrapModule, getQueueLogger } from 'autotel-cloudflare'` |
155
+ | Cloudflare Worker: Durable Object | `autotel-cloudflare` | `import { wrapDurableObject } from 'autotel-cloudflare'` |
156
+ | Hono on Workers | `autotel-cloudflare` + `autotel-hono` | `wrapModule` from `autotel-cloudflare`, middleware from `autotel-hono` |
157
+ | Vercel Edge / Netlify Edge / Deno Deploy | `autotel-edge` | `import { init, trace, span, withTracing } from 'autotel-edge'` |
158
+ | Edge runtime: logs only | `autotel-edge` | `import { createEdgeLogger } from 'autotel-edge/logger'` |
159
159
 
160
160
  ## Quick Start
161
161
 
@@ -224,7 +224,7 @@ Sampling presets:
224
224
  ### 3. Instrument code with `trace()`
225
225
 
226
226
  ```typescript
227
- import { trace } from 'autotel';
227
+ import { trace, span, withTracing, getActiveTraceContext } from 'autotel';
228
228
 
229
229
  export const createUser = trace(async function createUser(
230
230
  data: CreateUserData,
@@ -236,6 +236,9 @@ export const createUser = trace(async function createUser(
236
236
 
237
237
  - Named function expressions automatically become span names (`code.function`).
238
238
  - Errors are recorded, spans are ended, and status is set automatically.
239
+ - When inference may be unreliable, use `trace('user.create', fn)` or
240
+ `instrument({ key: 'user.create', fn })`. For a module-sized batch, use
241
+ `instrument({ functions: { createUser, updateUser } })`.
239
242
 
240
243
  ### 4. See the value everywhere
241
244
 
@@ -522,7 +525,7 @@ These use the `autotel.*` namespace intentionally. OpenTelemetry does not define
522
525
  Wrap any sync/async function to create spans automatically.
523
526
 
524
527
  ```typescript
525
- import { trace } from 'autotel';
528
+ import { trace, span, withTracing } from 'autotel';
526
529
 
527
530
  export const updateUser = trace(async function updateUser(
528
531
  id: string,
@@ -536,26 +539,27 @@ export const deleteUser = trace('user.delete', async (id: string) => {
536
539
  return db.users.delete(id);
537
540
  });
538
541
 
539
- // Factory form exposes the `ctx` helper (see below)
540
- export const createOrder = trace((ctx) => async (order: Order) => {
541
- ctx.setAttribute('order.id', order.id);
542
- return submit(order);
543
- });
542
+ // Explicit factory form exposes the `ctx` helper
543
+ export const createOrder = withTracing({ name: 'order.create' })(
544
+ (ctx) => async (order: Order) => {
545
+ ctx.setAttribute('order.id', order.id);
546
+ return submit(order);
547
+ },
548
+ );
544
549
 
545
- // Immediate execution - wraps and executes instantly (for middleware/wrappers)
550
+ // For one-off work, create the wrapper and call it
546
551
  function timed<T>(operation: string, fn: () => Promise<T>): Promise<T> {
547
- return trace(operation, async (ctx) => {
548
- ctx.setAttribute('operation', operation);
552
+ return trace(operation, async () => {
553
+ getActiveTraceContext()?.setAttribute('operation', operation);
549
554
  return await fn();
550
- });
555
+ })();
551
556
  }
552
- // Executes immediately, returns Promise<T> directly
553
557
  ```
554
558
 
555
- **Two patterns supported:**
559
+ **Context access:**
556
560
 
557
- 1. **Factory pattern** `trace(ctx => (...args) => result)` : Returns a wrapped function for reuse
558
- 2. **Immediate execution** `trace(ctx => result)` : Executes once immediately, returns the result directly
561
+ 1. Plain `trace(name?, fn)` wrappers receive their real arguments; use `getActiveTraceContext()` inside.
562
+ 2. Explicit factories use `withTracing({ name })(ctx => (...args) => result)`.
559
563
 
560
564
  - Automatic span lifecycle (`start`, `end`, status, and error recording).
561
565
  - Function names feed `operation.name`, `code.function`, and events enrichment.
@@ -566,7 +570,7 @@ function timed<T>(operation: string, fn: () => Promise<T>): Promise<T> {
566
570
  Create nested spans for individual code blocks without wrapping entire functions.
567
571
 
568
572
  ```typescript
569
- import { span, trace } from 'autotel';
573
+ import { span, trace, withTracing } from 'autotel';
570
574
 
571
575
  export const rollDice = trace(async function rollDice(rolls: number) {
572
576
  const results: number[] = [];
@@ -591,27 +595,29 @@ Nested spans automatically inherit context and correlation IDs.
591
595
 
592
596
  ### Trace Context (`ctx`)
593
597
 
594
- Every `trace((ctx) => ...)` factory receives a type-safe helper backed by `AsyncLocalStorage`.
598
+ Every `withTracing({})((ctx) => ...)` factory receives a type-safe helper backed by `AsyncLocalStorage`.
595
599
 
596
600
  ```typescript
597
- import { trace, recordStructuredError } from 'autotel';
601
+ import { trace, span, withTracing, recordStructuredError } from 'autotel';
598
602
  import { SpanStatusCode } from '@opentelemetry/api';
599
603
 
600
- export const createUser = trace((ctx) => async (input: CreateUserData) => {
601
- logger.info({ traceId: ctx.traceId }, 'Handling request');
602
- ctx.setAttributes({ 'user.id': input.id, 'user.plan': input.plan });
604
+ export const createUser = withTracing({})(
605
+ (ctx) => async (input: CreateUserData) => {
606
+ logger.info({ traceId: ctx.traceId }, 'Handling request');
607
+ ctx.setAttributes({ 'user.id': input.id, 'user.plan': input.plan });
603
608
 
604
- try {
605
- const user = await db.users.create(input);
606
- ctx.setStatus({ code: SpanStatusCode.OK });
607
- return user;
608
- } catch (error) {
609
- // Records the error on the span and sets ERROR status. Pair with
610
- // `getRequestLogger(ctx).error(error)` if you also want a correlated log.
611
- recordStructuredError(ctx, error as Error);
612
- throw error;
613
- }
614
- });
609
+ try {
610
+ const user = await db.users.create(input);
611
+ ctx.setStatus({ code: SpanStatusCode.OK });
612
+ return user;
613
+ } catch (error) {
614
+ // Records the error on the span and sets ERROR status. Pair with
615
+ // `getRequestLogger(ctx).error(error)` if you also want a correlated log.
616
+ recordStructuredError(ctx, error as Error);
617
+ throw error;
618
+ }
619
+ },
620
+ );
615
621
  ```
616
622
 
617
623
  Available helpers: `traceId`, `spanId`, `correlationId`, `setAttribute`, `setAttributes`, `setStatus`, `getBaggage`, `setBaggage`, `deleteBaggage`, `getAllBaggage`.
@@ -626,11 +632,11 @@ Available helpers: `traceId`, `spanId`, `correlationId`, `setAttribute`, `setAtt
626
632
  Baggage allows you to propagate custom key-value pairs across distributed traces. Baggage is automatically included in HTTP headers when using `injectTraceContext()` from `autotel/http`.
627
633
 
628
634
  ```typescript
629
- import { trace, withBaggage } from 'autotel';
635
+ import { trace, span, withTracing, withBaggage } from 'autotel';
630
636
  import { injectTraceContext } from 'autotel/http';
631
637
 
632
638
  // Set baggage for downstream services
633
- export const createOrder = trace((ctx) => async (order: Order) => {
639
+ export const createOrder = withTracing({})((ctx) => async (order: Order) => {
634
640
  return await withBaggage({
635
641
  baggage: {
636
642
  'tenant.id': order.tenantId,
@@ -654,7 +660,7 @@ export const createOrder = trace((ctx) => async (order: Order) => {
654
660
  For type-safe baggage operations, use `defineBaggageSchema()`:
655
661
 
656
662
  ```typescript
657
- import { trace, defineBaggageSchema } from 'autotel';
663
+ import { trace, span, withTracing, defineBaggageSchema } from 'autotel';
658
664
 
659
665
  type TenantBaggage = { tenantId: string; region?: string };
660
666
  const tenantBaggage = defineBaggageSchema<TenantBaggage>('tenant');
@@ -678,14 +684,14 @@ export const handler = trace<TenantBaggage>((ctx) => async () => {
678
684
  Enable `baggage: true` in `init()` to automatically copy all baggage entries to span attributes, making them visible in trace UIs without manual `ctx.setAttribute()` calls:
679
685
 
680
686
  ```typescript
681
- import { init, trace, withBaggage } from 'autotel';
687
+ import { init, trace, span, withTracing, withBaggage } from 'autotel';
682
688
 
683
689
  init({
684
690
  service: 'my-app',
685
691
  baggage: true, // Auto-copy baggage to span attributes
686
692
  });
687
693
 
688
- export const processOrder = trace((ctx) => async (order: Order) => {
694
+ export const processOrder = withTracing({})((ctx) => async (order: Order) => {
689
695
  return await withBaggage({
690
696
  baggage: {
691
697
  'tenant.id': order.tenantId,
@@ -713,7 +719,13 @@ init({
713
719
  **Extracting Baggage from Incoming Requests:**
714
720
 
715
721
  ```typescript
716
- import { extractTraceContext, trace, context } from 'autotel';
722
+ import {
723
+ extractTraceContext,
724
+ trace,
725
+ span,
726
+ withTracing,
727
+ context,
728
+ } from 'autotel';
717
729
 
718
730
  // In Express middleware
719
731
  app.use((req, res, next) => {
@@ -888,7 +900,7 @@ Attachers know WHERE to attach attributes - they handle spans, resources, and ap
888
900
  import { setUser, httpServer, identify, dbClient } from 'autotel/attributes';
889
901
 
890
902
  // Set user attributes with automatic PII redaction
891
- export const handleRequest = trace((ctx) => async (req) => {
903
+ export const handleRequest = withTracing({})((ctx) => async (req) => {
892
904
  setUser(ctx, {
893
905
  id: req.userId,
894
906
  email: req.userEmail, // Automatically redacted by default
@@ -904,7 +916,7 @@ export const handleRequest = trace((ctx) => async (req) => {
904
916
  });
905
917
 
906
918
  // Bundle user, session, and device attributes together
907
- export const identifyUser = trace((ctx) => async (data) => {
919
+ export const identifyUser = withTracing({})((ctx) => async (data) => {
908
920
  identify(ctx, {
909
921
  user: { id: data.userId, name: data.userName },
910
922
  session: { id: data.sessionId },
@@ -913,7 +925,7 @@ export const identifyUser = trace((ctx) => async (data) => {
913
925
  });
914
926
 
915
927
  // Database client attributes
916
- export const queryUsers = trace((ctx) => async () => {
928
+ export const queryUsers = withTracing({})((ctx) => async () => {
917
929
  dbClient(ctx, {
918
930
  system: 'postgresql',
919
931
  operation: 'SELECT',
@@ -930,7 +942,7 @@ export const queryUsers = trace((ctx) => async () => {
930
942
  ```typescript
931
943
  import { safeSetAttributes, attrs } from 'autotel/attributes';
932
944
 
933
- export const processUser = trace((ctx) => async (user) => {
945
+ export const processUser = withTracing({})((ctx) => async (user) => {
934
946
  // Default: PII is redacted automatically
935
947
  safeSetAttributes(ctx, attrs.user.data({ email: 'user@example.com' }));
936
948
  // → { 'user.email': '[REDACTED]' }
@@ -980,7 +992,7 @@ Domain helpers bundle multiple attribute groups for common scenarios:
980
992
  import { transaction } from 'autotel/attributes';
981
993
 
982
994
  // Bundle HTTP request with user context
983
- export const handleRequest = trace((ctx) => async (req) => {
995
+ export const handleRequest = withTracing({})((ctx) => async (req) => {
984
996
  transaction(ctx, {
985
997
  user: { id: req.userId },
986
998
  session: { id: req.sessionId },
@@ -1248,9 +1260,9 @@ Baggage allows key-value pairs to propagate across service boundaries. Autotel p
1248
1260
  Use the pre-built `BusinessBaggage` schema for common business context:
1249
1261
 
1250
1262
  ```typescript
1251
- import { BusinessBaggage, trace } from 'autotel';
1263
+ import { BusinessBaggage, trace, span, withTracing } from 'autotel';
1252
1264
 
1253
- export const processOrder = trace((ctx) => async (order: Order) => {
1265
+ export const processOrder = withTracing({})((ctx) => async (order: Order) => {
1254
1266
  // Set business context (propagates to downstream services)
1255
1267
  BusinessBaggage.set(ctx, {
1256
1268
  tenantId: order.tenantId,
@@ -1266,7 +1278,7 @@ export const processOrder = trace((ctx) => async (order: Order) => {
1266
1278
  });
1267
1279
 
1268
1280
  // In downstream service
1269
- export const chargeOrder = trace((ctx) => async () => {
1281
+ export const chargeOrder = withTracing({})((ctx) => async () => {
1270
1282
  // Read business context
1271
1283
  const { tenantId, userId, priority } = BusinessBaggage.get(ctx);
1272
1284
 
@@ -1311,7 +1323,7 @@ const OrderBaggage = createSafeBaggageSchema(
1311
1323
  );
1312
1324
 
1313
1325
  // Use in traced functions
1314
- export const processOrder = trace((ctx) => async (order: Order) => {
1326
+ export const processOrder = withTracing({})((ctx) => async (order: Order) => {
1315
1327
  // Type-safe set (TypeScript validates fields)
1316
1328
  OrderBaggage.set(ctx, {
1317
1329
  orderId: order.id,
@@ -1443,12 +1455,12 @@ export const orderSaga = traceWorkflow({
1443
1455
  // 2. ReserveInventory.compensate (release)
1444
1456
  ```
1445
1457
 
1446
- **WorkflowContext Methods:**
1458
+ **Context Methods:**
1447
1459
 
1448
1460
  - `ctx.getWorkflowId()` - Get current workflow instance ID
1449
1461
  - `ctx.getWorkflowName()` - Get workflow type name
1450
- - `ctx.getStepIndex()` - Current step number
1451
- - `ctx.getPreviousStepContext()` - SpanContext for linking
1462
+ - Step factories receive `StepContext`, which adds `getStepName()`,
1463
+ `getStepIndex()`, and `getWorkflowContext()`
1452
1464
 
1453
1465
  **Compensation Attributes:**
1454
1466
 
@@ -1468,7 +1480,7 @@ import { Metric, createHistogram } from 'autotel';
1468
1480
  const metrics = new Metric('checkout');
1469
1481
  const revenue = createHistogram('checkout.revenue');
1470
1482
 
1471
- export const processOrder = trace((ctx) => async (order) => {
1483
+ export const processOrder = withTracing({})((ctx) => async (order) => {
1472
1484
  metrics.trackEvent('order.completed', {
1473
1485
  orderId: order.id,
1474
1486
  amount: order.total,
@@ -1488,7 +1500,7 @@ Track user behavior, conversion funnels, and business outcomes alongside your Op
1488
1500
  **Recommended: Configure subscribers in `init()`, use global `track()` function:**
1489
1501
 
1490
1502
  ```typescript
1491
- import { init, track, trace } from 'autotel';
1503
+ import { init, track, trace, span, withTracing } from 'autotel';
1492
1504
  import { PostHogSubscriber } from 'autotel-subscribers/posthog';
1493
1505
 
1494
1506
  init({
@@ -1559,7 +1571,7 @@ npm install @opentelemetry/instrumentation-pino
1559
1571
 
1560
1572
  ```typescript
1561
1573
  import pino from 'pino';
1562
- import { init, trace } from 'autotel';
1574
+ import { init, trace, span, withTracing } from 'autotel';
1563
1575
 
1564
1576
  const logger = pino({
1565
1577
  level: process.env.LOG_LEVEL || 'info',
@@ -1665,7 +1677,7 @@ init({
1665
1677
  ### Basic Usage
1666
1678
 
1667
1679
  ```typescript
1668
- import { init, trace, setUser, httpServer } from 'autotel';
1680
+ import { init, trace, span, withTracing, setUser, httpServer } from 'autotel';
1669
1681
  import pino from 'pino';
1670
1682
 
1671
1683
  const logger = pino();
@@ -1679,28 +1691,30 @@ init({
1679
1691
  },
1680
1692
  });
1681
1693
 
1682
- export const processCheckout = trace((ctx) => async (order: Order) => {
1683
- setUser(ctx, {
1684
- id: order.userId,
1685
- subscription: order.plan,
1686
- accountAgeDays: daysSince(order.userCreatedAt),
1687
- });
1694
+ export const processCheckout = withTracing({})(
1695
+ (ctx) => async (order: Order) => {
1696
+ setUser(ctx, {
1697
+ id: order.userId,
1698
+ subscription: order.plan,
1699
+ accountAgeDays: daysSince(order.userCreatedAt),
1700
+ });
1688
1701
 
1689
- httpServer(ctx, {
1690
- method: 'POST',
1691
- route: '/api/checkout',
1692
- statusCode: 200,
1693
- });
1702
+ httpServer(ctx, {
1703
+ method: 'POST',
1704
+ route: '/api/checkout',
1705
+ statusCode: 200,
1706
+ });
1694
1707
 
1695
- ctx.setAttributes({
1696
- 'cart.total_cents': order.total,
1697
- 'payment.method': order.paymentMethod,
1698
- 'payment.provider': 'stripe',
1699
- });
1708
+ ctx.setAttributes({
1709
+ 'cart.total_cents': order.total,
1710
+ 'payment.method': order.paymentMethod,
1711
+ 'payment.provider': 'stripe',
1712
+ });
1700
1713
 
1701
- // When this span ends, a canonical log line is automatically emitted
1702
- // with ALL attributes: user.id, user.subscription, cart.total_cents, etc.
1703
- });
1714
+ // When this span ends, a canonical log line is automatically emitted
1715
+ // with ALL attributes: user.id, user.subscription, cart.total_cents, etc.
1716
+ },
1717
+ );
1704
1718
  ```
1705
1719
 
1706
1720
  ### What You Get
@@ -1798,9 +1812,15 @@ It writes correlated request context and log records, so canonical log lines sti
1798
1812
  wide event per request.
1799
1813
 
1800
1814
  ```typescript
1801
- import { trace, getRequestLogger, createStructuredError } from 'autotel';
1802
-
1803
- export const checkout = trace((ctx) => async (order: Order) => {
1815
+ import {
1816
+ trace,
1817
+ span,
1818
+ withTracing,
1819
+ getRequestLogger,
1820
+ createStructuredError,
1821
+ } from 'autotel';
1822
+
1823
+ export const checkout = withTracing({})((ctx) => async (order: Order) => {
1804
1824
  const log = getRequestLogger(ctx);
1805
1825
 
1806
1826
  log.set({ user: { id: order.userId, plan: order.plan } });
@@ -1884,7 +1904,7 @@ try {
1884
1904
 
1885
1905
  `autotel/diagnostics` bridges Node's built-in
1886
1906
  [`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) into
1887
- autotel spans and events — no monkey-patching, no `import-in-the-middle`. Every
1907
+ autotel spans and events. No monkey-patching, no `import-in-the-middle`. Every
1888
1908
  entry point is opt-in and degrades to a no-op on runtimes (edge, old Node) that
1889
1909
  lack the underlying channels.
1890
1910
 
@@ -1915,8 +1935,8 @@ const stop = instrumentHttp(); // SERVER span per inbound request (parented to t
1915
1935
 
1916
1936
  This is an opt-in alternative to `@opentelemetry/instrumentation-http` for span
1917
1937
  coverage and propagation. Limitation: a plain channel can't wrap the request
1918
- handler, so it does **not** set an ambient context for the handler's duration —
1919
- application spans created inside a handler won't auto-nest under the SERVER span.
1938
+ handler, so it does **not** set an ambient context for the handler's duration.
1939
+ Application spans created inside a handler won't auto-nest under the SERVER span.
1920
1940
  Use `@opentelemetry/instrumentation-http` if you need that nesting.
1921
1941
 
1922
1942
  **Bridge any channel** with the shared primitive (also used by
@@ -2332,7 +2352,7 @@ Autotel is designed as an **enabler** - it provides composable primitives that l
2332
2352
  ### Instrumenting Queue Consumers
2333
2353
 
2334
2354
  ```typescript
2335
- import { trace, span, track } from 'autotel';
2355
+ import { trace, span, withTracing, span, track } from 'autotel';
2336
2356
 
2337
2357
  // Wrap your consumer handler with trace()
2338
2358
  export const processMessage = trace(async function processMessage(
@@ -2369,7 +2389,7 @@ consumer.on('message', async (msg) => {
2369
2389
  ### Instrumenting Scheduled Jobs / Cron
2370
2390
 
2371
2391
  ```typescript
2372
- import { trace, getMetrics } from 'autotel';
2392
+ import { trace, span, withTracing, getMetrics } from 'autotel';
2373
2393
 
2374
2394
  export const dailyReportJob = trace(async function dailyReportJob() {
2375
2395
  const metrics = getMetrics();
@@ -2632,7 +2652,7 @@ For edge runtimes with different constraints:
2632
2652
  Cloudflare Workers example:
2633
2653
 
2634
2654
  ```typescript
2635
- import { wrapModule, trace, init } from 'autotel-cloudflare';
2655
+ import { wrapModule, trace, span, withTracing, init } from 'autotel-cloudflare';
2636
2656
 
2637
2657
  const processOrder = trace(async (orderId: string, kv: KVNamespace) => {
2638
2658
  return kv.get(orderId);
@@ -2799,7 +2819,7 @@ Autotel provides utilities that make it easy to instrument any library with Open
2799
2819
  Here's the minimal code to instrument any library:
2800
2820
 
2801
2821
  ```typescript
2802
- import { trace, SpanKind } from '@opentelemetry/api';
2822
+ import { trace, span, withTracing, SpanKind } from '@opentelemetry/api';
2803
2823
  import { runWithSpan, finalizeSpan } from 'autotel/trace-helpers';
2804
2824
 
2805
2825
  const INSTRUMENTED_FLAG = Symbol('instrumented');
@@ -2837,7 +2857,7 @@ export function instrumentMyLibrary(client) {
2837
2857
  Let's walk through instrumenting the popular axios HTTP client:
2838
2858
 
2839
2859
  ```typescript
2840
- import { trace, SpanKind } from '@opentelemetry/api';
2860
+ import { trace, span, withTracing, SpanKind } from '@opentelemetry/api';
2841
2861
  import { runWithSpan, finalizeSpan } from 'autotel/trace-helpers';
2842
2862
  import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
2843
2863
 
@@ -3087,7 +3107,7 @@ import {
3087
3107
  finalizeSpan, // Set status and end span with error handling
3088
3108
  getActiveSpan, // Get currently active span
3089
3109
  getTraceContext, // Get trace IDs for correlation
3090
- enrichWithTraceContext, // Add trace context to objects
3110
+ enrichWithTraceContext, // Add trace, withTracing context to objects
3091
3111
  getActiveContext, // Get current OpenTelemetry context
3092
3112
  } from 'autotel/trace-helpers';
3093
3113
 
@@ -3131,7 +3151,9 @@ logger.info(
3131
3151
 
3132
3152
  ```typescript
3133
3153
  import {
3134
- trace, // Access to tracer provider
3154
+ trace,
3155
+ span,
3156
+ withTracing, // Access to tracer provider
3135
3157
  context, // Context management (advanced)
3136
3158
  SpanKind, // CLIENT, SERVER, INTERNAL, PRODUCER, CONSUMER
3137
3159
  SpanStatusCode, // OK, ERROR, UNSET
@@ -3226,8 +3248,8 @@ init({
3226
3248
 
3227
3249
  ## See also
3228
3250
 
3229
- - [autotel-cloudflare](../autotel-cloudflare) — Cloudflare Workers with KV/R2/D1/DO instrumentation
3230
- - [autotel-edge](../autotel-edge) — vendor-agnostic edge runtime foundation
3231
- - [autotel-drizzle](../autotel-drizzle) — Drizzle ORM query spans
3251
+ - [autotel-cloudflare](../autotel-cloudflare): Cloudflare Workers with KV/R2/D1/DO instrumentation
3252
+ - [autotel-edge](../autotel-edge): vendor-agnostic edge runtime foundation
3253
+ - [autotel-drizzle](../autotel-drizzle): Drizzle ORM query spans
3232
3254
 
3233
3255
  Happy observing!
@@ -0,0 +1,87 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/analysis.ts
4
+ const DEFAULT_MAX_VALUES_PER_FIELD = 50;
5
+ const DEFAULT_MAX_UNIQUE_RATIO = .5;
6
+ const DEFAULT_MIN_DIFFERENCE = .1;
7
+ const DEFAULT_LIMIT = 20;
8
+ /**
9
+ * Render a value as a grouping key.
10
+ *
11
+ * Objects and arrays return undefined: a nested structure does not name a
12
+ * cohort, and stringifying it produces noise rather than a testable split.
13
+ */
14
+ function valueKey(value) {
15
+ if (value === null || value === void 0) return;
16
+ const kind = typeof value;
17
+ if (kind === "string" || kind === "number" || kind === "boolean" || kind === "bigint") return String(value);
18
+ }
19
+ /**
20
+ * Fold one group's events into the shared tally.
21
+ *
22
+ * Both groups accumulate into the same structure, so the caller never builds a
23
+ * combined array or revisits an event once per candidate field.
24
+ */
25
+ function accumulate(tally, events, group, includes) {
26
+ for (const event of events) for (const [field, raw] of Object.entries(event)) {
27
+ if (!includes(field)) continue;
28
+ const value = valueKey(raw);
29
+ if (value === void 0) continue;
30
+ let values = tally.get(field);
31
+ if (values === void 0) {
32
+ values = /* @__PURE__ */ new Map();
33
+ tally.set(field, values);
34
+ }
35
+ const counts = values.get(value) ?? {
36
+ outlier: 0,
37
+ baseline: 0
38
+ };
39
+ counts[group]++;
40
+ values.set(value, counts);
41
+ }
42
+ }
43
+ /**
44
+ * Rank the field/value pairs that separate an outlier group from a baseline.
45
+ *
46
+ * Returns an empty array when either group is empty, because a fraction over
47
+ * zero events carries no information.
48
+ *
49
+ * @param options - The two populations and the scan limits
50
+ * @returns Differences sorted by absolute strength, strongest first
51
+ */
52
+ function compareCohorts(options) {
53
+ const { outlier, baseline, fields, ignoreFields, maxValuesPerField = DEFAULT_MAX_VALUES_PER_FIELD, maxUniqueRatio = DEFAULT_MAX_UNIQUE_RATIO, minDifference = DEFAULT_MIN_DIFFERENCE, limit = DEFAULT_LIMIT } = options;
54
+ if (outlier.length === 0 || baseline.length === 0) return [];
55
+ const ignored = new Set(ignoreFields);
56
+ const selected = fields === void 0 ? void 0 : new Set(fields);
57
+ const includes = (field) => !ignored.has(field) && (selected === void 0 || selected.has(field));
58
+ const tally = /* @__PURE__ */ new Map();
59
+ accumulate(tally, outlier, "outlier", includes);
60
+ accumulate(tally, baseline, "baseline", includes);
61
+ const results = [];
62
+ const total = outlier.length + baseline.length;
63
+ for (const [field, values] of tally) {
64
+ if (values.size > maxValuesPerField || values.size > total * maxUniqueRatio) continue;
65
+ for (const [value, counts] of values) {
66
+ const outlierFraction = counts.outlier / outlier.length;
67
+ const baselineFraction = counts.baseline / baseline.length;
68
+ const difference = outlierFraction - baselineFraction;
69
+ if (Math.abs(difference) < minDifference) continue;
70
+ results.push({
71
+ field,
72
+ value,
73
+ outlierFraction,
74
+ baselineFraction,
75
+ difference,
76
+ outlierCount: counts.outlier,
77
+ baselineCount: counts.baseline
78
+ });
79
+ }
80
+ }
81
+ results.sort((a, b) => Math.abs(b.difference) - Math.abs(a.difference) || b.difference - a.difference || a.field.localeCompare(b.field) || a.value.localeCompare(b.value));
82
+ return results.slice(0, limit);
83
+ }
84
+
85
+ //#endregion
86
+ exports.compareCohorts = compareCohorts;
87
+ //# sourceMappingURL=analysis.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.cjs","names":[],"sources":["../src/analysis.ts"],"sourcesContent":["/**\n * Core Analysis Loop\n *\n * Debugging from first principles: take the events you care about, take a\n * comparable normal population, and ask which recorded field separates them.\n * The loop is mechanical, so run it in code instead of clicking through a\n * dashboard.\n *\n * `compareCohorts()` scores every field/value pair by how much more often it\n * appears in the outlier group than in the baseline. The top result names the\n * cohort behind a regression, which is the hypothesis you then verify against\n * individual traces.\n *\n * The input is any array of flat records: wide events from\n * `getRequestLogger()`, `TestSpan.attributes` from `autotel/testing`, or rows\n * returned by a backend query.\n *\n * @example Find the cohort behind a latency regression\n * ```typescript\n * import { compareCohorts } from 'autotel/analysis'\n *\n * const slow = events.filter((event) => event['duration_ms'] >= 800)\n * const normal = events.filter((event) => event['duration_ms'] < 800)\n *\n * const [top] = compareCohorts({ outlier: slow, baseline: normal })\n * // { field: 'payment.provider', value: 'bank-beta', difference: 0.94, ... }\n * ```\n */\n\n/** A flat telemetry record. Span attributes and wide events both satisfy it. */\nexport type AnalysisEvent = Record<string, unknown>;\n\n/** How strongly one field/value pair separates the outlier group from the baseline. */\nexport interface CohortDifference {\n /** Attribute name, such as `payment.provider`. */\n field: string;\n /** The value, rendered as a string for display and grouping. */\n value: string;\n /** Share of outlier events carrying this value, 0-1. */\n outlierFraction: number;\n /** Share of baseline events carrying this value, 0-1. */\n baselineFraction: number;\n /** `outlierFraction - baselineFraction`. Positive means over-represented in the outliers. */\n difference: number;\n outlierCount: number;\n baselineCount: number;\n}\n\nexport interface CompareCohortsOptions {\n /** The events you are investigating: the errors, the slow requests, the failed checkouts. */\n outlier: readonly AnalysisEvent[];\n /** A comparable normal population from the same time range. */\n baseline: readonly AnalysisEvent[];\n /** Restrict the scan to these fields. Defaults to every field seen in either group. */\n fields?: readonly string[];\n /** Fields to skip, such as identifiers you already know are unique. */\n ignoreFields?: readonly string[];\n /**\n * Skip a field once it holds more distinct values than this across both\n * groups. Default 50.\n */\n maxValuesPerField?: number;\n /**\n * Skip a field whose distinct values outnumber this share of the combined\n * events. A request id or a raw duration takes a near-unique value per\n * event, so its values never repeat and it cannot describe a cohort. The\n * ratio catches those fields in small populations, where an absolute cap\n * does not. Bucket numeric fields at instrumentation time if you want them\n * ranked. Default 0.5.\n */\n maxUniqueRatio?: number;\n /** Drop pairs whose absolute difference falls below this. Default 0.1. */\n minDifference?: number;\n /** Maximum results to return, strongest first. Default 20. */\n limit?: number;\n}\n\nconst DEFAULT_MAX_VALUES_PER_FIELD = 50;\nconst DEFAULT_MAX_UNIQUE_RATIO = 0.5;\nconst DEFAULT_MIN_DIFFERENCE = 0.1;\nconst DEFAULT_LIMIT = 20;\n\n/**\n * Render a value as a grouping key.\n *\n * Objects and arrays return undefined: a nested structure does not name a\n * cohort, and stringifying it produces noise rather than a testable split.\n */\nfunction valueKey(value: unknown): string | undefined {\n if (value === null || value === undefined) {\n return undefined;\n }\n const kind = typeof value;\n if (\n kind === 'string' ||\n kind === 'number' ||\n kind === 'boolean' ||\n kind === 'bigint'\n ) {\n return String(value);\n }\n return undefined;\n}\n\n/** Occurrences of one value, split by the group it appeared in. */\ninterface ValueCounts {\n outlier: number;\n baseline: number;\n}\n\n/** field -> value -> counts */\ntype FieldTally = Map<string, Map<string, ValueCounts>>;\n\n/**\n * Fold one group's events into the shared tally.\n *\n * Both groups accumulate into the same structure, so the caller never builds a\n * combined array or revisits an event once per candidate field.\n */\nfunction accumulate(\n tally: FieldTally,\n events: readonly AnalysisEvent[],\n group: keyof ValueCounts,\n includes: (field: string) => boolean,\n): void {\n for (const event of events) {\n for (const [field, raw] of Object.entries(event)) {\n if (!includes(field)) {\n continue;\n }\n const value = valueKey(raw);\n if (value === undefined) {\n continue;\n }\n let values = tally.get(field);\n if (values === undefined) {\n values = new Map<string, ValueCounts>();\n tally.set(field, values);\n }\n const counts = values.get(value) ?? { outlier: 0, baseline: 0 };\n counts[group]++;\n values.set(value, counts);\n }\n }\n}\n\n/**\n * Rank the field/value pairs that separate an outlier group from a baseline.\n *\n * Returns an empty array when either group is empty, because a fraction over\n * zero events carries no information.\n *\n * @param options - The two populations and the scan limits\n * @returns Differences sorted by absolute strength, strongest first\n */\nexport function compareCohorts(\n options: CompareCohortsOptions,\n): CohortDifference[] {\n const {\n outlier,\n baseline,\n fields,\n ignoreFields,\n maxValuesPerField = DEFAULT_MAX_VALUES_PER_FIELD,\n maxUniqueRatio = DEFAULT_MAX_UNIQUE_RATIO,\n minDifference = DEFAULT_MIN_DIFFERENCE,\n limit = DEFAULT_LIMIT,\n } = options;\n\n if (outlier.length === 0 || baseline.length === 0) {\n return [];\n }\n\n const ignored = new Set(ignoreFields);\n const selected = fields === undefined ? undefined : new Set(fields);\n const includes = (field: string) =>\n !ignored.has(field) && (selected === undefined || selected.has(field));\n\n const tally: FieldTally = new Map();\n accumulate(tally, outlier, 'outlier', includes);\n accumulate(tally, baseline, 'baseline', includes);\n\n const results: CohortDifference[] = [];\n const total = outlier.length + baseline.length;\n\n for (const [field, values] of tally) {\n if (\n values.size > maxValuesPerField ||\n values.size > total * maxUniqueRatio\n ) {\n continue;\n }\n\n for (const [value, counts] of values) {\n const outlierFraction = counts.outlier / outlier.length;\n const baselineFraction = counts.baseline / baseline.length;\n const difference = outlierFraction - baselineFraction;\n\n if (Math.abs(difference) < minDifference) {\n continue;\n }\n\n results.push({\n field,\n value,\n outlierFraction,\n baselineFraction,\n difference,\n outlierCount: counts.outlier,\n baselineCount: counts.baseline,\n });\n }\n }\n\n // Strongest first. On a tie prefer the over-represented value, because a\n // cohort you can open traces from beats one defined by its absence. Fall\n // back to field and value so repeated runs return the same order.\n results.sort(\n (a, b) =>\n Math.abs(b.difference) - Math.abs(a.difference) ||\n b.difference - a.difference ||\n a.field.localeCompare(b.field) ||\n a.value.localeCompare(b.value),\n );\n\n return results.slice(0, limit);\n}\n"],"mappings":";;;AA6EA,MAAM,+BAA+B;AACrC,MAAM,2BAA2B;AACjC,MAAM,yBAAyB;AAC/B,MAAM,gBAAgB;;;;;;;AAQtB,SAAS,SAAS,OAAoC;CACpD,IAAI,UAAU,QAAQ,UAAU,QAC9B;CAEF,MAAM,OAAO,OAAO;CACpB,IACE,SAAS,YACT,SAAS,YACT,SAAS,aACT,SAAS,UAET,OAAO,OAAO,KAAK;AAGvB;;;;;;;AAiBA,SAAS,WACP,OACA,QACA,OACA,UACM;CACN,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,CAAC,OAAO,QAAQ,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,CAAC,SAAS,KAAK,GACjB;EAEF,MAAM,QAAQ,SAAS,GAAG;EAC1B,IAAI,UAAU,QACZ;EAEF,IAAI,SAAS,MAAM,IAAI,KAAK;EAC5B,IAAI,WAAW,QAAW;GACxB,yBAAS,IAAI,IAAyB;GACtC,MAAM,IAAI,OAAO,MAAM;EACzB;EACA,MAAM,SAAS,OAAO,IAAI,KAAK,KAAK;GAAE,SAAS;GAAG,UAAU;EAAE;EAC9D,OAAO,MAAM;EACb,OAAO,IAAI,OAAO,MAAM;CAC1B;AAEJ;;;;;;;;;;AAWA,SAAgB,eACd,SACoB;CACpB,MAAM,EACJ,SACA,UACA,QACA,cACA,oBAAoB,8BACpB,iBAAiB,0BACjB,gBAAgB,wBAChB,QAAQ,kBACN;CAEJ,IAAI,QAAQ,WAAW,KAAK,SAAS,WAAW,GAC9C,OAAO,CAAC;CAGV,MAAM,UAAU,IAAI,IAAI,YAAY;CACpC,MAAM,WAAW,WAAW,SAAY,SAAY,IAAI,IAAI,MAAM;CAClE,MAAM,YAAY,UAChB,CAAC,QAAQ,IAAI,KAAK,MAAM,aAAa,UAAa,SAAS,IAAI,KAAK;CAEtE,MAAM,wBAAoB,IAAI,IAAI;CAClC,WAAW,OAAO,SAAS,WAAW,QAAQ;CAC9C,WAAW,OAAO,UAAU,YAAY,QAAQ;CAEhD,MAAM,UAA8B,CAAC;CACrC,MAAM,QAAQ,QAAQ,SAAS,SAAS;CAExC,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO;EACnC,IACE,OAAO,OAAO,qBACd,OAAO,OAAO,QAAQ,gBAEtB;EAGF,KAAK,MAAM,CAAC,OAAO,WAAW,QAAQ;GACpC,MAAM,kBAAkB,OAAO,UAAU,QAAQ;GACjD,MAAM,mBAAmB,OAAO,WAAW,SAAS;GACpD,MAAM,aAAa,kBAAkB;GAErC,IAAI,KAAK,IAAI,UAAU,IAAI,eACzB;GAGF,QAAQ,KAAK;IACX;IACA;IACA;IACA;IACA;IACA,cAAc,OAAO;IACrB,eAAe,OAAO;GACxB,CAAC;EACH;CACF;CAKA,QAAQ,MACL,GAAG,MACF,KAAK,IAAI,EAAE,UAAU,IAAI,KAAK,IAAI,EAAE,UAAU,KAC9C,EAAE,aAAa,EAAE,cACjB,EAAE,MAAM,cAAc,EAAE,KAAK,KAC7B,EAAE,MAAM,cAAc,EAAE,KAAK,CACjC;CAEA,OAAO,QAAQ,MAAM,GAAG,KAAK;AAC/B"}