autotel 4.2.5 → 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.
- package/README.md +125 -103
- package/dist/analysis.cjs +87 -0
- package/dist/analysis.cjs.map +1 -0
- package/dist/analysis.d.cts +87 -0
- package/dist/analysis.d.cts.map +1 -0
- package/dist/analysis.d.ts +87 -0
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +85 -0
- package/dist/analysis.js.map +1 -0
- package/dist/{attribute-redacting-processor-DtTS9xxh.d.ts → attribute-redacting-processor-Pk7lAzWd.d.cts} +13 -8
- package/dist/attribute-redacting-processor-Pk7lAzWd.d.cts.map +1 -0
- package/dist/{attribute-redacting-processor-DtTS9xxh.d.cts → attribute-redacting-processor-Pk7lAzWd.d.ts} +13 -8
- package/dist/attribute-redacting-processor-Pk7lAzWd.d.ts.map +1 -0
- package/dist/attribute-redacting-processor.cjs +4 -4
- package/dist/attribute-redacting-processor.cjs.map +1 -1
- package/dist/attribute-redacting-processor.d.cts +1 -1
- package/dist/attribute-redacting-processor.d.ts +1 -1
- package/dist/attribute-redacting-processor.js +4 -4
- package/dist/attribute-redacting-processor.js.map +1 -1
- package/dist/attributes.d.cts +1 -1
- package/dist/attributes.d.ts +1 -1
- package/dist/auto.cjs +1 -1
- package/dist/auto.cjs.map +1 -1
- package/dist/auto.d.cts +1 -1
- package/dist/auto.d.ts +1 -1
- package/dist/auto.js +1 -1
- package/dist/auto.js.map +1 -1
- package/dist/business-baggage.d.cts +2 -3
- package/dist/business-baggage.d.cts.map +1 -1
- package/dist/business-baggage.d.ts +2 -3
- package/dist/business-baggage.d.ts.map +1 -1
- package/dist/{canonical-log-line-processor-xvjMgtpF.d.cts → canonical-log-line-processor-B4WgG-VS.d.cts} +2 -3
- package/dist/canonical-log-line-processor-B4WgG-VS.d.cts.map +1 -0
- package/dist/{canonical-log-line-processor-BcRuAdRk.d.ts → canonical-log-line-processor-CL_J7gb5.d.ts} +2 -3
- package/dist/canonical-log-line-processor-CL_J7gb5.d.ts.map +1 -0
- package/dist/{canonical-log-line-processor-CcrDi6TO.cjs → canonical-log-line-processor-DOjb6Kxy.cjs} +5 -5
- package/dist/canonical-log-line-processor-DOjb6Kxy.cjs.map +1 -0
- package/dist/{canonical-log-line-processor-FLezvFCB.js → canonical-log-line-processor-mKABvGP0.js} +5 -5
- package/dist/canonical-log-line-processor-mKABvGP0.js.map +1 -0
- package/dist/config.d.cts +12 -7
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.ts +12 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/correlation-id.cjs +1 -1
- package/dist/correlation-id.d.cts +0 -1
- package/dist/correlation-id.d.cts.map +1 -1
- package/dist/correlation-id.d.ts +0 -1
- package/dist/correlation-id.d.ts.map +1 -1
- package/dist/correlation-id.js +1 -1
- package/dist/db.d.cts.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/decorators.cjs +1 -1
- package/dist/decorators.cjs.map +1 -1
- package/dist/decorators.d.cts +1 -2
- package/dist/decorators.d.cts.map +1 -1
- package/dist/decorators.d.ts +1 -2
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +1 -1
- package/dist/decorators.js.map +1 -1
- package/dist/{define-event-CreknLm3.d.ts → define-event-B2z1SBe7.d.ts} +2 -3
- package/dist/define-event-B2z1SBe7.d.ts.map +1 -0
- package/dist/{define-event-HZRizPwz.d.cts → define-event-CGG048HE.d.cts} +2 -3
- package/dist/define-event-CGG048HE.d.cts.map +1 -0
- package/dist/diagnostics.cjs +10 -1
- package/dist/diagnostics.cjs.map +1 -1
- package/dist/diagnostics.d.cts +0 -1
- package/dist/diagnostics.d.cts.map +1 -1
- package/dist/diagnostics.d.ts +0 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +10 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/drain-pipeline.d.cts +12 -5
- package/dist/drain-pipeline.d.cts.map +1 -1
- package/dist/drain-pipeline.d.ts +12 -5
- package/dist/drain-pipeline.d.ts.map +1 -1
- package/dist/enrichers.d.cts.map +1 -1
- package/dist/enrichers.d.ts.map +1 -1
- package/dist/{event-rzA1X5h3.cjs → event-CwIpFdoY.cjs} +3 -3
- package/dist/event-CwIpFdoY.cjs.map +1 -0
- package/dist/{event-BEm5IJ8U.js → event-pLMF5b3d.js} +4 -4
- package/dist/event-pLMF5b3d.js.map +1 -0
- package/dist/{event-subscriber-D1XLkPzi.d.ts → event-subscriber-CWh8sTGh.d.cts} +2 -2
- package/dist/event-subscriber-CWh8sTGh.d.cts.map +1 -0
- package/dist/{event-subscriber-D1XLkPzi.d.cts → event-subscriber-CWh8sTGh.d.ts} +2 -2
- package/dist/event-subscriber-CWh8sTGh.d.ts.map +1 -0
- package/dist/event-subscriber.d.cts +1 -1
- package/dist/event-subscriber.d.ts +1 -1
- package/dist/{event-testing-CfFs3to2.d.ts → event-testing-CA2mIx1E.d.ts} +2 -3
- package/dist/event-testing-CA2mIx1E.d.ts.map +1 -0
- package/dist/{event-testing-BqRnI0z4.d.cts → event-testing-D0qWfqAy.d.cts} +2 -3
- package/dist/event-testing-D0qWfqAy.d.cts.map +1 -0
- package/dist/event-testing.d.cts +1 -1
- package/dist/event-testing.d.ts +1 -1
- package/dist/event.cjs +1 -1
- package/dist/event.d.cts +3 -4
- package/dist/event.d.cts.map +1 -1
- package/dist/event.d.ts +3 -4
- package/dist/event.d.ts.map +1 -1
- package/dist/event.js +1 -1
- package/dist/exporters.d.cts +0 -4
- package/dist/exporters.d.cts.map +1 -1
- package/dist/exporters.d.ts +0 -4
- package/dist/exporters.d.ts.map +1 -1
- package/dist/{filtering-span-processor-B8R8B7Uk.d.ts → filtering-span-processor-BpDagWNa.d.cts} +1 -2
- package/dist/filtering-span-processor-BpDagWNa.d.cts.map +1 -0
- package/dist/{filtering-span-processor-B8R8B7Uk.d.cts → filtering-span-processor-BpDagWNa.d.ts} +1 -2
- package/dist/filtering-span-processor-BpDagWNa.d.ts.map +1 -0
- package/dist/filtering-span-processor.d.cts +1 -1
- package/dist/filtering-span-processor.d.ts +1 -1
- package/dist/functional-Bit6noRu.js +840 -0
- package/dist/functional-Bit6noRu.js.map +1 -0
- package/dist/functional-Cj7PSItS.cjs +890 -0
- package/dist/functional-Cj7PSItS.cjs.map +1 -0
- package/dist/functional.cjs +2 -2
- package/dist/functional.d.cts +79 -130
- package/dist/functional.d.cts.map +1 -1
- package/dist/functional.d.ts +79 -130
- package/dist/functional.d.ts.map +1 -1
- package/dist/functional.js +2 -2
- package/dist/http.cjs +5 -5
- package/dist/http.cjs.map +1 -1
- package/dist/http.d.cts +4 -5
- package/dist/http.d.cts.map +1 -1
- package/dist/http.d.ts +4 -5
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +5 -5
- package/dist/http.js.map +1 -1
- package/dist/{index-eKuioqT1.d.cts → index-BPcxVucm.d.cts} +2 -3
- package/dist/index-BPcxVucm.d.cts.map +1 -0
- package/dist/{index-Ck06vlW2.d.ts → index-DolOVX6F.d.ts} +2 -3
- package/dist/index-DolOVX6F.d.ts.map +1 -0
- package/dist/index.cjs +10 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -14
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -16
- package/dist/index.js.map +1 -1
- package/dist/{init-BxJEJ9Tn.cjs → init-B2uvZReD.cjs} +19 -10
- package/dist/init-B2uvZReD.cjs.map +1 -0
- package/dist/{init-B7u-DjxM.d.ts → init-CTyqG9qR.d.ts} +24 -17
- package/dist/init-CTyqG9qR.d.ts.map +1 -0
- package/dist/{init-BvBB45-T.js → init-CdEWjhvl.js} +20 -11
- package/dist/init-CdEWjhvl.js.map +1 -0
- package/dist/{init-DSrRmVnz.d.cts → init-a4yPDYqC.d.cts} +24 -17
- package/dist/init-a4yPDYqC.d.cts.map +1 -0
- package/dist/instrumentation.cjs +7 -13
- package/dist/instrumentation.cjs.map +1 -1
- package/dist/instrumentation.d.cts +0 -1
- package/dist/instrumentation.d.cts.map +1 -1
- package/dist/instrumentation.d.ts +0 -1
- package/dist/instrumentation.d.ts.map +1 -1
- package/dist/instrumentation.js +8 -14
- package/dist/instrumentation.js.map +1 -1
- package/dist/{logger-BauSUhUv.d.ts → logger-CN4xpzMd.d.cts} +1 -2
- package/dist/logger-CN4xpzMd.d.cts.map +1 -0
- package/dist/{logger-BauSUhUv.d.cts → logger-CN4xpzMd.d.ts} +1 -2
- package/dist/logger-CN4xpzMd.d.ts.map +1 -0
- package/dist/logger-D3Ej3DII.js.map +1 -1
- package/dist/logger-thMPLpOG.cjs.map +1 -1
- package/dist/logger.d.cts +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/messaging-adapters.cjs.map +1 -1
- package/dist/messaging-adapters.d.cts +0 -1
- package/dist/messaging-adapters.d.cts.map +1 -1
- package/dist/messaging-adapters.d.ts +0 -1
- package/dist/messaging-adapters.d.ts.map +1 -1
- package/dist/messaging-adapters.js.map +1 -1
- package/dist/messaging-testing.d.cts +0 -1
- package/dist/messaging-testing.d.cts.map +1 -1
- package/dist/messaging-testing.d.ts +0 -1
- package/dist/messaging-testing.d.ts.map +1 -1
- package/dist/messaging.cjs +27 -10
- package/dist/messaging.cjs.map +1 -1
- package/dist/messaging.d.cts +6 -7
- package/dist/messaging.d.cts.map +1 -1
- package/dist/messaging.d.ts +6 -7
- package/dist/messaging.d.ts.map +1 -1
- package/dist/messaging.js +27 -10
- package/dist/messaging.js.map +1 -1
- package/dist/metric-helpers.d.cts +0 -1
- package/dist/metric-helpers.d.cts.map +1 -1
- package/dist/metric-helpers.d.ts +0 -1
- package/dist/metric-helpers.d.ts.map +1 -1
- package/dist/{metric-testing-DXdK3-Q3.d.ts → metric-testing-CWm6UhaR.d.ts} +2 -3
- package/dist/metric-testing-CWm6UhaR.d.ts.map +1 -0
- package/dist/{metric-testing-MxvzChDp.d.cts → metric-testing-CpvP3ZIa.d.cts} +2 -3
- package/dist/metric-testing-CpvP3ZIa.d.cts.map +1 -0
- package/dist/metric-testing.d.cts +1 -1
- package/dist/metric-testing.d.ts +1 -1
- package/dist/metric.d.cts +3 -4
- package/dist/metric.d.cts.map +1 -1
- package/dist/metric.d.ts +3 -4
- package/dist/metric.d.ts.map +1 -1
- package/dist/parse-error.d.cts.map +1 -1
- package/dist/parse-error.d.ts.map +1 -1
- package/dist/processors.cjs +1 -1
- package/dist/processors.d.cts +1 -1
- package/dist/processors.d.ts +1 -1
- package/dist/processors.js +1 -1
- package/dist/register.d.cts +1 -1
- package/dist/register.d.ts +1 -1
- package/dist/{sampling-DfYhDJij.d.cts → sampling-BR9fkSwx.d.cts} +127 -10
- package/dist/sampling-BR9fkSwx.d.cts.map +1 -0
- package/dist/{sampling-CR0Va1VB.d.ts → sampling-CP3e7-Yr.d.ts} +127 -10
- package/dist/sampling-CP3e7-Yr.d.ts.map +1 -0
- package/dist/sampling.cjs +160 -12
- package/dist/sampling.cjs.map +1 -1
- package/dist/sampling.d.cts +2 -2
- package/dist/sampling.d.ts +2 -2
- package/dist/sampling.js +157 -13
- package/dist/sampling.js.map +1 -1
- package/dist/security-schema.d.cts +9 -4
- package/dist/security-schema.d.cts.map +1 -1
- package/dist/security-schema.d.ts +9 -4
- package/dist/security-schema.d.ts.map +1 -1
- package/dist/semantic-conventions-FhSxv-bK.d.cts.map +1 -1
- package/dist/semantic-conventions-FhSxv-bK.d.ts.map +1 -1
- package/dist/semantic-conventions.cjs.map +1 -1
- package/dist/semantic-conventions.js.map +1 -1
- package/dist/semantic-helpers.cjs +85 -304
- package/dist/semantic-helpers.cjs.map +1 -1
- package/dist/semantic-helpers.d.cts +21 -12
- package/dist/semantic-helpers.d.cts.map +1 -1
- package/dist/semantic-helpers.d.ts +21 -12
- package/dist/semantic-helpers.d.ts.map +1 -1
- package/dist/semantic-helpers.js +85 -304
- package/dist/semantic-helpers.js.map +1 -1
- package/dist/slo.cjs +225 -0
- package/dist/slo.cjs.map +1 -0
- package/dist/slo.d.cts +97 -0
- package/dist/slo.d.cts.map +1 -0
- package/dist/slo.d.ts +97 -0
- package/dist/slo.d.ts.map +1 -0
- package/dist/slo.js +223 -0
- package/dist/slo.js.map +1 -0
- package/dist/{span-name-normalizer-8ZOGJuwv.d.ts → span-name-normalizer-CN1-8C76.d.cts} +1 -2
- package/dist/span-name-normalizer-CN1-8C76.d.cts.map +1 -0
- package/dist/{span-name-normalizer-8ZOGJuwv.d.cts → span-name-normalizer-CN1-8C76.d.ts} +1 -2
- package/dist/span-name-normalizer-CN1-8C76.d.ts.map +1 -0
- package/dist/span-name-normalizer.cjs.map +1 -1
- package/dist/span-name-normalizer.d.cts +1 -1
- package/dist/span-name-normalizer.d.ts +1 -1
- package/dist/span-name-normalizer.js.map +1 -1
- package/dist/tail-sampling-processor.d.cts +0 -1
- package/dist/tail-sampling-processor.d.cts.map +1 -1
- package/dist/tail-sampling-processor.d.ts +0 -1
- package/dist/tail-sampling-processor.d.ts.map +1 -1
- package/dist/test-span-collector.cjs +13 -1
- package/dist/test-span-collector.cjs.map +1 -1
- package/dist/test-span-collector.d.cts +8 -1
- package/dist/test-span-collector.d.cts.map +1 -1
- package/dist/test-span-collector.d.ts +8 -1
- package/dist/test-span-collector.d.ts.map +1 -1
- package/dist/test-span-collector.js +13 -1
- package/dist/test-span-collector.js.map +1 -1
- package/dist/testing.cjs +76 -11
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +30 -5
- package/dist/testing.d.cts.map +1 -1
- package/dist/testing.d.ts +30 -5
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +73 -12
- package/dist/testing.js.map +1 -1
- package/dist/{trace-context-Cijqoi6e.d.ts → trace-context-IuyoPyNq.d.cts} +9 -9
- package/dist/trace-context-IuyoPyNq.d.cts.map +1 -0
- package/dist/{trace-context-Cijqoi6e.d.cts → trace-context-IuyoPyNq.d.ts} +9 -9
- package/dist/trace-context-IuyoPyNq.d.ts.map +1 -0
- package/dist/trace-factory-validation-BjVAinz6.js +13 -0
- package/dist/trace-factory-validation-BjVAinz6.js.map +1 -0
- package/dist/trace-factory-validation-Dc8epn87.cjs +19 -0
- package/dist/trace-factory-validation-Dc8epn87.cjs.map +1 -0
- package/dist/trace-helpers.cjs +7 -7
- package/dist/trace-helpers.cjs.map +1 -1
- package/dist/trace-helpers.d.cts +6 -7
- package/dist/trace-helpers.d.cts.map +1 -1
- package/dist/trace-helpers.d.ts +6 -7
- package/dist/trace-helpers.d.ts.map +1 -1
- package/dist/trace-helpers.js +7 -7
- package/dist/trace-helpers.js.map +1 -1
- package/dist/tracer-provider.cjs +27 -0
- package/dist/tracer-provider.cjs.map +1 -1
- package/dist/tracer-provider.d.cts +19 -2
- package/dist/tracer-provider.d.cts.map +1 -1
- package/dist/tracer-provider.d.ts +19 -2
- package/dist/tracer-provider.d.ts.map +1 -1
- package/dist/tracer-provider.js +27 -1
- package/dist/tracer-provider.js.map +1 -1
- package/dist/{track-D7O7oIZa.js → track-BBcxEJEC.js} +7 -12
- package/dist/track-BBcxEJEC.js.map +1 -0
- package/dist/{track-eovhCJ-I.cjs → track-BI6dmZ2X.cjs} +6 -17
- package/dist/track-BI6dmZ2X.cjs.map +1 -0
- package/dist/validate.cjs.map +1 -1
- package/dist/validate.d.cts +1 -2
- package/dist/validate.d.cts.map +1 -1
- package/dist/validate.d.ts +1 -2
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js.map +1 -1
- package/dist/validation-attributes.d.cts +17 -8
- package/dist/validation-attributes.d.cts.map +1 -1
- package/dist/validation-attributes.d.ts +17 -8
- package/dist/validation-attributes.d.ts.map +1 -1
- package/dist/webhook.cjs +5 -4
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +4 -4
- package/dist/webhook.d.cts.map +1 -1
- package/dist/webhook.d.ts +4 -4
- package/dist/webhook.d.ts.map +1 -1
- package/dist/webhook.js +5 -4
- package/dist/webhook.js.map +1 -1
- package/dist/workflow-distributed.cjs +5 -5
- package/dist/workflow-distributed.cjs.map +1 -1
- package/dist/workflow-distributed.d.cts +25 -15
- package/dist/workflow-distributed.d.cts.map +1 -1
- package/dist/workflow-distributed.d.ts +25 -15
- package/dist/workflow-distributed.d.ts.map +1 -1
- package/dist/workflow-distributed.js +5 -5
- package/dist/workflow-distributed.js.map +1 -1
- package/dist/workflow.cjs +24 -30
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +11 -6
- package/dist/workflow.d.cts.map +1 -1
- package/dist/workflow.d.ts +11 -6
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +24 -30
- package/dist/workflow.js.map +1 -1
- package/dist/yaml-config.d.cts +2 -3
- package/dist/yaml-config.d.cts.map +1 -1
- package/dist/yaml-config.d.ts +2 -3
- package/dist/yaml-config.d.ts.map +1 -1
- package/package.json +23 -14
- package/skills/analyze-traces/SKILL.md +42 -13
- package/skills/autotel-core/SKILL.md +24 -17
- package/skills/autotel-events/SKILL.md +1 -1
- package/skills/autotel-frameworks/SKILL.md +41 -6
- package/skills/autotel-instrumentation/SKILL.md +14 -9
- package/skills/autotel-request-logging/SKILL.md +19 -14
- package/skills/autotel-structured-errors/SKILL.md +2 -2
- package/skills/build-audit-trails/SKILL.md +11 -11
- package/skills/build-audit-trails/references/audit-queries.md +3 -3
- package/skills/debug-missing-spans/SKILL.md +12 -12
- package/skills/migrate-to-autotel/SKILL.md +20 -20
- package/skills/review-otel-patterns/SKILL.md +44 -42
- package/skills/review-otel-patterns/references/code-review.md +4 -4
- package/skills/review-otel-patterns/references/processor-pipeline.md +3 -3
- package/skills/review-otel-patterns/references/structured-errors.md +1 -1
- package/skills/review-otel-patterns/references/wide-spans.md +2 -2
- package/skills/tune-sampling/SKILL.md +91 -16
- package/dist/attribute-redacting-processor-DtTS9xxh.d.cts.map +0 -1
- package/dist/attribute-redacting-processor-DtTS9xxh.d.ts.map +0 -1
- package/dist/canonical-log-line-processor-BcRuAdRk.d.ts.map +0 -1
- package/dist/canonical-log-line-processor-CcrDi6TO.cjs.map +0 -1
- package/dist/canonical-log-line-processor-FLezvFCB.js.map +0 -1
- package/dist/canonical-log-line-processor-xvjMgtpF.d.cts.map +0 -1
- package/dist/define-event-CreknLm3.d.ts.map +0 -1
- package/dist/define-event-HZRizPwz.d.cts.map +0 -1
- package/dist/event-BEm5IJ8U.js.map +0 -1
- package/dist/event-rzA1X5h3.cjs.map +0 -1
- package/dist/event-subscriber-D1XLkPzi.d.cts.map +0 -1
- package/dist/event-subscriber-D1XLkPzi.d.ts.map +0 -1
- package/dist/event-testing-BqRnI0z4.d.cts.map +0 -1
- package/dist/event-testing-CfFs3to2.d.ts.map +0 -1
- package/dist/filtering-span-processor-B8R8B7Uk.d.cts.map +0 -1
- package/dist/filtering-span-processor-B8R8B7Uk.d.ts.map +0 -1
- package/dist/functional-BCtxvYir.cjs +0 -1315
- package/dist/functional-BCtxvYir.cjs.map +0 -1
- package/dist/functional-CrAq8Az8.js +0 -1265
- package/dist/functional-CrAq8Az8.js.map +0 -1
- package/dist/index-Ck06vlW2.d.ts.map +0 -1
- package/dist/index-eKuioqT1.d.cts.map +0 -1
- package/dist/init-B7u-DjxM.d.ts.map +0 -1
- package/dist/init-BvBB45-T.js.map +0 -1
- package/dist/init-BxJEJ9Tn.cjs.map +0 -1
- package/dist/init-DSrRmVnz.d.cts.map +0 -1
- package/dist/logger-BauSUhUv.d.cts.map +0 -1
- package/dist/logger-BauSUhUv.d.ts.map +0 -1
- package/dist/metric-testing-DXdK3-Q3.d.ts.map +0 -1
- package/dist/metric-testing-MxvzChDp.d.cts.map +0 -1
- package/dist/sampling-CR0Va1VB.d.ts.map +0 -1
- package/dist/sampling-DfYhDJij.d.cts.map +0 -1
- package/dist/span-name-normalizer-8ZOGJuwv.d.cts.map +0 -1
- package/dist/span-name-normalizer-8ZOGJuwv.d.ts.map +0 -1
- package/dist/trace-context-Cijqoi6e.d.cts.map +0 -1
- package/dist/trace-context-Cijqoi6e.d.ts.map +0 -1
- package/dist/track-D7O7oIZa.js.map +0 -1
- package/dist/track-eovhCJ-I.cjs.map +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { n as TraceContext } from "./trace-context-
|
|
1
|
+
import { n as TraceContext } from "./trace-context-IuyoPyNq.js";
|
|
2
2
|
import { Attributes } from "@opentelemetry/api";
|
|
3
|
-
|
|
4
3
|
//#region src/semantic-helpers.d.ts
|
|
4
|
+
type SemanticHandler<TArgs extends unknown[], TReturn> = (...args: TArgs) => TReturn | Promise<TReturn>;
|
|
5
|
+
type SemanticFactory<TArgs extends unknown[], TReturn> = (ctx: TraceContext) => SemanticHandler<TArgs, TReturn>;
|
|
5
6
|
/**
|
|
6
7
|
* Configuration for database operations
|
|
7
8
|
*
|
|
@@ -17,6 +18,8 @@ interface DBConfig {
|
|
|
17
18
|
database?: string;
|
|
18
19
|
/** Collection/table name */
|
|
19
20
|
collection?: string;
|
|
21
|
+
/** Low-cardinality query summary used as the preferred span name */
|
|
22
|
+
querySummary?: string;
|
|
20
23
|
/** Additional attributes to add to the span */
|
|
21
24
|
attributes?: Attributes;
|
|
22
25
|
}
|
|
@@ -31,6 +34,10 @@ interface HTTPConfig {
|
|
|
31
34
|
method?: string;
|
|
32
35
|
/** Target URL or URL template */
|
|
33
36
|
url?: string;
|
|
37
|
+
/** Low-cardinality server route used in the span name */
|
|
38
|
+
route?: string;
|
|
39
|
+
/** Low-cardinality client URL template used in the span name */
|
|
40
|
+
urlTemplate?: string;
|
|
34
41
|
/** Additional attributes to add to the span */
|
|
35
42
|
attributes?: Attributes;
|
|
36
43
|
}
|
|
@@ -54,9 +61,9 @@ interface MessagingConfig {
|
|
|
54
61
|
* Trace database operations with DB semantic conventions
|
|
55
62
|
*
|
|
56
63
|
* Automatically adds standard attributes for database operations:
|
|
57
|
-
* - db.system
|
|
58
|
-
* - db.operation
|
|
59
|
-
* - db.
|
|
64
|
+
* - db.system.name
|
|
65
|
+
* - db.operation.name
|
|
66
|
+
* - db.namespace
|
|
60
67
|
* - db.collection.name (for NoSQL)
|
|
61
68
|
*
|
|
62
69
|
* **Use Cases:**
|
|
@@ -76,11 +83,10 @@ interface MessagingConfig {
|
|
|
76
83
|
* system: 'postgresql',
|
|
77
84
|
* operation: 'SELECT',
|
|
78
85
|
* database: 'app_db',
|
|
79
|
-
* collection: 'users'
|
|
86
|
+
* collection: 'users',
|
|
87
|
+
* querySummary: 'SELECT users'
|
|
80
88
|
* })(ctx => async (userId: string) => {
|
|
81
89
|
* const query = 'SELECT * FROM users WHERE id = $1'
|
|
82
|
-
* ctx.setAttribute('db.statement', query)
|
|
83
|
-
*
|
|
84
90
|
* const result = await pool.query(query, [userId])
|
|
85
91
|
* ctx.setAttribute('db.rows_affected', result.rowCount)
|
|
86
92
|
*
|
|
@@ -149,7 +155,8 @@ interface MessagingConfig {
|
|
|
149
155
|
*
|
|
150
156
|
* @public
|
|
151
157
|
*/
|
|
152
|
-
declare function traceDB<TArgs extends unknown[], TReturn>(
|
|
158
|
+
declare function traceDB(config: DBConfig): <TArgs extends unknown[], TReturn>(factory: SemanticFactory<TArgs, TReturn>) => SemanticHandler<TArgs, TReturn>;
|
|
159
|
+
declare function traceDB<TArgs extends unknown[], TReturn>(config: DBConfig, fn: SemanticHandler<TArgs, TReturn>): SemanticHandler<TArgs, TReturn>;
|
|
153
160
|
/**
|
|
154
161
|
* Trace HTTP client operations with HTTP semantic conventions
|
|
155
162
|
*
|
|
@@ -171,7 +178,7 @@ declare function traceDB<TArgs extends unknown[], TReturn>(config: DBConfig): (f
|
|
|
171
178
|
*
|
|
172
179
|
* export const fetchUser = traceHTTP({
|
|
173
180
|
* method: 'GET',
|
|
174
|
-
*
|
|
181
|
+
* urlTemplate: '/users/{id}'
|
|
175
182
|
* })(ctx => async (userId: string) => {
|
|
176
183
|
* const url = `https://api.example.com/users/${userId}`
|
|
177
184
|
* ctx.setAttribute('url.full', url)
|
|
@@ -218,7 +225,8 @@ declare function traceDB<TArgs extends unknown[], TReturn>(config: DBConfig): (f
|
|
|
218
225
|
*
|
|
219
226
|
* @public
|
|
220
227
|
*/
|
|
221
|
-
declare function traceHTTP<TArgs extends unknown[], TReturn>(
|
|
228
|
+
declare function traceHTTP(config: HTTPConfig): <TArgs extends unknown[], TReturn>(factory: SemanticFactory<TArgs, TReturn>) => SemanticHandler<TArgs, TReturn>;
|
|
229
|
+
declare function traceHTTP<TArgs extends unknown[], TReturn>(config: HTTPConfig, fn: SemanticHandler<TArgs, TReturn>): SemanticHandler<TArgs, TReturn>;
|
|
222
230
|
/**
|
|
223
231
|
* Trace messaging operations with Messaging semantic conventions
|
|
224
232
|
*
|
|
@@ -316,7 +324,8 @@ declare function traceHTTP<TArgs extends unknown[], TReturn>(config: HTTPConfig)
|
|
|
316
324
|
*
|
|
317
325
|
* @public
|
|
318
326
|
*/
|
|
319
|
-
declare function traceMessaging<TArgs extends unknown[], TReturn>(
|
|
327
|
+
declare function traceMessaging(config: MessagingConfig): <TArgs extends unknown[], TReturn>(factory: SemanticFactory<TArgs, TReturn>) => SemanticHandler<TArgs, TReturn>;
|
|
328
|
+
declare function traceMessaging<TArgs extends unknown[], TReturn>(config: MessagingConfig, fn: SemanticHandler<TArgs, TReturn>): SemanticHandler<TArgs, TReturn>;
|
|
320
329
|
//#endregion
|
|
321
330
|
export { DBConfig, HTTPConfig, MessagingConfig, traceDB, traceHTTP, traceMessaging };
|
|
322
331
|
//# sourceMappingURL=semantic-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-helpers.d.ts","names":[],"sources":["../src/semantic-helpers.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"semantic-helpers.d.ts","names":[],"sources":["../src/semantic-helpers.ts"],"mappings":";;;KAcK,gBAAgB,yBAAyB,eACzC,MAAM,UACN,UAAU,QAAQ;KAElB,gBAAgB,yBAAyB,YAC5C,KAAK,iBACF,gBAAgB,OAAO;;;;;;;UAgEX;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;UASE;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;UASE;;EAEf;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqGC,QACd,QAAQ,YACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,QAAQ,yBAAyB,SAC/C,QAAQ,UACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8GV,UACd,QAAQ,cACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,UAAU,yBAAyB,SACjD,QAAQ,YACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4HV,eACd,QAAQ,mBACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,eAAe,yBAAyB,SACtD,QAAQ,iBACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO"}
|
package/dist/semantic-helpers.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as withTracing } from "./functional-Bit6noRu.js";
|
|
2
|
+
import { t as assertTraceFactory } from "./trace-factory-validation-BjVAinz6.js";
|
|
3
|
+
import { SpanKind } from "@opentelemetry/api";
|
|
2
4
|
|
|
3
5
|
//#region src/semantic-helpers.ts
|
|
4
6
|
/**
|
|
@@ -9,317 +11,96 @@ import { a as trace } from "./functional-CrAq8Az8.js";
|
|
|
9
11
|
*
|
|
10
12
|
* Based on: https://opentelemetry.io/docs/specs/semconv/
|
|
11
13
|
*/
|
|
14
|
+
function setConfiguredAttributes(ctx, attributes) {
|
|
15
|
+
if (!attributes) return;
|
|
16
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
17
|
+
if (value === void 0 || value === null) continue;
|
|
18
|
+
const attributeValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
|
|
19
|
+
ctx.setAttribute(key, attributeValue);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
12
22
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Automatically adds standard attributes for database operations:
|
|
16
|
-
* - db.system
|
|
17
|
-
* - db.operation
|
|
18
|
-
* - db.name
|
|
19
|
-
* - db.collection.name (for NoSQL)
|
|
20
|
-
*
|
|
21
|
-
* **Use Cases:**
|
|
22
|
-
* - SQL queries (PostgreSQL, MySQL, SQLite)
|
|
23
|
-
* - NoSQL operations (MongoDB, DynamoDB, Redis)
|
|
24
|
-
* - ORM queries (Prisma, TypeORM, Drizzle)
|
|
25
|
-
*
|
|
26
|
-
* @param config - Database operation configuration
|
|
27
|
-
* @returns Traced function factory with DB attributes
|
|
28
|
-
*
|
|
29
|
-
* @example PostgreSQL query
|
|
30
|
-
* ```typescript
|
|
31
|
-
* import { traceDB } from 'autotel/semantic-helpers'
|
|
32
|
-
* import { pool } from './db'
|
|
33
|
-
*
|
|
34
|
-
* export const getUser = traceDB({
|
|
35
|
-
* system: 'postgresql',
|
|
36
|
-
* operation: 'SELECT',
|
|
37
|
-
* database: 'app_db',
|
|
38
|
-
* collection: 'users'
|
|
39
|
-
* })(ctx => async (userId: string) => {
|
|
40
|
-
* const query = 'SELECT * FROM users WHERE id = $1'
|
|
41
|
-
* ctx.setAttribute('db.statement', query)
|
|
42
|
-
*
|
|
43
|
-
* const result = await pool.query(query, [userId])
|
|
44
|
-
* ctx.setAttribute('db.rows_affected', result.rowCount)
|
|
45
|
-
*
|
|
46
|
-
* return result.rows[0]
|
|
47
|
-
* })
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* @example MongoDB with Mongoose
|
|
51
|
-
* ```typescript
|
|
52
|
-
* import { traceDB } from 'autotel/semantic-helpers'
|
|
53
|
-
* import { User } from './models/User'
|
|
54
|
-
*
|
|
55
|
-
* export const findUsers = traceDB({
|
|
56
|
-
* system: 'mongodb',
|
|
57
|
-
* operation: 'find',
|
|
58
|
-
* database: 'app_db',
|
|
59
|
-
* collection: 'users'
|
|
60
|
-
* })(ctx => async (filter: object) => {
|
|
61
|
-
* ctx.setAttribute('db.mongodb.filter', JSON.stringify(filter))
|
|
62
|
-
*
|
|
63
|
-
* const users = await User.find(filter).limit(100)
|
|
64
|
-
* ctx.setAttribute('db.response.count', users.length)
|
|
65
|
-
*
|
|
66
|
-
* return users
|
|
67
|
-
* })
|
|
68
|
-
* ```
|
|
69
|
-
*
|
|
70
|
-
* @example Redis operations
|
|
71
|
-
* ```typescript
|
|
72
|
-
* import { traceDB } from 'autotel/semantic-helpers'
|
|
73
|
-
* import { redis } from './redis'
|
|
74
|
-
*
|
|
75
|
-
* export const cacheGet = traceDB({
|
|
76
|
-
* system: 'redis',
|
|
77
|
-
* operation: 'GET'
|
|
78
|
-
* })(ctx => async (key: string) => {
|
|
79
|
-
* ctx.setAttribute('db.redis.key', key)
|
|
80
|
-
*
|
|
81
|
-
* const value = await redis.get(key)
|
|
82
|
-
* ctx.setAttribute('db.response.cache_hit', value !== null)
|
|
83
|
-
*
|
|
84
|
-
* return value
|
|
85
|
-
* })
|
|
86
|
-
* ```
|
|
87
|
-
*
|
|
88
|
-
* @example Prisma with detailed query info
|
|
89
|
-
* ```typescript
|
|
90
|
-
* import { traceDB } from 'autotel/semantic-helpers'
|
|
91
|
-
* import { prisma } from './prisma'
|
|
92
|
-
*
|
|
93
|
-
* export const createPost = traceDB({
|
|
94
|
-
* system: 'postgresql',
|
|
95
|
-
* operation: 'INSERT',
|
|
96
|
-
* database: 'app_db',
|
|
97
|
-
* collection: 'posts'
|
|
98
|
-
* })(ctx => async (data: { title: string; content: string; authorId: string }) => {
|
|
99
|
-
* ctx.setAttribute('db.prisma.model', 'Post')
|
|
100
|
-
* ctx.setAttribute('db.prisma.action', 'create')
|
|
101
|
-
*
|
|
102
|
-
* const post = await prisma.post.create({ data })
|
|
103
|
-
*
|
|
104
|
-
* ctx.setAttribute('db.response.id', post.id)
|
|
105
|
-
* return post
|
|
106
|
-
* })
|
|
107
|
-
* ```
|
|
108
|
-
*
|
|
109
|
-
* @public
|
|
23
|
+
* Shared tail of `traceDB`/`traceHTTP`/`traceMessaging`: wrap `fn` directly
|
|
24
|
+
* when given, otherwise return the curried factory-acceptor form.
|
|
110
25
|
*/
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
26
|
+
function wrapSemantic(helperName, name, spanKind, configure, fn) {
|
|
27
|
+
if (fn) {
|
|
28
|
+
assertTraceFactory(helperName, fn);
|
|
29
|
+
return withTracing({
|
|
30
|
+
name,
|
|
31
|
+
spanKind
|
|
32
|
+
})((ctx) => {
|
|
33
|
+
configure(ctx);
|
|
34
|
+
return fn;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return (factory) => {
|
|
38
|
+
assertTraceFactory(helperName, factory);
|
|
39
|
+
return withTracing({
|
|
40
|
+
name,
|
|
41
|
+
spanKind
|
|
42
|
+
})((ctx) => {
|
|
43
|
+
configure(ctx);
|
|
44
|
+
const handler = factory(ctx);
|
|
45
|
+
assertTraceFactory(helperName, handler, "result");
|
|
46
|
+
return handler;
|
|
125
47
|
});
|
|
126
48
|
};
|
|
127
49
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
* export const fetchUser = traceHTTP({
|
|
148
|
-
* method: 'GET',
|
|
149
|
-
* url: 'https://api.example.com/users/:id'
|
|
150
|
-
* })(ctx => async (userId: string) => {
|
|
151
|
-
* const url = `https://api.example.com/users/${userId}`
|
|
152
|
-
* ctx.setAttribute('url.full', url)
|
|
153
|
-
*
|
|
154
|
-
* const response = await fetch(url)
|
|
155
|
-
* ctx.setAttribute('http.response.status_code', response.status)
|
|
156
|
-
*
|
|
157
|
-
* if (!response.ok) {
|
|
158
|
-
* ctx.setAttribute('error', true)
|
|
159
|
-
* throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
160
|
-
* }
|
|
161
|
-
*
|
|
162
|
-
* return response.json()
|
|
163
|
-
* })
|
|
164
|
-
* ```
|
|
165
|
-
*
|
|
166
|
-
* @example Axios with retry logic
|
|
167
|
-
* ```typescript
|
|
168
|
-
* import { traceHTTP } from 'autotel/semantic-helpers'
|
|
169
|
-
* import axios from 'axios'
|
|
170
|
-
*
|
|
171
|
-
* export const sendWebhook = traceHTTP({
|
|
172
|
-
* method: 'POST',
|
|
173
|
-
* url: 'https://webhook.example.com/events'
|
|
174
|
-
* })(ctx => async (payload: object) => {
|
|
175
|
-
* let attempts = 0
|
|
176
|
-
* const maxAttempts = 3
|
|
177
|
-
*
|
|
178
|
-
* while (attempts < maxAttempts) {
|
|
179
|
-
* try {
|
|
180
|
-
* attempts++
|
|
181
|
-
* ctx.setAttribute('http.request.resend_count', attempts - 1)
|
|
182
|
-
*
|
|
183
|
-
* const response = await axios.post('https://webhook.example.com/events', payload)
|
|
184
|
-
* ctx.setAttribute('http.response.status_code', response.status)
|
|
185
|
-
* return response.data
|
|
186
|
-
* } catch (error) {
|
|
187
|
-
* if (attempts >= maxAttempts) throw error
|
|
188
|
-
* await new Promise(resolve => setTimeout(resolve, 1000 * attempts))
|
|
189
|
-
* }
|
|
190
|
-
* }
|
|
191
|
-
* })
|
|
192
|
-
* ```
|
|
193
|
-
*
|
|
194
|
-
* @public
|
|
195
|
-
*/
|
|
196
|
-
function traceHTTP(config) {
|
|
197
|
-
return (fnFactory) => {
|
|
198
|
-
return trace((ctx) => {
|
|
199
|
-
if (config.method) ctx.setAttribute("http.request.method", config.method);
|
|
200
|
-
if (config.url) ctx.setAttribute("url.full", config.url);
|
|
201
|
-
if (config.attributes) {
|
|
202
|
-
for (const [key, value] of Object.entries(config.attributes)) if (value !== void 0 && value !== null) {
|
|
203
|
-
const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
|
|
204
|
-
ctx.setAttribute(key, attrValue);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return fnFactory(ctx);
|
|
208
|
-
});
|
|
50
|
+
function traceDB(config, fn) {
|
|
51
|
+
if (!config || typeof config !== "object") throw new TypeError("traceDB: config must be an object");
|
|
52
|
+
if (typeof config.system !== "string" || config.system.trim() === "") throw new TypeError("traceDB: config.system must be a non-empty string");
|
|
53
|
+
const target = config.collection ?? config.database;
|
|
54
|
+
const spanName = (config.querySummary ?? [config.operation, target].filter(Boolean).join(" ")) || config.system;
|
|
55
|
+
const configure = (ctx) => {
|
|
56
|
+
ctx.setAttribute("db.system.name", config.system);
|
|
57
|
+
ctx.setAttribute("db.system", config.system);
|
|
58
|
+
if (config.operation) {
|
|
59
|
+
ctx.setAttribute("db.operation.name", config.operation);
|
|
60
|
+
ctx.setAttribute("db.operation", config.operation);
|
|
61
|
+
}
|
|
62
|
+
if (config.database) {
|
|
63
|
+
ctx.setAttribute("db.namespace", config.database);
|
|
64
|
+
ctx.setAttribute("db.name", config.database);
|
|
65
|
+
}
|
|
66
|
+
if (config.collection) ctx.setAttribute("db.collection.name", config.collection);
|
|
67
|
+
if (config.querySummary) ctx.setAttribute("db.query.summary", config.querySummary);
|
|
68
|
+
setConfiguredAttributes(ctx, config.attributes);
|
|
209
69
|
};
|
|
70
|
+
return wrapSemantic("traceDB", spanName, SpanKind.CLIENT, configure, fn);
|
|
210
71
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
*
|
|
242
|
-
* await producer.send({
|
|
243
|
-
* topic: 'user-events',
|
|
244
|
-
* messages: [
|
|
245
|
-
* {
|
|
246
|
-
* key: event.userId,
|
|
247
|
-
* value: JSON.stringify(event.data)
|
|
248
|
-
* }
|
|
249
|
-
* ]
|
|
250
|
-
* })
|
|
251
|
-
*
|
|
252
|
-
* ctx.setAttribute('messaging.message.id', event.userId)
|
|
253
|
-
* })
|
|
254
|
-
* ```
|
|
255
|
-
*
|
|
256
|
-
* @example Consuming from RabbitMQ
|
|
257
|
-
* ```typescript
|
|
258
|
-
* import { traceMessaging } from 'autotel/semantic-helpers'
|
|
259
|
-
* import { channel } from './rabbitmq'
|
|
260
|
-
*
|
|
261
|
-
* export const processOrder = traceMessaging({
|
|
262
|
-
* system: 'rabbitmq',
|
|
263
|
-
* operation: 'process',
|
|
264
|
-
* destination: 'orders'
|
|
265
|
-
* })(ctx => async (message: { orderId: string; items: object[] }) => {
|
|
266
|
-
* ctx.setAttribute('messaging.message.id', message.orderId)
|
|
267
|
-
* ctx.setAttribute('messaging.message.body.size', JSON.stringify(message).length)
|
|
268
|
-
*
|
|
269
|
-
* // Process order logic
|
|
270
|
-
* const result = await processOrderInternal(message)
|
|
271
|
-
*
|
|
272
|
-
* ctx.setAttribute('messaging.operation.result', 'success')
|
|
273
|
-
* return result
|
|
274
|
-
* })
|
|
275
|
-
* ```
|
|
276
|
-
*
|
|
277
|
-
* @example AWS SQS with batch processing
|
|
278
|
-
* ```typescript
|
|
279
|
-
* import { traceMessaging } from 'autotel/semantic-helpers'
|
|
280
|
-
* import { SQS } from '@aws-sdk/client-sqs'
|
|
281
|
-
*
|
|
282
|
-
* const sqs = new SQS()
|
|
283
|
-
*
|
|
284
|
-
* export const sendBatch = traceMessaging({
|
|
285
|
-
* system: 'aws_sqs',
|
|
286
|
-
* operation: 'publish',
|
|
287
|
-
* destination: 'notifications-queue'
|
|
288
|
-
* })(ctx => async (messages: Array<{ id: string; body: object }>) => {
|
|
289
|
-
* ctx.setAttribute('messaging.batch.message_count', messages.length)
|
|
290
|
-
*
|
|
291
|
-
* const result = await sqs.sendMessageBatch({
|
|
292
|
-
* QueueUrl: process.env.QUEUE_URL,
|
|
293
|
-
* Entries: messages.map(msg => ({
|
|
294
|
-
* Id: msg.id,
|
|
295
|
-
* MessageBody: JSON.stringify(msg.body)
|
|
296
|
-
* }))
|
|
297
|
-
* })
|
|
298
|
-
*
|
|
299
|
-
* ctx.setAttribute('messaging.operation.success_count', result.Successful?.length || 0)
|
|
300
|
-
* ctx.setAttribute('messaging.operation.failed_count', result.Failed?.length || 0)
|
|
301
|
-
*
|
|
302
|
-
* return result
|
|
303
|
-
* })
|
|
304
|
-
* ```
|
|
305
|
-
*
|
|
306
|
-
* @public
|
|
307
|
-
*/
|
|
308
|
-
function traceMessaging(config) {
|
|
309
|
-
return (fnFactory) => {
|
|
310
|
-
return trace((ctx) => {
|
|
311
|
-
ctx.setAttribute("messaging.system", config.system);
|
|
312
|
-
if (config.operation) ctx.setAttribute("messaging.operation", config.operation);
|
|
313
|
-
if (config.destination) ctx.setAttribute("messaging.destination.name", config.destination);
|
|
314
|
-
if (config.attributes) {
|
|
315
|
-
for (const [key, value] of Object.entries(config.attributes)) if (value !== void 0 && value !== null) {
|
|
316
|
-
const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
|
|
317
|
-
ctx.setAttribute(key, attrValue);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
return fnFactory(ctx);
|
|
321
|
-
});
|
|
72
|
+
function traceHTTP(config, fn) {
|
|
73
|
+
if (!config || typeof config !== "object") throw new TypeError("traceHTTP: config must be an object");
|
|
74
|
+
const method = config.method?.toUpperCase() || "HTTP";
|
|
75
|
+
const target = config.route ?? config.urlTemplate;
|
|
76
|
+
const spanName = target ? `${method} ${target}` : method;
|
|
77
|
+
const configure = (ctx) => {
|
|
78
|
+
if (config.method) ctx.setAttribute("http.request.method", method);
|
|
79
|
+
if (config.url) ctx.setAttribute("url.full", config.url);
|
|
80
|
+
if (config.route) ctx.setAttribute("http.route", config.route);
|
|
81
|
+
if (config.urlTemplate) ctx.setAttribute("url.template", config.urlTemplate);
|
|
82
|
+
setConfiguredAttributes(ctx, config.attributes);
|
|
83
|
+
};
|
|
84
|
+
return wrapSemantic("traceHTTP", spanName, SpanKind.CLIENT, configure, fn);
|
|
85
|
+
}
|
|
86
|
+
function traceMessaging(config, fn) {
|
|
87
|
+
if (!config || typeof config !== "object") throw new TypeError("traceMessaging: config must be an object");
|
|
88
|
+
if (typeof config.system !== "string" || config.system.trim() === "") throw new TypeError("traceMessaging: config.system must be a non-empty string");
|
|
89
|
+
const operation = config.operation ?? "messaging";
|
|
90
|
+
const spanName = [operation, config.destination].filter(Boolean).join(" ");
|
|
91
|
+
const operationType = operation === "publish" ? "send" : operation;
|
|
92
|
+
const spanKind = operation === "publish" ? SpanKind.PRODUCER : operation === "process" ? SpanKind.CONSUMER : operation === "receive" ? SpanKind.CLIENT : SpanKind.INTERNAL;
|
|
93
|
+
const configure = (ctx) => {
|
|
94
|
+
ctx.setAttribute("messaging.system", config.system);
|
|
95
|
+
if (config.operation) {
|
|
96
|
+
ctx.setAttribute("messaging.operation.name", config.operation);
|
|
97
|
+
ctx.setAttribute("messaging.operation.type", operationType);
|
|
98
|
+
ctx.setAttribute("messaging.operation", config.operation);
|
|
99
|
+
}
|
|
100
|
+
if (config.destination) ctx.setAttribute("messaging.destination.name", config.destination);
|
|
101
|
+
setConfiguredAttributes(ctx, config.attributes);
|
|
322
102
|
};
|
|
103
|
+
return wrapSemantic("traceMessaging", spanName, spanKind, configure, fn);
|
|
323
104
|
}
|
|
324
105
|
|
|
325
106
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-helpers.js","names":[],"sources":["../src/semantic-helpers.ts"],"sourcesContent":["/**\n * Semantic convention helpers for OpenTelemetry\n *\n * Pre-configured trace helpers that follow OpenTelemetry semantic conventions\n * for common operation types. Reduces boilerplate and ensures consistency.\n *\n * Based on: https://opentelemetry.io/docs/specs/semconv/\n */\n\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport type { Attributes } from '@opentelemetry/api';\n\n/**\n * Configuration for database operations\n *\n * Follows DB semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/database/\n */\nexport interface DBConfig {\n /** Database system (e.g., 'postgresql', 'mongodb', 'redis') */\n system: string;\n /** Operation type (e.g., 'SELECT', 'INSERT', 'find', 'get') */\n operation?: string;\n /** Database name */\n database?: string;\n /** Collection/table name */\n collection?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for HTTP client operations\n *\n * Follows HTTP semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/http/\n */\nexport interface HTTPConfig {\n /** HTTP method (e.g., 'GET', 'POST') */\n method?: string;\n /** Target URL or URL template */\n url?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for messaging operations\n *\n * Follows Messaging semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/messaging/\n */\nexport interface MessagingConfig {\n /** Messaging system (e.g., 'kafka', 'rabbitmq', 'sqs') */\n system: string;\n /** Operation type */\n operation?: 'publish' | 'receive' | 'process';\n /** Destination name (queue/topic) */\n destination?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Trace database operations with DB semantic conventions\n *\n * Automatically adds standard attributes for database operations:\n * - db.system\n * - db.operation\n * - db.name\n * - db.collection.name (for NoSQL)\n *\n * **Use Cases:**\n * - SQL queries (PostgreSQL, MySQL, SQLite)\n * - NoSQL operations (MongoDB, DynamoDB, Redis)\n * - ORM queries (Prisma, TypeORM, Drizzle)\n *\n * @param config - Database operation configuration\n * @returns Traced function factory with DB attributes\n *\n * @example PostgreSQL query\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { pool } from './db'\n *\n * export const getUser = traceDB({\n * system: 'postgresql',\n * operation: 'SELECT',\n * database: 'app_db',\n * collection: 'users'\n * })(ctx => async (userId: string) => {\n * const query = 'SELECT * FROM users WHERE id = $1'\n * ctx.setAttribute('db.statement', query)\n *\n * const result = await pool.query(query, [userId])\n * ctx.setAttribute('db.rows_affected', result.rowCount)\n *\n * return result.rows[0]\n * })\n * ```\n *\n * @example MongoDB with Mongoose\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { User } from './models/User'\n *\n * export const findUsers = traceDB({\n * system: 'mongodb',\n * operation: 'find',\n * database: 'app_db',\n * collection: 'users'\n * })(ctx => async (filter: object) => {\n * ctx.setAttribute('db.mongodb.filter', JSON.stringify(filter))\n *\n * const users = await User.find(filter).limit(100)\n * ctx.setAttribute('db.response.count', users.length)\n *\n * return users\n * })\n * ```\n *\n * @example Redis operations\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { redis } from './redis'\n *\n * export const cacheGet = traceDB({\n * system: 'redis',\n * operation: 'GET'\n * })(ctx => async (key: string) => {\n * ctx.setAttribute('db.redis.key', key)\n *\n * const value = await redis.get(key)\n * ctx.setAttribute('db.response.cache_hit', value !== null)\n *\n * return value\n * })\n * ```\n *\n * @example Prisma with detailed query info\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { prisma } from './prisma'\n *\n * export const createPost = traceDB({\n * system: 'postgresql',\n * operation: 'INSERT',\n * database: 'app_db',\n * collection: 'posts'\n * })(ctx => async (data: { title: string; content: string; authorId: string }) => {\n * ctx.setAttribute('db.prisma.model', 'Post')\n * ctx.setAttribute('db.prisma.action', 'create')\n *\n * const post = await prisma.post.create({ data })\n *\n * ctx.setAttribute('db.response.id', post.id)\n * return post\n * })\n * ```\n *\n * @public\n */\nexport function traceDB<TArgs extends unknown[], TReturn>(config: DBConfig) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('db.system', config.system);\n if (config.operation) {\n ctx.setAttribute('db.operation', config.operation);\n }\n if (config.database) {\n ctx.setAttribute('db.name', config.database);\n }\n if (config.collection) {\n ctx.setAttribute('db.collection.name', config.collection);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n\n/**\n * Trace HTTP client operations with HTTP semantic conventions\n *\n * Automatically adds standard attributes for HTTP requests:\n * - http.request.method\n * - url.full\n *\n * **Use Cases:**\n * - External API calls\n * - Microservice communication\n * - Third-party integrations\n *\n * @param config - HTTP operation configuration\n * @returns Traced function factory with HTTP attributes\n *\n * @example Fetch API\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n *\n * export const fetchUser = traceHTTP({\n * method: 'GET',\n * url: 'https://api.example.com/users/:id'\n * })(ctx => async (userId: string) => {\n * const url = `https://api.example.com/users/${userId}`\n * ctx.setAttribute('url.full', url)\n *\n * const response = await fetch(url)\n * ctx.setAttribute('http.response.status_code', response.status)\n *\n * if (!response.ok) {\n * ctx.setAttribute('error', true)\n * throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n * }\n *\n * return response.json()\n * })\n * ```\n *\n * @example Axios with retry logic\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n * import axios from 'axios'\n *\n * export const sendWebhook = traceHTTP({\n * method: 'POST',\n * url: 'https://webhook.example.com/events'\n * })(ctx => async (payload: object) => {\n * let attempts = 0\n * const maxAttempts = 3\n *\n * while (attempts < maxAttempts) {\n * try {\n * attempts++\n * ctx.setAttribute('http.request.resend_count', attempts - 1)\n *\n * const response = await axios.post('https://webhook.example.com/events', payload)\n * ctx.setAttribute('http.response.status_code', response.status)\n * return response.data\n * } catch (error) {\n * if (attempts >= maxAttempts) throw error\n * await new Promise(resolve => setTimeout(resolve, 1000 * attempts))\n * }\n * }\n * })\n * ```\n *\n * @public\n */\nexport function traceHTTP<TArgs extends unknown[], TReturn>(\n config: HTTPConfig,\n) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n if (config.method) {\n ctx.setAttribute('http.request.method', config.method);\n }\n if (config.url) {\n ctx.setAttribute('url.full', config.url);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n\n/**\n * Trace messaging operations with Messaging semantic conventions\n *\n * Automatically adds standard attributes for messaging:\n * - messaging.system\n * - messaging.operation\n * - messaging.destination.name\n *\n * **Use Cases:**\n * - Publishing messages to queues/topics\n * - Consuming messages from queues/topics\n * - Event-driven architectures\n *\n * @param config - Messaging operation configuration\n * @returns Traced function factory with Messaging attributes\n *\n * @example Publishing to Kafka\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { kafka } from './kafka'\n *\n * const producer = kafka.producer()\n *\n * export const publishEvent = traceMessaging({\n * system: 'kafka',\n * operation: 'publish',\n * destination: 'user-events'\n * })(ctx => async (event: { type: string; userId: string; data: object }) => {\n * ctx.setAttribute('messaging.message.type', event.type)\n * ctx.setAttribute('messaging.kafka.partition', 0)\n *\n * await producer.send({\n * topic: 'user-events',\n * messages: [\n * {\n * key: event.userId,\n * value: JSON.stringify(event.data)\n * }\n * ]\n * })\n *\n * ctx.setAttribute('messaging.message.id', event.userId)\n * })\n * ```\n *\n * @example Consuming from RabbitMQ\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { channel } from './rabbitmq'\n *\n * export const processOrder = traceMessaging({\n * system: 'rabbitmq',\n * operation: 'process',\n * destination: 'orders'\n * })(ctx => async (message: { orderId: string; items: object[] }) => {\n * ctx.setAttribute('messaging.message.id', message.orderId)\n * ctx.setAttribute('messaging.message.body.size', JSON.stringify(message).length)\n *\n * // Process order logic\n * const result = await processOrderInternal(message)\n *\n * ctx.setAttribute('messaging.operation.result', 'success')\n * return result\n * })\n * ```\n *\n * @example AWS SQS with batch processing\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { SQS } from '@aws-sdk/client-sqs'\n *\n * const sqs = new SQS()\n *\n * export const sendBatch = traceMessaging({\n * system: 'aws_sqs',\n * operation: 'publish',\n * destination: 'notifications-queue'\n * })(ctx => async (messages: Array<{ id: string; body: object }>) => {\n * ctx.setAttribute('messaging.batch.message_count', messages.length)\n *\n * const result = await sqs.sendMessageBatch({\n * QueueUrl: process.env.QUEUE_URL,\n * Entries: messages.map(msg => ({\n * Id: msg.id,\n * MessageBody: JSON.stringify(msg.body)\n * }))\n * })\n *\n * ctx.setAttribute('messaging.operation.success_count', result.Successful?.length || 0)\n * ctx.setAttribute('messaging.operation.failed_count', result.Failed?.length || 0)\n *\n * return result\n * })\n * ```\n *\n * @public\n */\nexport function traceMessaging<TArgs extends unknown[], TReturn>(\n config: MessagingConfig,\n) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('messaging.system', config.system);\n if (config.operation) {\n ctx.setAttribute('messaging.operation', config.operation);\n }\n if (config.destination) {\n ctx.setAttribute('messaging.destination.name', config.destination);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmKA,SAAgB,QAA0C,QAAkB;CAC1E,QACE,cAC2C;EAC3C,OAAO,OAAuB,QAAQ;GAEpC,IAAI,aAAa,aAAa,OAAO,MAAM;GAC3C,IAAI,OAAO,WACT,IAAI,aAAa,gBAAgB,OAAO,SAAS;GAEnD,IAAI,OAAO,UACT,IAAI,aAAa,WAAW,OAAO,QAAQ;GAE7C,IAAI,OAAO,YACT,IAAI,aAAa,sBAAsB,OAAO,UAAU;GAE1D,IAAI,OAAO,YACT;SAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,UAAU,GACzD,IAAI,UAAU,UAAa,UAAU,MAAM;KAGzC,MAAM,YACJ,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,YACb,QACA,KAAK,UAAU,KAAK;KAC1B,IAAI,aAAa,KAAK,SAAS;IACjC;GACF;GAIF,OAAO,UAAU,GAAG;EACtB,CAAC;CACH;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsEA,SAAgB,UACd,QACA;CACA,QACE,cAC2C;EAC3C,OAAO,OAAuB,QAAQ;GAEpC,IAAI,OAAO,QACT,IAAI,aAAa,uBAAuB,OAAO,MAAM;GAEvD,IAAI,OAAO,KACT,IAAI,aAAa,YAAY,OAAO,GAAG;GAEzC,IAAI,OAAO,YACT;SAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,UAAU,GACzD,IAAI,UAAU,UAAa,UAAU,MAAM;KAGzC,MAAM,YACJ,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,YACb,QACA,KAAK,UAAU,KAAK;KAC1B,IAAI,aAAa,KAAK,SAAS;IACjC;GACF;GAIF,OAAO,UAAU,GAAG;EACtB,CAAC;CACH;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmGA,SAAgB,eACd,QACA;CACA,QACE,cAC2C;EAC3C,OAAO,OAAuB,QAAQ;GAEpC,IAAI,aAAa,oBAAoB,OAAO,MAAM;GAClD,IAAI,OAAO,WACT,IAAI,aAAa,uBAAuB,OAAO,SAAS;GAE1D,IAAI,OAAO,aACT,IAAI,aAAa,8BAA8B,OAAO,WAAW;GAEnE,IAAI,OAAO,YACT;SAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,UAAU,GACzD,IAAI,UAAU,UAAa,UAAU,MAAM;KAGzC,MAAM,YACJ,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,YACb,QACA,KAAK,UAAU,KAAK;KAC1B,IAAI,aAAa,KAAK,SAAS;IACjC;GACF;GAIF,OAAO,UAAU,GAAG;EACtB,CAAC;CACH;AACF"}
|
|
1
|
+
{"version":3,"file":"semantic-helpers.js","names":[],"sources":["../src/semantic-helpers.ts"],"sourcesContent":["/**\n * Semantic convention helpers for OpenTelemetry\n *\n * Pre-configured trace helpers that follow OpenTelemetry semantic conventions\n * for common operation types. Reduces boilerplate and ensures consistency.\n *\n * Based on: https://opentelemetry.io/docs/specs/semconv/\n */\n\nimport { withTracing } from './functional';\nimport { assertTraceFactory } from './trace-factory-validation';\nimport type { TraceContext } from './trace-context';\nimport { SpanKind, type Attributes } from '@opentelemetry/api';\n\ntype SemanticHandler<TArgs extends unknown[], TReturn> = (\n ...args: TArgs\n) => TReturn | Promise<TReturn>;\n\ntype SemanticFactory<TArgs extends unknown[], TReturn> = (\n ctx: TraceContext,\n) => SemanticHandler<TArgs, TReturn>;\n\nfunction setConfiguredAttributes(\n ctx: TraceContext,\n attributes?: Attributes,\n): void {\n if (!attributes) return;\n for (const [key, value] of Object.entries(attributes)) {\n if (value === undefined || value === null) continue;\n const attributeValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attributeValue);\n }\n}\n\n/**\n * Shared tail of `traceDB`/`traceHTTP`/`traceMessaging`: wrap `fn` directly\n * when given, otherwise return the curried factory-acceptor form.\n */\nfunction wrapSemantic<TArgs extends unknown[], TReturn>(\n helperName: string,\n name: string,\n spanKind: SpanKind,\n configure: (ctx: TraceContext) => void,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (fn) {\n assertTraceFactory(helperName, fn);\n return withTracing<TArgs, TReturn>({ name, spanKind })(\n (ctx: TraceContext) => {\n configure(ctx);\n return fn;\n },\n );\n }\n return <TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => {\n assertTraceFactory(helperName, factory);\n return withTracing<TFactoryArgs, TFactoryReturn>({ name, spanKind })(\n (ctx: TraceContext) => {\n configure(ctx);\n const handler = factory(ctx);\n assertTraceFactory(helperName, handler, 'result');\n return handler;\n },\n );\n };\n}\n\n/**\n * Configuration for database operations\n *\n * Follows DB semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/database/\n */\nexport interface DBConfig {\n /** Database system (e.g., 'postgresql', 'mongodb', 'redis') */\n system: string;\n /** Operation type (e.g., 'SELECT', 'INSERT', 'find', 'get') */\n operation?: string;\n /** Database name */\n database?: string;\n /** Collection/table name */\n collection?: string;\n /** Low-cardinality query summary used as the preferred span name */\n querySummary?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for HTTP client operations\n *\n * Follows HTTP semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/http/\n */\nexport interface HTTPConfig {\n /** HTTP method (e.g., 'GET', 'POST') */\n method?: string;\n /** Target URL or URL template */\n url?: string;\n /** Low-cardinality server route used in the span name */\n route?: string;\n /** Low-cardinality client URL template used in the span name */\n urlTemplate?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for messaging operations\n *\n * Follows Messaging semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/messaging/\n */\nexport interface MessagingConfig {\n /** Messaging system (e.g., 'kafka', 'rabbitmq', 'sqs') */\n system: string;\n /** Operation type */\n operation?: 'publish' | 'receive' | 'process';\n /** Destination name (queue/topic) */\n destination?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Trace database operations with DB semantic conventions\n *\n * Automatically adds standard attributes for database operations:\n * - db.system.name\n * - db.operation.name\n * - db.namespace\n * - db.collection.name (for NoSQL)\n *\n * **Use Cases:**\n * - SQL queries (PostgreSQL, MySQL, SQLite)\n * - NoSQL operations (MongoDB, DynamoDB, Redis)\n * - ORM queries (Prisma, TypeORM, Drizzle)\n *\n * @param config - Database operation configuration\n * @returns Traced function factory with DB attributes\n *\n * @example PostgreSQL query\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { pool } from './db'\n *\n * export const getUser = traceDB({\n * system: 'postgresql',\n * operation: 'SELECT',\n * database: 'app_db',\n * collection: 'users',\n * querySummary: 'SELECT users'\n * })(ctx => async (userId: string) => {\n * const query = 'SELECT * FROM users WHERE id = $1'\n * const result = await pool.query(query, [userId])\n * ctx.setAttribute('db.rows_affected', result.rowCount)\n *\n * return result.rows[0]\n * })\n * ```\n *\n * @example MongoDB with Mongoose\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { User } from './models/User'\n *\n * export const findUsers = traceDB({\n * system: 'mongodb',\n * operation: 'find',\n * database: 'app_db',\n * collection: 'users'\n * })(ctx => async (filter: object) => {\n * ctx.setAttribute('db.mongodb.filter', JSON.stringify(filter))\n *\n * const users = await User.find(filter).limit(100)\n * ctx.setAttribute('db.response.count', users.length)\n *\n * return users\n * })\n * ```\n *\n * @example Redis operations\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { redis } from './redis'\n *\n * export const cacheGet = traceDB({\n * system: 'redis',\n * operation: 'GET'\n * })(ctx => async (key: string) => {\n * ctx.setAttribute('db.redis.key', key)\n *\n * const value = await redis.get(key)\n * ctx.setAttribute('db.response.cache_hit', value !== null)\n *\n * return value\n * })\n * ```\n *\n * @example Prisma with detailed query info\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { prisma } from './prisma'\n *\n * export const createPost = traceDB({\n * system: 'postgresql',\n * operation: 'INSERT',\n * database: 'app_db',\n * collection: 'posts'\n * })(ctx => async (data: { title: string; content: string; authorId: string }) => {\n * ctx.setAttribute('db.prisma.model', 'Post')\n * ctx.setAttribute('db.prisma.action', 'create')\n *\n * const post = await prisma.post.create({ data })\n *\n * ctx.setAttribute('db.response.id', post.id)\n * return post\n * })\n * ```\n *\n * @public\n */\nexport function traceDB(\n config: DBConfig,\n): <TArgs extends unknown[], TReturn>(\n factory: SemanticFactory<TArgs, TReturn>,\n) => SemanticHandler<TArgs, TReturn>;\nexport function traceDB<TArgs extends unknown[], TReturn>(\n config: DBConfig,\n fn: SemanticHandler<TArgs, TReturn>,\n): SemanticHandler<TArgs, TReturn>;\nexport function traceDB<TArgs extends unknown[], TReturn>(\n config: DBConfig,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (!config || typeof config !== 'object') {\n throw new TypeError('traceDB: config must be an object');\n }\n if (typeof config.system !== 'string' || config.system.trim() === '') {\n throw new TypeError('traceDB: config.system must be a non-empty string');\n }\n const target = config.collection ?? config.database;\n const name =\n config.querySummary ?? [config.operation, target].filter(Boolean).join(' ');\n const spanName = name || config.system;\n const configure = (ctx: TraceContext) => {\n // Emit current stable names plus legacy aliases for dashboard compatibility.\n ctx.setAttribute('db.system.name', config.system);\n ctx.setAttribute('db.system', config.system);\n if (config.operation) {\n ctx.setAttribute('db.operation.name', config.operation);\n ctx.setAttribute('db.operation', config.operation);\n }\n if (config.database) {\n ctx.setAttribute('db.namespace', config.database);\n ctx.setAttribute('db.name', config.database);\n }\n if (config.collection) {\n ctx.setAttribute('db.collection.name', config.collection);\n }\n if (config.querySummary) {\n ctx.setAttribute('db.query.summary', config.querySummary);\n }\n setConfiguredAttributes(ctx, config.attributes);\n };\n return wrapSemantic('traceDB', spanName, SpanKind.CLIENT, configure, fn);\n}\n\n/**\n * Trace HTTP client operations with HTTP semantic conventions\n *\n * Automatically adds standard attributes for HTTP requests:\n * - http.request.method\n * - url.full\n *\n * **Use Cases:**\n * - External API calls\n * - Microservice communication\n * - Third-party integrations\n *\n * @param config - HTTP operation configuration\n * @returns Traced function factory with HTTP attributes\n *\n * @example Fetch API\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n *\n * export const fetchUser = traceHTTP({\n * method: 'GET',\n * urlTemplate: '/users/{id}'\n * })(ctx => async (userId: string) => {\n * const url = `https://api.example.com/users/${userId}`\n * ctx.setAttribute('url.full', url)\n *\n * const response = await fetch(url)\n * ctx.setAttribute('http.response.status_code', response.status)\n *\n * if (!response.ok) {\n * ctx.setAttribute('error', true)\n * throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n * }\n *\n * return response.json()\n * })\n * ```\n *\n * @example Axios with retry logic\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n * import axios from 'axios'\n *\n * export const sendWebhook = traceHTTP({\n * method: 'POST',\n * url: 'https://webhook.example.com/events'\n * })(ctx => async (payload: object) => {\n * let attempts = 0\n * const maxAttempts = 3\n *\n * while (attempts < maxAttempts) {\n * try {\n * attempts++\n * ctx.setAttribute('http.request.resend_count', attempts - 1)\n *\n * const response = await axios.post('https://webhook.example.com/events', payload)\n * ctx.setAttribute('http.response.status_code', response.status)\n * return response.data\n * } catch (error) {\n * if (attempts >= maxAttempts) throw error\n * await new Promise(resolve => setTimeout(resolve, 1000 * attempts))\n * }\n * }\n * })\n * ```\n *\n * @public\n */\nexport function traceHTTP(\n config: HTTPConfig,\n): <TArgs extends unknown[], TReturn>(\n factory: SemanticFactory<TArgs, TReturn>,\n) => SemanticHandler<TArgs, TReturn>;\nexport function traceHTTP<TArgs extends unknown[], TReturn>(\n config: HTTPConfig,\n fn: SemanticHandler<TArgs, TReturn>,\n): SemanticHandler<TArgs, TReturn>;\nexport function traceHTTP<TArgs extends unknown[], TReturn>(\n config: HTTPConfig,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (!config || typeof config !== 'object') {\n throw new TypeError('traceHTTP: config must be an object');\n }\n const method = config.method?.toUpperCase() || 'HTTP';\n const target = config.route ?? config.urlTemplate;\n const spanName = target ? `${method} ${target}` : method;\n const configure = (ctx: TraceContext) => {\n if (config.method) ctx.setAttribute('http.request.method', method);\n if (config.url) ctx.setAttribute('url.full', config.url);\n if (config.route) ctx.setAttribute('http.route', config.route);\n if (config.urlTemplate) {\n ctx.setAttribute('url.template', config.urlTemplate);\n }\n setConfiguredAttributes(ctx, config.attributes);\n };\n return wrapSemantic('traceHTTP', spanName, SpanKind.CLIENT, configure, fn);\n}\n\n/**\n * Trace messaging operations with Messaging semantic conventions\n *\n * Automatically adds standard attributes for messaging:\n * - messaging.system\n * - messaging.operation\n * - messaging.destination.name\n *\n * **Use Cases:**\n * - Publishing messages to queues/topics\n * - Consuming messages from queues/topics\n * - Event-driven architectures\n *\n * @param config - Messaging operation configuration\n * @returns Traced function factory with Messaging attributes\n *\n * @example Publishing to Kafka\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { kafka } from './kafka'\n *\n * const producer = kafka.producer()\n *\n * export const publishEvent = traceMessaging({\n * system: 'kafka',\n * operation: 'publish',\n * destination: 'user-events'\n * })(ctx => async (event: { type: string; userId: string; data: object }) => {\n * ctx.setAttribute('messaging.message.type', event.type)\n * ctx.setAttribute('messaging.kafka.partition', 0)\n *\n * await producer.send({\n * topic: 'user-events',\n * messages: [\n * {\n * key: event.userId,\n * value: JSON.stringify(event.data)\n * }\n * ]\n * })\n *\n * ctx.setAttribute('messaging.message.id', event.userId)\n * })\n * ```\n *\n * @example Consuming from RabbitMQ\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { channel } from './rabbitmq'\n *\n * export const processOrder = traceMessaging({\n * system: 'rabbitmq',\n * operation: 'process',\n * destination: 'orders'\n * })(ctx => async (message: { orderId: string; items: object[] }) => {\n * ctx.setAttribute('messaging.message.id', message.orderId)\n * ctx.setAttribute('messaging.message.body.size', JSON.stringify(message).length)\n *\n * // Process order logic\n * const result = await processOrderInternal(message)\n *\n * ctx.setAttribute('messaging.operation.result', 'success')\n * return result\n * })\n * ```\n *\n * @example AWS SQS with batch processing\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { SQS } from '@aws-sdk/client-sqs'\n *\n * const sqs = new SQS()\n *\n * export const sendBatch = traceMessaging({\n * system: 'aws_sqs',\n * operation: 'publish',\n * destination: 'notifications-queue'\n * })(ctx => async (messages: Array<{ id: string; body: object }>) => {\n * ctx.setAttribute('messaging.batch.message_count', messages.length)\n *\n * const result = await sqs.sendMessageBatch({\n * QueueUrl: process.env.QUEUE_URL,\n * Entries: messages.map(msg => ({\n * Id: msg.id,\n * MessageBody: JSON.stringify(msg.body)\n * }))\n * })\n *\n * ctx.setAttribute('messaging.operation.success_count', result.Successful?.length || 0)\n * ctx.setAttribute('messaging.operation.failed_count', result.Failed?.length || 0)\n *\n * return result\n * })\n * ```\n *\n * @public\n */\nexport function traceMessaging(\n config: MessagingConfig,\n): <TArgs extends unknown[], TReturn>(\n factory: SemanticFactory<TArgs, TReturn>,\n) => SemanticHandler<TArgs, TReturn>;\nexport function traceMessaging<TArgs extends unknown[], TReturn>(\n config: MessagingConfig,\n fn: SemanticHandler<TArgs, TReturn>,\n): SemanticHandler<TArgs, TReturn>;\nexport function traceMessaging<TArgs extends unknown[], TReturn>(\n config: MessagingConfig,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (!config || typeof config !== 'object') {\n throw new TypeError('traceMessaging: config must be an object');\n }\n if (typeof config.system !== 'string' || config.system.trim() === '') {\n throw new TypeError(\n 'traceMessaging: config.system must be a non-empty string',\n );\n }\n const operation = config.operation ?? 'messaging';\n const spanName = [operation, config.destination].filter(Boolean).join(' ');\n const operationType = operation === 'publish' ? 'send' : operation;\n const spanKind =\n operation === 'publish'\n ? SpanKind.PRODUCER\n : operation === 'process'\n ? SpanKind.CONSUMER\n : operation === 'receive'\n ? SpanKind.CLIENT\n : SpanKind.INTERNAL;\n const configure = (ctx: TraceContext) => {\n ctx.setAttribute('messaging.system', config.system);\n if (config.operation) {\n ctx.setAttribute('messaging.operation.name', config.operation);\n ctx.setAttribute('messaging.operation.type', operationType);\n ctx.setAttribute('messaging.operation', config.operation);\n }\n if (config.destination) {\n ctx.setAttribute('messaging.destination.name', config.destination);\n }\n setConfiguredAttributes(ctx, config.attributes);\n };\n return wrapSemantic('traceMessaging', spanName, spanKind, configure, fn);\n}\n"],"mappings":";;;;;;;;;;;;;AAsBA,SAAS,wBACP,KACA,YACM;CACN,IAAI,CAAC,YAAY;CACjB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,UAAU,GAAG;EACrD,IAAI,UAAU,UAAa,UAAU,MAAM;EAC3C,MAAM,iBACJ,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,YACb,QACA,KAAK,UAAU,KAAK;EAC1B,IAAI,aAAa,KAAK,cAAc;CACtC;AACF;;;;;AAMA,SAAS,aACP,YACA,MACA,UACA,WACA,IAKsD;CACtD,IAAI,IAAI;EACN,mBAAmB,YAAY,EAAE;EACjC,OAAO,YAA4B;GAAE;GAAM;EAAS,CAAC,CAAC,EACnD,QAAsB;GACrB,UAAU,GAAG;GACb,OAAO;EACT,CACF;CACF;CACA,QACE,YACG;EACH,mBAAmB,YAAY,OAAO;EACtC,OAAO,YAA0C;GAAE;GAAM;EAAS,CAAC,CAAC,EACjE,QAAsB;GACrB,UAAU,GAAG;GACb,MAAM,UAAU,QAAQ,GAAG;GAC3B,mBAAmB,YAAY,SAAS,QAAQ;GAChD,OAAO;EACT,CACF;CACF;AACF;AAsKA,SAAgB,QACd,QACA,IAKsD;CACtD,IAAI,CAAC,UAAU,OAAO,WAAW,UAC/B,MAAM,IAAI,UAAU,mCAAmC;CAEzD,IAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,KAAK,MAAM,IAChE,MAAM,IAAI,UAAU,mDAAmD;CAEzE,MAAM,SAAS,OAAO,cAAc,OAAO;CAG3C,MAAM,YADJ,OAAO,gBAAgB,CAAC,OAAO,WAAW,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,MACnD,OAAO;CAChC,MAAM,aAAa,QAAsB;EAEvC,IAAI,aAAa,kBAAkB,OAAO,MAAM;EAChD,IAAI,aAAa,aAAa,OAAO,MAAM;EAC3C,IAAI,OAAO,WAAW;GACpB,IAAI,aAAa,qBAAqB,OAAO,SAAS;GACtD,IAAI,aAAa,gBAAgB,OAAO,SAAS;EACnD;EACA,IAAI,OAAO,UAAU;GACnB,IAAI,aAAa,gBAAgB,OAAO,QAAQ;GAChD,IAAI,aAAa,WAAW,OAAO,QAAQ;EAC7C;EACA,IAAI,OAAO,YACT,IAAI,aAAa,sBAAsB,OAAO,UAAU;EAE1D,IAAI,OAAO,cACT,IAAI,aAAa,oBAAoB,OAAO,YAAY;EAE1D,wBAAwB,KAAK,OAAO,UAAU;CAChD;CACA,OAAO,aAAa,WAAW,UAAU,SAAS,QAAQ,WAAW,EAAE;AACzE;AA+EA,SAAgB,UACd,QACA,IAKsD;CACtD,IAAI,CAAC,UAAU,OAAO,WAAW,UAC/B,MAAM,IAAI,UAAU,qCAAqC;CAE3D,MAAM,SAAS,OAAO,QAAQ,YAAY,KAAK;CAC/C,MAAM,SAAS,OAAO,SAAS,OAAO;CACtC,MAAM,WAAW,SAAS,GAAG,OAAO,GAAG,WAAW;CAClD,MAAM,aAAa,QAAsB;EACvC,IAAI,OAAO,QAAQ,IAAI,aAAa,uBAAuB,MAAM;EACjE,IAAI,OAAO,KAAK,IAAI,aAAa,YAAY,OAAO,GAAG;EACvD,IAAI,OAAO,OAAO,IAAI,aAAa,cAAc,OAAO,KAAK;EAC7D,IAAI,OAAO,aACT,IAAI,aAAa,gBAAgB,OAAO,WAAW;EAErD,wBAAwB,KAAK,OAAO,UAAU;CAChD;CACA,OAAO,aAAa,aAAa,UAAU,SAAS,QAAQ,WAAW,EAAE;AAC3E;AA4GA,SAAgB,eACd,QACA,IAKsD;CACtD,IAAI,CAAC,UAAU,OAAO,WAAW,UAC/B,MAAM,IAAI,UAAU,0CAA0C;CAEhE,IAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,KAAK,MAAM,IAChE,MAAM,IAAI,UACR,0DACF;CAEF,MAAM,YAAY,OAAO,aAAa;CACtC,MAAM,WAAW,CAAC,WAAW,OAAO,WAAW,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CACzE,MAAM,gBAAgB,cAAc,YAAY,SAAS;CACzD,MAAM,WACJ,cAAc,YACV,SAAS,WACT,cAAc,YACZ,SAAS,WACT,cAAc,YACZ,SAAS,SACT,SAAS;CACnB,MAAM,aAAa,QAAsB;EACvC,IAAI,aAAa,oBAAoB,OAAO,MAAM;EAClD,IAAI,OAAO,WAAW;GACpB,IAAI,aAAa,4BAA4B,OAAO,SAAS;GAC7D,IAAI,aAAa,4BAA4B,aAAa;GAC1D,IAAI,aAAa,uBAAuB,OAAO,SAAS;EAC1D;EACA,IAAI,OAAO,aACT,IAAI,aAAa,8BAA8B,OAAO,WAAW;EAEnE,wBAAwB,KAAK,OAAO,UAAU;CAChD;CACA,OAAO,aAAa,kBAAkB,UAAU,UAAU,WAAW,EAAE;AACzE"}
|