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
@@ -12,7 +12,7 @@ license: MIT
12
12
 
13
13
  # Migrate to autotel
14
14
 
15
- Replacing tracing in a live service is risky — you can lose data, change span shapes, or break dashboards your on-call team relies on. This skill covers the safe paths from each major source, what to change in your code, and how to verify the cutover before turning the old stack off.
15
+ Replacing tracing in a live service is risky. You can lose data, change span shapes, or break dashboards your on-call team relies on. This skill covers the safe paths from each major source, what to change in your code, and how to verify the cutover before turning the old stack off.
16
16
 
17
17
  ## Choose your starting point
18
18
 
@@ -34,11 +34,11 @@ Replacing tracing in a live service is risky — you can lose data, change span
34
34
  4. **Disable the old stack.** Remove old SDK imports + processors; redeploy.
35
35
  5. **Decommission.** Remove old packages from `package.json` and lock files; archive old dashboards.
36
36
 
37
- Don't compress this into a single PR. The riskiest step is "disable old stack" — keep it last.
37
+ Don't compress this into a single PR. The riskiest step is "disable old stack". Keep it last.
38
38
 
39
39
  ## From raw `@opentelemetry/sdk-node`
40
40
 
41
- The smoothest migration. autotel layers on top of OTel — your span attributes, propagators, and exporters can stay.
41
+ The smoothest migration. autotel layers on top of OTel. Your span attributes, propagators, and exporters can stay.
42
42
 
43
43
  ### Drop-in init
44
44
 
@@ -76,15 +76,15 @@ init({
76
76
 
77
77
  ### What you gain immediately
78
78
 
79
- - `useLogger().set({ … })` flattens onto the active span — no more `span.setAttribute('user.id', id)` boilerplate.
80
- - `attributeRedactor: 'default'` — PII masking for free in production.
79
+ - `useLogger().set({ … })` flattens onto the active span: no more `span.setAttribute('user.id', id)` boilerplate.
80
+ - `attributeRedactor: 'default'`: PII masking for free in production.
81
81
  - `destinations: [...]` for straightforward OTLP multi-backend fan-out.
82
82
  - Cloudflare Workers + Edge support out of the box (`defineWorkerFetch`).
83
83
 
84
84
  ### What stays the same
85
85
 
86
86
  - Your propagator (`W3CTraceContextPropagator` is the default).
87
- - Your exporters — pass them via `spanProcessors` if you want to keep custom ones.
87
+ - Your exporters: pass them via `spanProcessors` if you want to keep custom ones.
88
88
  - Your resource attributes.
89
89
 
90
90
  ## From Sentry performance tracing
@@ -148,7 +148,7 @@ Datadog APM uses its own format and proprietary tracer. The migration path is OT
148
148
 
149
149
  ### Step 1: Stop importing `dd-trace`
150
150
 
151
- `dd-trace` patches every supported library on import — keeping it in the bundle while autotel runs causes double-instrumentation. Remove `import 'dd-trace'` (or the `--require dd-trace/init` arg).
151
+ `dd-trace` patches every supported library on import. Keeping it in the bundle while autotel runs causes double-instrumentation. Remove `import 'dd-trace'` (or the `--require dd-trace/init` arg).
152
152
 
153
153
  ### Step 2: Point autotel at Datadog OTLP intake
154
154
 
@@ -166,7 +166,7 @@ For the EU site use `datadoghq.eu`; for US3 / US5 see Datadog's region matrix.
166
166
 
167
167
  ### Step 3: Map Datadog span tags
168
168
 
169
- Datadog uses `service`, `resource`, `operation` — OTel uses `service.name`, `http.route`, span name. autotel handles the conversion automatically when exporting via `dd-api-key`. If you have custom Datadog tags in dashboards, rename them in code:
169
+ Datadog uses `service`, `resource`, `operation`. OTel uses `service.name`, `http.route`, span name. autotel handles the conversion automatically when exporting via `dd-api-key`. If you have custom Datadog tags in dashboards, rename them in code:
170
170
 
171
171
  | Datadog tag | OTel attribute |
172
172
  | ----------- | --------------------------- |
@@ -185,7 +185,7 @@ Datadog uses `service`, `resource`, `operation` — OTel uses `service.name`, `h
185
185
 
186
186
  ## From New Relic Node agent
187
187
 
188
- New Relic's agent is invasive — it patches Node internals. Plan a maintenance window for the cutover.
188
+ New Relic's agent is invasive. It patches Node internals. Plan a maintenance window for the cutover.
189
189
 
190
190
  ### Step 1: Remove `--require newrelic`
191
191
 
@@ -214,7 +214,7 @@ For EU: `https://otlp.eu01.nr-data.net/v1/traces`.
214
214
 
215
215
  ## From Honeycomb Beelines
216
216
 
217
- Beelines for Node was Honeycomb's pre-OTel SDK. Migration is straightforward — Honeycomb supports OTLP natively.
217
+ Beelines for Node was Honeycomb's pre-OTel SDK. Migration is straightforward. Honeycomb supports OTLP natively.
218
218
 
219
219
  ```typescript
220
220
  init({
@@ -234,7 +234,7 @@ init({
234
234
 
235
235
  Both are deprecated; the migration is "rewrite the tracer setup, leave call sites alone." OpenTracing's `Tracer.startSpan` and OpenCensus's `tracer.startRootSpan` shapes are similar enough that a script can replace them with `trace()` calls in most files.
236
236
 
237
- For libraries you don't control that still use OpenTracing, the OTel project ships a [shim](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing) — wire it once, then migrate at your own pace.
237
+ For libraries you don't control that still use OpenTracing, the OTel project ships a [shim](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing). Wire it once, then migrate at your own pace.
238
238
 
239
239
  ## From unstructured logging
240
240
 
@@ -249,21 +249,21 @@ See [`review-otel-patterns`](../review-otel-patterns/SKILL.md) for the framework
249
249
 
250
250
  ## Verifying the cutover
251
251
 
252
- | Check | How |
253
- | --------------------------- | --------------------------------------------------------------------------------------------- |
254
- | **Span volume matches** | Compare `count(spans)` per route over 24h; should be within ±5 % |
255
- | **p99 latency unchanged** | Histograms on both backends |
256
- | **Error rate unchanged** | `count(spans where status=error)` |
257
- | **Trace correlation works** | Pick 10 random `traceId`s; confirm cross-service spans resolve |
258
- | **Bundle size acceptable** | `pnpm bundle-size` — moving from heavy agents (New Relic, Datadog) often _shrinks_ the bundle |
252
+ | Check | How |
253
+ | --------------------------- | -------------------------------------------------------------------------------------------- |
254
+ | **Span volume matches** | Compare `count(spans)` per route over 24h; should be within ±5 % |
255
+ | **p99 latency unchanged** | Histograms on both backends |
256
+ | **Error rate unchanged** | `count(spans where status=error)` |
257
+ | **Trace correlation works** | Pick 10 random `traceId`s; confirm cross-service spans resolve |
258
+ | **Bundle size acceptable** | `pnpm bundle-size`: moving from heavy agents (New Relic, Datadog) often _shrinks_ the bundle |
259
259
 
260
260
  ## Anti-patterns
261
261
 
262
262
  | Anti-pattern | Fix |
263
263
  | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
264
- | Both old SDK and autotel running on the same library | Pick one — double-instrumentation duplicates spans |
264
+ | Both old SDK and autotel running on the same library | Pick one: double-instrumentation duplicates spans |
265
265
  | Removing the old SDK in the same PR as adding autotel | Run both side-by-side for 24–48 h first |
266
266
  | Changing span names during migration | Preserve names; rename in a separate PR after dashboards re-pointed |
267
267
  | No metric snapshot before cutover | Take p50/p95/p99 + error-rate baselines first |
268
- | Migrating prod before staging | Always staging first — at least 24 h |
268
+ | Migrating prod before staging | Always staging first: at least 24 h |
269
269
  | Trusting the old vendor agent's auto-instrumentation list | autotel's targeted instrumentations (`autotel-drizzle`, `autotel-mongoose`, …) are faster and tighter; expect to add a couple |
@@ -17,7 +17,7 @@ license: MIT
17
17
 
18
18
  # Review OpenTelemetry patterns
19
19
 
20
- Review and improve OpenTelemetry instrumentation in TypeScript/JavaScript codebases using autotel. Replace ad-hoc tracing with idiomatic OTel-native spans, metrics and structured logs that work across every major framework and edge runtime — without vendor lock-in.
20
+ Review and improve OpenTelemetry instrumentation in TypeScript/JavaScript codebases using autotel. Replace ad-hoc tracing with idiomatic OTel-native spans, metrics and structured logs that work across every major framework and edge runtime. Without vendor lock-in.
21
21
 
22
22
  ## When to use
23
23
 
@@ -64,7 +64,7 @@ npm install autotel-sentry # Sentry exporter via OTLP
64
64
 
65
65
  ### Next.js (App Router)
66
66
 
67
- Step 1 — Initialise once in `instrumentation.ts`:
67
+ Step 1: Initialise once in `instrumentation.ts`:
68
68
 
69
69
  ```typescript
70
70
  // instrumentation.ts
@@ -82,7 +82,7 @@ export function register() {
82
82
  }
83
83
  ```
84
84
 
85
- Step 2 — Wrap route handlers:
85
+ Step 2: Wrap route handlers:
86
86
 
87
87
  ```typescript
88
88
  // app/api/checkout/route.ts
@@ -96,9 +96,9 @@ export const POST = withAutotel(async (request: Request) => {
96
96
  });
97
97
  ```
98
98
 
99
- Step 3 — Tag Server Actions the same way (`withAutotel`).
99
+ Step 3: Tag Server Actions the same way (`withAutotel`).
100
100
 
101
- Step 4 — Browser → server trace propagation: drop in `<TraceProvider />` from `autotel-web` so the W3C `traceparent` header is forwarded automatically.
101
+ Step 4: Browser to server trace propagation: drop in `<TraceProvider />` from `autotel-web` so the W3C `traceparent` header is forwarded automatically.
102
102
 
103
103
  ### Nuxt + Nitro v3
104
104
 
@@ -149,14 +149,13 @@ export const Route = createRootRoute({
149
149
 
150
150
  ```typescript
151
151
  import { Hono } from 'hono';
152
- import { honoToolkit } from 'autotel-adapters';
152
+ import { autotelMiddleware, useLogger } from 'autotel-adapters/hono';
153
153
 
154
- const { useLogger, withAutotel } = honoToolkit;
155
154
  const app = new Hono();
156
- app.use('*', withAutotel({ service: 'my-api' }));
155
+ app.use('*', autotelMiddleware());
157
156
 
158
157
  app.get('/api/users', (c) => {
159
- const log = useLogger(c);
158
+ const log = useLogger();
160
159
  log.set({ users: { count: 42 } });
161
160
  return c.json({ users: [] });
162
161
  });
@@ -168,7 +167,7 @@ The `autotel-adapters` toolkit ships a uniform shape for these: `withAutotel` mi
168
167
 
169
168
  ### Cloudflare Workers (with auto `waitUntil`)
170
169
 
171
- `defineWorkerFetch` instruments the handler **and** wires `ctx.waitUntil` for span exports — without it, async exports silently drop:
170
+ `defineWorkerFetch` instruments the handler **and** wires `ctx.waitUntil` for span exports. Without it, async exports silently drop:
172
171
 
173
172
  ```typescript
174
173
  import { defineWorkerFetch } from 'autotel-cloudflare';
@@ -182,7 +181,7 @@ export default defineWorkerFetch(
182
181
  );
183
182
  ```
184
183
 
185
- For broader use cases (`scheduled`, `queue`, `email` handlers, Durable Objects, Workflows), use `wrapModule` / `wrapDurableObject` / `instrumentWorkflow` — same auto-`waitUntil` semantics.
184
+ For broader use cases (`scheduled`, `queue`, `email` handlers, Durable Objects, Workflows), use `wrapModule` / `wrapDurableObject` / `instrumentWorkflow`. Same auto-`waitUntil` semantics.
186
185
 
187
186
  ### AWS Lambda
188
187
 
@@ -245,16 +244,19 @@ Enrichers turn raw request data into standard, low-cardinality span attributes.
245
244
  | `requestSize(reqHeaders, resHeaders?)` | `http.request.body.size`, `http.response.body.size` | `content-length` headers |
246
245
 
247
246
  ```typescript
247
+ import { withTracing } from 'autotel';
248
248
  import { userAgent, geo, requestSize } from 'autotel/enrichers';
249
249
 
250
- export const handler = trace((ctx) => async (request: Request) => {
251
- ctx.setAttributes({
252
- ...userAgent(request.headers),
253
- ...geo(request.headers),
254
- ...requestSize(request.headers),
255
- });
256
- // ... handle request
257
- });
250
+ export const handler = withTracing({ name: 'http.request' })(
251
+ (ctx) => async (request: Request) => {
252
+ ctx.setAttributes({
253
+ ...userAgent(request.headers),
254
+ ...geo(request.headers),
255
+ ...requestSize(request.headers),
256
+ });
257
+ // ... handle request
258
+ },
259
+ );
258
260
  ```
259
261
 
260
262
  For your own derived fields on a request's wide event, build a reusable enricher with `defineEnricher` (from `autotel`) instead of scattering ad-hoc field writes. `compute` returns an object that is merged into the named `field`; return `undefined` to skip. Keep the output low-cardinality (bucket or hash high-cardinality values):
@@ -279,7 +281,7 @@ const enrichTier = defineEnricher<
279
281
 
280
282
  ## Backends (multi-vendor OTLP)
281
283
 
282
- Switch backends with **no code changes** — autotel speaks OTLP HTTP/JSON and HTTP/protobuf out of the box.
284
+ Switch backends with **no code changes**. Autotel speaks OTLP HTTP/JSON and HTTP/protobuf out of the box.
283
285
 
284
286
  | Backend | Endpoint | Headers |
285
287
  | -------------------------------- | ---------------------------------------------------------- | ------------------------------------- |
@@ -334,7 +336,7 @@ const config: AttributeRedactorConfig = {
334
336
  init({ attributeRedactor: config });
335
337
  ```
336
338
 
337
- For free-text fields outside the span pipeline (logs, error messages, frontend payloads), use `createStringRedactor('default')` — same masks, returns a `(s: string) => string`.
339
+ For free-text fields outside the span pipeline (logs, error messages, frontend payloads), use `createStringRedactor('default')`. Same masks, returns a `(s: string) => string`.
338
340
 
339
341
  ---
340
342
 
@@ -365,7 +367,7 @@ export const otelConfig = defineConfig({
365
367
  });
366
368
  ```
367
369
 
368
- Errors are isolated per item — one bad processor cannot break the others. See [references/processor-pipeline.md](references/processor-pipeline.md) for the full pipeline cookbook.
370
+ Errors are isolated per item. One bad processor cannot break the others. See [references/processor-pipeline.md](references/processor-pipeline.md) for the full pipeline cookbook.
369
371
 
370
372
  ---
371
373
 
@@ -380,15 +382,15 @@ Errors are isolated per item — one bad processor cannot break the others. See
380
382
  | `BaggageSpanProcessor` | Lift baggage entries onto every span |
381
383
  | `PrettyConsoleExporter` | Hierarchical colourised output for local dev |
382
384
 
383
- Compose them at build time with `composeSpanProcessors([...])` — no boilerplate.
385
+ Compose them at build time with `composeSpanProcessors([...])`. No boilerplate.
384
386
 
385
387
  ---
386
388
 
387
389
  ## AI SDK integration (gen-ai semantic conventions)
388
390
 
389
- autotel implements the **OTel gen-ai semantic conventions** out of the box. Token usage, tool calls, model info, latency, cost — captured as standard attributes (`gen_ai.usage.input_tokens`, `gen_ai.tool.name`, `gen_ai.response.finish_reasons`, …) so any backend that understands OTel can render LLM telemetry without custom mapping.
391
+ autotel implements the **OTel gen-ai semantic conventions** out of the box. Token usage, tool calls, model info, latency, cost. Captured as standard attributes (`gen_ai.usage.input_tokens`, `gen_ai.tool.name`, `gen_ai.response.finish_reasons`, …) so any backend that understands OTel can render LLM telemetry without custom mapping.
390
392
 
391
- > Node.js apps get the same canonical `gen_ai.*` conventions (plus cost, metric views, and agent governance) from the `autotel-genai` package — `traceGenAI` / `recordGenAiUsage` from `autotel-genai/trace` and `genAiMetricViews` from `autotel-genai/metrics`. `withAiTelemetry` below is the edge-runtime entry point.
393
+ > Node.js apps get the same canonical `gen_ai.*` conventions (plus cost, metric views, and agent governance) from the `autotel-genai` package. `traceGenAI` / `recordGenAiUsage` from `autotel-genai/trace` and `genAiMetricViews` from `autotel-genai/metrics`. `withAiTelemetry` below is the edge-runtime entry point.
392
394
 
393
395
  ```typescript
394
396
  import { trace } from 'autotel';
@@ -423,7 +425,7 @@ Anti-patterns to detect:
423
425
 
424
426
  ## Structured errors
425
427
 
426
- Throw rich errors that carry status, audience, and remediation hints — and consume them at HTTP boundaries:
428
+ Throw rich errors that carry status, audience, and remediation hints. And consume them at HTTP boundaries:
427
429
 
428
430
  ```typescript
429
431
  import { createStructuredError, parseError } from 'autotel';
@@ -492,21 +494,21 @@ pnpm --filter autotel run test:e2e
492
494
 
493
495
  ## Anti-patterns to detect
494
496
 
495
- | Anti-pattern | Fix |
496
- | --------------------------------------------------- | ------------------------------------------------------------------- |
497
- | `console.log` in handlers | Use `useLogger()` — fields land on the active span |
498
- | Manual `tracer.startSpan` boilerplate | `trace(fn)` — auto-named, auto-ended, auto-status |
499
- | `try { … } catch (e) { console.error(e); throw e }` | Replace with `createStructuredError({ … })` |
500
- | `throw new Error('something went wrong')` | `createStructuredError({ message, status, why, fix })` |
501
- | Ad-hoc `span.setAttribute('user_id', id)` | Use `useLogger().set({ user: { id } })` — flattens with stable keys |
502
- | Multiple exporters wired in parallel by hand | `composeSpanProcessors([…])` |
503
- | PII in attributes | `attributeRedactor: 'default'` (on in prod by default) |
504
- | Cloudflare Workers without `waitUntil` | Use `defineWorkerFetch` / `wrapModule` |
505
- | High-cardinality span names (`/users/123`) | `SpanNameNormalizingProcessor` |
506
- | AI SDK token logs | `withAiTelemetry()` + gen-ai semantic conventions |
507
- | Health checks blowing up trace volume | `FilteringSpanProcessor` |
508
- | No tests for instrumentation | `InMemorySpanExporter` + `autotel-vitest` matchers |
509
- | Manual context propagation in fetch | `instrumentation.instrumentGlobalFetch: true` (default) |
497
+ | Anti-pattern | Fix |
498
+ | --------------------------------------------------- | ------------------------------------------------------------------ |
499
+ | `console.log` in handlers | Use `useLogger()`: fields land on the active span |
500
+ | Manual `tracer.startSpan` boilerplate | `trace(fn)`: auto-named, auto-ended, auto-status |
501
+ | `try { … } catch (e) { console.error(e); throw e }` | Replace with `createStructuredError({ … })` |
502
+ | `throw new Error('something went wrong')` | `createStructuredError({ message, status, why, fix })` |
503
+ | Ad-hoc `span.setAttribute('user_id', id)` | Use `useLogger().set({ user: { id } })`: flattens with stable keys |
504
+ | Multiple exporters wired in parallel by hand | `composeSpanProcessors([…])` |
505
+ | PII in attributes | `attributeRedactor: 'default'` (on in prod by default) |
506
+ | Cloudflare Workers without `waitUntil` | Use `defineWorkerFetch` / `wrapModule` |
507
+ | High-cardinality span names (`/users/123`) | `SpanNameNormalizingProcessor` |
508
+ | AI SDK token logs | `withAiTelemetry()` + gen-ai semantic conventions |
509
+ | Health checks blowing up trace volume | `FilteringSpanProcessor` |
510
+ | No tests for instrumentation | `InMemorySpanExporter` + `autotel-vitest` matchers |
511
+ | Manual context propagation in fetch | `instrumentation.instrumentGlobalFetch: true` (default) |
510
512
 
511
513
  See [references/code-review.md](references/code-review.md) for the full checklist.
512
514
 
@@ -530,7 +532,7 @@ See [references/code-review.md](references/code-review.md) for the full checklis
530
532
 
531
533
  ## Loading reference files
532
534
 
533
- Load based on what you're working on — **do not load all at once**:
535
+ Load based on what you're working on. **do not load all at once**:
534
536
 
535
537
  - Designing spans → [references/wide-spans.md](references/wide-spans.md)
536
538
  - Improving errors → [references/structured-errors.md](references/structured-errors.md)
@@ -7,7 +7,7 @@ Run through this list when adding observability to a new service or auditing an
7
7
  - [ ] **Service name set.** `service.name` resource attribute is unique per deployable unit (not just `"app"`).
8
8
  - [ ] **OTLP endpoint configured** via `OTLP_ENDPOINT` env var. Don't hard-code per-vendor URLs.
9
9
  - [ ] **No global SDK init in handlers.** Init runs once at module load (Next.js `instrumentation.ts`, Workers top of module, Node `--require`).
10
- - [ ] **Production redaction on.** `attributeRedactor: 'default'` (or `'strict'` / `'pci-dss'`) — autotel turns it on automatically when `NODE_ENV === 'production'`.
10
+ - [ ] **Production redaction on.** `attributeRedactor: 'default'` (or `'strict'` / `'pci-dss'`): autotel turns it on automatically when `NODE_ENV === 'production'`.
11
11
  - [ ] **Sampling configured.** Don't ship 100% in production unless volume is genuinely tiny. `sampling.rates: { server: 25 }` is a reasonable starting point.
12
12
 
13
13
  ## Spans
@@ -31,8 +31,8 @@ Run through this list when adding observability to a new service or auditing an
31
31
  - [ ] **`useLogger().set({ … })` instead of `console.log`.** Logger fields land on the active span automatically.
32
32
  - [ ] **No PII in attributes** (or rely on redactor). Don't log raw email / cards / phones / JWTs.
33
33
  - [ ] **Group fields with objects.** `{ user: { id, plan } }`, not flat `userId` / `userPlan`.
34
- - [ ] **Decisions captured.** Which branch, which fallback, which feature flag — not just inputs.
35
- - [ ] **Background work uses `log.fork()`** — gets its own span and `_parentCorrelationId` for correlation.
34
+ - [ ] **Decisions captured.** Which branch, which fallback, which feature flag: not just inputs.
35
+ - [ ] **Background work uses `log.fork()`**: gets its own span and `_parentCorrelationId` for correlation.
36
36
 
37
37
  ## Errors
38
38
 
@@ -44,7 +44,7 @@ Run through this list when adding observability to a new service or auditing an
44
44
  ## Metrics
45
45
 
46
46
  - [ ] **Use OTel meter API**, not service-specific clients.
47
- - [ ] **Counters for events, histograms for durations, gauges for snapshots** — match the right type.
47
+ - [ ] **Counters for events, histograms for durations, gauges for snapshots**: match the right type.
48
48
  - [ ] **Bounded label cardinality.** Don't put `userId` on a metric label.
49
49
 
50
50
  ## AI / LLM
@@ -89,7 +89,7 @@ const normalise = new SpanNameNormalizingProcessor({
89
89
  });
90
90
  ```
91
91
 
92
- Now `GET /users/123e4567-e89b-12d3-a456-426614174000/orders` becomes `GET /users/:id/orders` in your traces — fewer unique span names, dramatically faster queries.
92
+ Now `GET /users/123e4567-e89b-12d3-a456-426614174000/orders` becomes `GET /users/:id/orders` in your traces. Fewer unique span names, dramatically faster queries.
93
93
 
94
94
  ## Lift baggage onto every span
95
95
 
@@ -103,7 +103,7 @@ spanProcessors: composeSpanProcessors([baggage, new BatchSpanProcessor(otlp)]);
103
103
 
104
104
  ## Subscribers for in-process side effects
105
105
 
106
- Subscribers run synchronously in the parent context — ideal for metrics, audit, and cost calculation that you want recorded **before** the span goes to the batcher.
106
+ Subscribers run synchronously in the parent context. Ideal for metrics, audit, and cost calculation that you want recorded **before** the span goes to the batcher.
107
107
 
108
108
  ```typescript
109
109
  import type { EdgeSubscriber } from 'autotel-edge';
@@ -192,7 +192,7 @@ export const otelConfig = defineConfig({
192
192
 
193
193
  ## Error isolation
194
194
 
195
- Every compose helper catches errors per item and logs to `console.error` with the helper name. A single bad processor cannot break the others — important when one of your subscribers is a third-party integration (Datadog, PagerDuty, …) that can rate-limit or 502.
195
+ Every compose helper catches errors per item and logs to `console.error` with the helper name. A single bad processor cannot break the others. Important when one of your subscribers is a third-party integration (Datadog, PagerDuty, …) that can rate-limit or 502.
196
196
 
197
197
  ## Choosing between subscribers and post-processors
198
198
 
@@ -98,5 +98,5 @@ app.onError((error, c) => {
98
98
  | `throw new Error('something went wrong')` | `createStructuredError({ message, status, why, fix })` |
99
99
  | Putting support IDs in `message` (`"Failed for user 42"`) | Use `internal: { userId: 42 }` |
100
100
  | Returning `details: { error: stack }` to clients | Stack traces stay in `cause` / span; never serialise them out |
101
- | `console.error(e); throw e` | Just throw — autotel's span will pick up the exception |
101
+ | `console.error(e); throw e` | Just throw: autotel's span will pick up the exception |
102
102
  | Two callers throwing different shapes for the same condition | Centralise: `function declined(reason: string) { throw createStructuredError({ … }) }` |
@@ -1,6 +1,6 @@
1
1
  # Designing wide spans
2
2
 
3
- A wide span is a single span per logical unit of work (request, job, message, fork) carrying _all_ the fields you'd ever want to filter or group by. autotel lets you build them with `useLogger().set({ … })` — fields are flattened to OTel attributes with stable dotted keys.
3
+ A wide span is a single span per logical unit of work (request, job, message, fork) carrying _all_ the fields you'd ever want to filter or group by. autotel lets you build them with `useLogger().set({ … })`. Fields are flattened to OTel attributes with stable dotted keys.
4
4
 
5
5
  ## Anatomy
6
6
 
@@ -50,7 +50,7 @@ payment.authCode=auth_x
50
50
  2. **Group with objects.** `{ user: { id, plan } }` not `userId` / `userPlan`. The flatten step keeps the key shape stable.
51
51
  3. **Capture decisions, not just inputs.** Which branch ran, which promo applied, which fallback fired.
52
52
  4. **Keep cardinality bounded.** Don't put per-request UUIDs in `span.name`; use `SpanNameNormalizingProcessor`. Free-text labels go in attributes.
53
- 5. **Avoid raw bodies.** Pick the shape: `{ user: { id, plan } }` — never `log.set({ user: requestBody })`.
53
+ 5. **Avoid raw bodies.** Pick the shape: `{ user: { id, plan } }`: never `log.set({ user: requestBody })`.
54
54
  6. **Trust the redactor.** PII you forgot to think about (emails, JWTs, cards) gets masked in production. See `attributeRedactor: 'default'`.
55
55
 
56
56
  ## When you need correlated child spans
@@ -30,14 +30,14 @@ Total cost = (spans/sec × $/span) + (storage_GB × $/GB-month)
30
30
  Head sampling reduces this directly.
31
31
  ```
32
32
 
33
- Head sampling makes a decision **at span start** — fast, but coarse (it doesn't know if the span will fail).
34
- Tail sampling makes the decision **at span end** — slower, more storage upfront, but precise.
33
+ Head sampling makes a decision **at span start**: fast but coarse, since it cannot know whether the span will fail.
34
+ Tail sampling makes the decision **at span end**: slower and heavier on storage, but precise.
35
35
 
36
36
  The right mix:
37
37
 
38
38
  - **Head sample at the entry point** to keep volume tractable.
39
39
  - **Tail keep** the high-value subset (errors, slow, AI, debug-headered).
40
- - **Don't sample audit spans** — separate processor, see [`build-audit-trails`](../build-audit-trails/SKILL.md).
40
+ - **Don't sample audit spans**: separate processor, see [`build-audit-trails`](../build-audit-trails/SKILL.md).
41
41
 
42
42
  ## Head sampling recipes
43
43
 
@@ -73,7 +73,7 @@ sampling: {
73
73
 
74
74
  ### Cloudflare Workers (per-colo budget)
75
75
 
76
- Workers run distributed — head sampling is your friend because there's no central queue:
76
+ Workers run distributed. Head sampling is your friend because there's no central queue:
77
77
 
78
78
  ```typescript
79
79
  defineWorkerFetch(
@@ -85,7 +85,7 @@ defineWorkerFetch(
85
85
  );
86
86
  ```
87
87
 
88
- ## Tail sampling — keep interesting traces
88
+ ## Tail sampling: keep interesting traces
89
89
 
90
90
  Tail sampling looks at the full trace (root span + children) before deciding. autotel ships `TailSamplingProcessor`:
91
91
 
@@ -138,9 +138,9 @@ spanProcessors: composeSpanProcessors([
138
138
 
139
139
  LLM calls produce 5–50 spans per request and are 100× more expensive than a typical handler call. Tradeoffs:
140
140
 
141
- - **Don't head-sample AI handlers below 50 %** — debugging "why did the model loop" requires the full chain.
142
- - **Always tail-keep AI traces** — the `gen_ai.*` attributes flag them.
143
- - **Cost-aware sampling** — keep all calls above a $ threshold:
141
+ - **Don't head-sample AI handlers below 50 %**: debugging "why did the model loop" requires the full chain.
142
+ - **Always tail-keep AI traces**: the `gen_ai.*` attributes flag them.
143
+ - **Cost-aware sampling**: keep all calls above a $ threshold:
144
144
 
145
145
  ```typescript
146
146
  keep: (trace) => {
@@ -176,7 +176,79 @@ if (request.headers.get('x-debug-trace') === '1') {
176
176
  }
177
177
  ```
178
178
 
179
- Now any user can mark a request as "trace this fully" by sending the header — invaluable for reproducing customer reports.
179
+ Now any user can mark a request as "trace this fully" by sending the header. Invaluable for reproducing customer reports.
180
+
181
+ ## Keeping the trace whole across services
182
+
183
+ `RandomSampler` rolls the dice in each process. The API can keep a trace its
184
+ worker drops, which leaves a waterfall with holes and no way to tell a dropped
185
+ span from a fast one. `DeterministicSampler` hashes a key that travels with the
186
+ request, so every service reaches the same verdict:
187
+
188
+ ```typescript
189
+ import { DeterministicSampler } from 'autotel/sampling';
190
+ import { trace } from '@opentelemetry/api';
191
+
192
+ init({
193
+ service: 'checkout',
194
+ sampler: new DeterministicSampler({
195
+ sampleRate: 0.1,
196
+ key: () => trace.getActiveSpan()?.spanContext().traceId,
197
+ }),
198
+ });
199
+ ```
200
+
201
+ Give every service the same rate and the same key. Different rates break the
202
+ agreement again.
203
+
204
+ ## Per-key target rates
205
+
206
+ A single rate cannot fit skewed traffic. At 1 % your busiest endpoint still
207
+ floods storage while the rare tenant whose failures you need disappears.
208
+ `KeyTargetRateSampler` counts traffic per key over a rolling window and gives
209
+ each key its own rate, so every key contributes about the same number of
210
+ events:
211
+
212
+ ```typescript
213
+ import { KeyTargetRateSampler } from 'autotel/sampling';
214
+
215
+ new KeyTargetRateSampler({
216
+ key: (context) => context.operationName,
217
+ targetPerKey: 10, // ~10 events per key per window
218
+ windowMs: 30_000,
219
+ maxKeys: 1000, // keys past this share one overflow bucket
220
+ });
221
+ ```
222
+
223
+ The first window keeps everything, because no traffic history exists yet. Rates
224
+ apply from the second window on.
225
+
226
+ ## Recording the rate
227
+
228
+ Sampled counts lie unless you record what you discarded. A query over a 1 %
229
+ sample reports a hundredth of your traffic, and the number looks plausible
230
+ enough to act on.
231
+
232
+ autotel writes `autotel.sampling.rate` on the span as "1 in N", so
233
+ `COUNT * rate` estimates the population. It appears only when N exceeds 1, so
234
+ fully captured spans stay clean. A custom sampler joins in by implementing
235
+ `sampleRate()`:
236
+
237
+ ```typescript
238
+ import type { Sampler } from 'autotel/sampling';
239
+
240
+ class TenantSampler implements Sampler {
241
+ shouldSample(context) {
242
+ /* … */
243
+ }
244
+ sampleRate() {
245
+ return 20; // each kept event stands for 20
246
+ }
247
+ }
248
+ ```
249
+
250
+ Reach for `hashUnitInterval` from `autotel/sampling` when you need the same
251
+ spread for your own keys.
180
252
 
181
253
  ## Sizing the rate
182
254
 
@@ -188,11 +260,11 @@ spans/sec ≈ requests/sec × spans_per_request × head_rate × tail_keep_rate
188
260
 
189
261
  Worked example for a 100 req/s API with 8 spans/req:
190
262
 
191
- | Head rate | Tail keep | Result |
192
- | --------- | -------------------------------- | -------------------------------------------- |
193
- | 100 % | 100 % | 800 spans/sec — expensive |
194
- | 10 % | 100 % (errors + slow + AI ≈ 5 %) | ≈ 110 spans/sec — sweet spot |
195
- | 1 % | 100 % | ≈ 18 spans/sec — too sparse for p99 alerting |
263
+ | Head rate | Tail keep | Result |
264
+ | --------- | -------------------------------- | ------------------------------------------- |
265
+ | 100 % | 100 % | 800 spans/sec: expensive |
266
+ | 10 % | 100 % (errors + slow + AI ≈ 5 %) | ≈ 110 spans/sec: sweet spot |
267
+ | 1 % | 100 % | ≈ 18 spans/sec: too sparse for p99 alerting |
196
268
 
197
269
  For per-vendor pricing:
198
270
 
@@ -208,8 +280,11 @@ For per-vendor pricing:
208
280
  | 1 % sampling with no tail keep | You'll miss every interesting failure |
209
281
  | Forgetting to tail-keep errors | Sampled traces with errors → silent customer pain |
210
282
  | Same rate for `server` and `internal` | Internal sub-spans are 5–20× more numerous; sample harder |
211
- | Ratio-based sampling on service entry point | Use parent-based — children of a sampled trace stay together |
283
+ | Ratio-based sampling on service entry point | Use parent-based: children of a sampled trace stay together |
212
284
  | Head-sampling AI calls below 50 % | Debugging tool loops requires the full chain |
213
285
  | Audit spans subject to sampling | Route them to a separate processor (see `build-audit-trails`) |
214
286
  | Tail processor before exporter (loses spans) | Tail processor goes between head sampler and remote exporter |
215
- | Rate-by-route hand-coded in handlers | Use head sampler + tail keep — declarative, one place |
287
+ | Rate-by-route hand-coded in handlers | Use head sampler + tail keep: declarative, one place |
288
+ | Counting sampled spans as the population | Multiply by `autotel.sampling.rate` |
289
+ | `RandomSampler` on a multi-service trace | `DeterministicSampler` keyed on the trace id keeps it whole |
290
+ | One flat rate over skewed traffic | `KeyTargetRateSampler` gives rare keys their own rate |
@@ -1 +0,0 @@
1
- {"version":3,"file":"attribute-redacting-processor-DtTS9xxh.d.cts","names":[],"sources":["../src/attribute-redacting-processor.ts"],"mappings":";;;;;;;KAsCY,mBAAA,IACV,GAAA,UACA,KAAA,EAAO,cAAA,KACJ,cAAc;;AAuBJ;AAMf;KAxBY,uBAAA;;;AAwBiD;KAnBjD,MAAA,IAAU,KAAa;;;;UAKlB,kBAAA;EA8BM;EA5BrB,IAAA;EAqCW;EAnCX,OAAA,EAAS,MAAA;EAmCqB;EAjC9B,WAAA;EAec;EAbd,IAAA,GAAO,MAAM;AAAA;;;;KAMH,kBAAA,gBAAkC,eAAe;;;;UAK5C,uBAAA;EAoBe;EAlB9B,WAAA,GAAc,MAAA;EAwBC;EArBf,aAAA,GAAgB,kBAAA;;EAGhB,KAAA;EAmBA;EAhBA,QAAA,aAAqB,kBAAA;EAgBe;EAbpC,QAAA,GAAW,MAAA;EAagD;EAV3D,WAAA;EA6BQ;EA1BR,QAAA,GAAW,mBAAA;AAAA;;;;UAMI,kCAAA;EACf,QAAA,EAAU,uBAAA,GAA0B,uBAAuB;AAAA;;;;cAMhD,iBAAA;EAAA;;;;;;;;;;;;;cAmBA,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoHA,gBAAA,EAAkB,MAAA,CAC7B,uBAAA,EACA,uBAAA;AAvDkB;AAqDpB;;;AArDoB,iBAsGJ,gCAAA,CACd,GAAA,EAAK,uBAAA,GAA0B,uBAAA,aAC9B,uBAAA,GAA0B,uBAAA;;;;;;;iBA4NpB,kBAAA,CACP,IAAA,EAAM,YAAA,EACN,QAAA,EAAU,mBAAA,GACT,YAAA;;AAhRsB;AA+CzB;;;;;;;;;;;iBAwQgB,uBAAA,CACd,MAAA,EAAQ,uBAAA,GAA0B,uBAAA,GACjC,mBAAA;;;;AAxQiD;AAsDnD;;;;;;;;cAkOY,2BAAA,YAAuC,aAAA;EAAA,iBACjC,gBAAA;EAAA,iBACA,QAAA;cAGf,gBAAA,EAAkB,aAAA,EAClB,OAAA,EAAS,kCAAA;EA/DV;;AAAY;EAyEb,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAM,aAAA,EAAe,OAAA;EAlCE;;;EAyCrC,KAAA,CAAM,IAAA,EAAM,YAAA;EAWZ,UAAA,IAAc,OAAA;EAId,QAAA,IAAY,OAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"attribute-redacting-processor-DtTS9xxh.d.ts","names":[],"sources":["../src/attribute-redacting-processor.ts"],"mappings":";;;;;;;KAsCY,mBAAA,IACV,GAAA,UACA,KAAA,EAAO,cAAA,KACJ,cAAc;;AAuBJ;AAMf;KAxBY,uBAAA;;;AAwBiD;KAnBjD,MAAA,IAAU,KAAa;;;;UAKlB,kBAAA;EA8BM;EA5BrB,IAAA;EAqCW;EAnCX,OAAA,EAAS,MAAA;EAmCqB;EAjC9B,WAAA;EAec;EAbd,IAAA,GAAO,MAAM;AAAA;;;;KAMH,kBAAA,gBAAkC,eAAe;;;;UAK5C,uBAAA;EAoBe;EAlB9B,WAAA,GAAc,MAAA;EAwBC;EArBf,aAAA,GAAgB,kBAAA;;EAGhB,KAAA;EAmBA;EAhBA,QAAA,aAAqB,kBAAA;EAgBe;EAbpC,QAAA,GAAW,MAAA;EAagD;EAV3D,WAAA;EA6BQ;EA1BR,QAAA,GAAW,mBAAA;AAAA;;;;UAMI,kCAAA;EACf,QAAA,EAAU,uBAAA,GAA0B,uBAAuB;AAAA;;;;cAMhD,iBAAA;EAAA;;;;;;;;;;;;;cAmBA,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoHA,gBAAA,EAAkB,MAAA,CAC7B,uBAAA,EACA,uBAAA;AAvDkB;AAqDpB;;;AArDoB,iBAsGJ,gCAAA,CACd,GAAA,EAAK,uBAAA,GAA0B,uBAAA,aAC9B,uBAAA,GAA0B,uBAAA;;;;;;;iBA4NpB,kBAAA,CACP,IAAA,EAAM,YAAA,EACN,QAAA,EAAU,mBAAA,GACT,YAAA;;AAhRsB;AA+CzB;;;;;;;;;;;iBAwQgB,uBAAA,CACd,MAAA,EAAQ,uBAAA,GAA0B,uBAAA,GACjC,mBAAA;;;;AAxQiD;AAsDnD;;;;;;;;cAkOY,2BAAA,YAAuC,aAAA;EAAA,iBACjC,gBAAA;EAAA,iBACA,QAAA;cAGf,gBAAA,EAAkB,aAAA,EAClB,OAAA,EAAS,kCAAA;EA/DV;;AAAY;EAyEb,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAM,aAAA,EAAe,OAAA;EAlCE;;;EAyCrC,KAAA,CAAM,IAAA,EAAM,YAAA;EAWZ,UAAA,IAAc,OAAA;EAId,QAAA,IAAY,OAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"canonical-log-line-processor-BcRuAdRk.d.ts","names":[],"sources":["../src/processors/canonical-log-line-processor.ts"],"mappings":";;;;;AA6Ce;AAGf;;AAHe,KATH,mBAAA,IACV,GAAA,UACA,KAAA,EAAO,cAAA,KACJ,cAAc;AAAA,UAEF,qBAAA;EACf,IAAA,EAAM,YAAA;EACN,KAAA;EACA,OAAA;EACA,KAAA,EAAO,MAAM;AAAA;AAAA,UAGE,aAAA;EASuB;EAPtC,MAAA;EASS;EAPT,UAAA;EAqBoB;EAnBpB,IAAA;AAAA;AAAA,UAGe,uBAAA;EA4BgC;EA1B/C,MAAA,GAAS,MAAA;EA4BiD;EA1B1D,aAAA;EAFA;EAIA,QAAA;EAFA;EAIA,aAAA,IAAiB,IAAA,EAAM,YAAA;EAAvB;EAEA,yBAAA;EAFiB;;;;;EAQjB,iBAAA,GAAoB,mBAAA;EAEN;EAAd,UAAA,IAAc,GAAA,EAAK,qBAAA;EAQZ;;;;;;;EAAP,IAAA,GAAO,aAAA;EAIyB;EAFhC,KAAA,IAAS,GAAA,EAAK,qBAAA,YAAiC,OAAA;EAOzC;EALN,YAAA,IAAgB,KAAA,WAAgB,GAAA,EAAK,qBAAA;EAiE1B;;;;EA5DX,MAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4SyB;;;;;;;;;;;;;;;;;;;;cAhPd,yBAAA,YAAqC,aAAA;EAAA,QACxC,MAAA;EAAA,QACA,aAAA;EAAA,QACA,QAAA;EAAA,QACA,aAAA;EAAA,QACA,yBAAA;EAAA,QACA,iBAAA;EAAA,QACA,UAAA;EAAA,QACA,KAAA;EAAA,QACA,YAAA;EAAA,QACA,MAAA;EAAA,QACA,aAAA;cAGI,OAAA,GAAS,uBAAA;EAAA,QAsBb,kBAAA;EA8BR,OAAA;EAIA,KAAA,CAAM,IAAA,EAAM,YAAA;EAAA,QA+CJ,qBAAA;EAAA,QA+BA,gBAAA;EAAA,QAcA,aAAA;EAAA,QAQA,WAAA;EAAA,QA0BA,WAAA;EAAA,QAeA,SAAA;EAAA,QAKA,iBAAA;EAAA,QAUA,qBAAA;EAUF,UAAA,IAAc,OAAA;EAId,QAAA,IAAY,OAAA;AAAA"}