autotel 3.6.0 → 4.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/dist/attribute-redacting-processor-DtTS9xxh.d.cts +175 -0
- package/dist/attribute-redacting-processor-DtTS9xxh.d.cts.map +1 -0
- package/dist/attribute-redacting-processor-DtTS9xxh.d.ts +175 -0
- package/dist/attribute-redacting-processor-DtTS9xxh.d.ts.map +1 -0
- package/dist/attribute-redacting-processor.cjs +374 -33
- package/dist/attribute-redacting-processor.cjs.map +1 -1
- package/dist/attribute-redacting-processor.d.cts +2 -207
- package/dist/attribute-redacting-processor.d.ts +2 -207
- package/dist/attribute-redacting-processor.js +368 -2
- package/dist/attribute-redacting-processor.js.map +1 -1
- package/dist/attributes-CmYpdqCN.js +591 -0
- package/dist/attributes-CmYpdqCN.js.map +1 -0
- package/dist/attributes-PZ5doLgw.cjs +704 -0
- package/dist/attributes-PZ5doLgw.cjs.map +1 -0
- package/dist/attributes.cjs +21 -85
- package/dist/attributes.d.cts +2 -20
- package/dist/attributes.d.ts +2 -20
- package/dist/attributes.js +3 -5
- package/dist/auto.cjs +50 -28
- package/dist/auto.cjs.map +1 -1
- package/dist/auto.d.cts +1 -2
- package/dist/auto.d.ts +1 -2
- package/dist/auto.js +49 -23
- package/dist/auto.js.map +1 -1
- package/dist/business-baggage.cjs +357 -13
- package/dist/business-baggage.cjs.map +1 -1
- package/dist/business-baggage.d.cts +106 -139
- package/dist/business-baggage.d.cts.map +1 -0
- package/dist/business-baggage.d.ts +106 -139
- package/dist/business-baggage.d.ts.map +1 -0
- package/dist/business-baggage.js +357 -2
- package/dist/business-baggage.js.map +1 -1
- package/dist/canonical-log-line-processor--RlFDHhm.cjs +377 -0
- package/dist/canonical-log-line-processor--RlFDHhm.cjs.map +1 -0
- package/dist/canonical-log-line-processor-BcRuAdRk.d.ts +147 -0
- package/dist/canonical-log-line-processor-BcRuAdRk.d.ts.map +1 -0
- package/dist/canonical-log-line-processor-DbBQT5vY.js +366 -0
- package/dist/canonical-log-line-processor-DbBQT5vY.js.map +1 -0
- package/dist/canonical-log-line-processor-xvjMgtpF.d.cts +147 -0
- package/dist/canonical-log-line-processor-xvjMgtpF.d.cts.map +1 -0
- package/dist/config.cjs +118 -22
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +33 -45
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.ts +33 -45
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +116 -3
- package/dist/config.js.map +1 -1
- package/dist/correlated-events-Bzh5y-UB.js +28 -0
- package/dist/correlated-events-Bzh5y-UB.js.map +1 -0
- package/dist/correlated-events-kSwLo3mi.cjs +34 -0
- package/dist/correlated-events-kSwLo3mi.cjs.map +1 -0
- package/dist/correlation-id.cjs +11 -54
- package/dist/correlation-id.d.cts +6 -5
- package/dist/correlation-id.d.cts.map +1 -0
- package/dist/correlation-id.d.ts +6 -5
- package/dist/correlation-id.d.ts.map +1 -0
- package/dist/correlation-id.js +3 -17
- package/dist/db.cjs +244 -209
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts +28 -26
- package/dist/db.d.cts.map +1 -0
- package/dist/db.d.ts +28 -26
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +243 -207
- package/dist/db.js.map +1 -1
- package/dist/decorators.cjs +39 -66
- package/dist/decorators.cjs.map +1 -1
- package/dist/decorators.d.cts +10 -37
- package/dist/decorators.d.cts.map +1 -0
- package/dist/decorators.d.ts +10 -37
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +38 -64
- package/dist/decorators.js.map +1 -1
- package/dist/define-event-CreknLm3.d.ts +25 -0
- package/dist/define-event-CreknLm3.d.ts.map +1 -0
- package/dist/define-event-HZRizPwz.d.cts +25 -0
- package/dist/define-event-HZRizPwz.d.cts.map +1 -0
- package/dist/drain-pipeline.cjs +111 -9
- package/dist/drain-pipeline.cjs.map +1 -1
- package/dist/drain-pipeline.d.cts +27 -32
- package/dist/drain-pipeline.d.cts.map +1 -0
- package/dist/drain-pipeline.d.ts +27 -32
- package/dist/drain-pipeline.d.ts.map +1 -0
- package/dist/drain-pipeline.js +111 -2
- package/dist/drain-pipeline.js.map +1 -1
- package/dist/enrichers.cjs +59 -66
- package/dist/enrichers.cjs.map +1 -1
- package/dist/enrichers.d.cts +15 -13
- package/dist/enrichers.d.cts.map +1 -0
- package/dist/enrichers.d.ts +15 -13
- package/dist/enrichers.d.ts.map +1 -0
- package/dist/enrichers.js +58 -65
- package/dist/enrichers.js.map +1 -1
- package/dist/event-Dlqr4ZNL.cjs +778 -0
- package/dist/event-Dlqr4ZNL.cjs.map +1 -0
- package/dist/event-_58ryBjh.js +761 -0
- package/dist/event-_58ryBjh.js.map +1 -0
- package/dist/event-subscriber-D1XLkPzi.d.cts +223 -0
- package/dist/event-subscriber-D1XLkPzi.d.cts.map +1 -0
- package/dist/event-subscriber-D1XLkPzi.d.ts +223 -0
- package/dist/event-subscriber-D1XLkPzi.d.ts.map +1 -0
- package/dist/event-subscriber.cjs +0 -6
- package/dist/event-subscriber.d.cts +2 -221
- package/dist/event-subscriber.d.ts +2 -221
- package/dist/event-subscriber.js +1 -3
- package/dist/event-testing-BqRnI0z4.d.cts +106 -0
- package/dist/event-testing-BqRnI0z4.d.cts.map +1 -0
- package/dist/event-testing-CfFs3to2.d.ts +106 -0
- package/dist/event-testing-CfFs3to2.d.ts.map +1 -0
- package/dist/event-testing.cjs +93 -17
- package/dist/event-testing.cjs.map +1 -1
- package/dist/event-testing.d.cts +2 -110
- package/dist/event-testing.d.ts +2 -110
- package/dist/event-testing.js +91 -2
- package/dist/event-testing.js.map +1 -1
- package/dist/event.cjs +5 -37
- package/dist/event.d.cts +295 -340
- package/dist/event.d.cts.map +1 -0
- package/dist/event.d.ts +295 -340
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +3 -21
- package/dist/exporters.cjs +12 -16
- package/dist/exporters.d.cts +86 -111
- package/dist/exporters.d.cts.map +1 -0
- package/dist/exporters.d.ts +86 -111
- package/dist/exporters.d.ts.map +1 -0
- package/dist/exporters.js +4 -4
- package/dist/filtering-span-processor-B8R8B7Uk.d.cts +59 -0
- package/dist/filtering-span-processor-B8R8B7Uk.d.cts.map +1 -0
- package/dist/filtering-span-processor-B8R8B7Uk.d.ts +59 -0
- package/dist/filtering-span-processor-B8R8B7Uk.d.ts.map +1 -0
- package/dist/filtering-span-processor.cjs +49 -9
- package/dist/filtering-span-processor.cjs.map +1 -1
- package/dist/filtering-span-processor.d.cts +2 -80
- package/dist/filtering-span-processor.d.ts +2 -80
- package/dist/filtering-span-processor.js +49 -2
- package/dist/filtering-span-processor.js.map +1 -1
- package/dist/functional-BGkT8J-h.js +1265 -0
- package/dist/functional-BGkT8J-h.js.map +1 -0
- package/dist/functional-C4CzoVrX.cjs +1312 -0
- package/dist/functional-C4CzoVrX.cjs.map +1 -0
- package/dist/functional.cjs +11 -57
- package/dist/functional.d.cts +96 -97
- package/dist/functional.d.cts.map +1 -0
- package/dist/functional.d.ts +96 -97
- package/dist/functional.d.ts.map +1 -0
- package/dist/functional.js +3 -20
- package/dist/http.cjs +276 -176
- package/dist/http.cjs.map +1 -1
- package/dist/http.d.cts +17 -37
- package/dist/http.d.cts.map +1 -0
- package/dist/http.d.ts +17 -37
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +275 -174
- package/dist/http.js.map +1 -1
- package/dist/index-Ck06vlW2.d.ts +678 -0
- package/dist/index-Ck06vlW2.d.ts.map +1 -0
- package/dist/index-eKuioqT1.d.cts +678 -0
- package/dist/index-eKuioqT1.d.cts.map +1 -0
- package/dist/index.cjs +751 -1218
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +341 -659
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +341 -659
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +606 -737
- package/dist/index.js.map +1 -1
- package/dist/init-CNp-ee80.d.cts +1157 -0
- package/dist/init-CNp-ee80.d.cts.map +1 -0
- package/dist/init-Ch6t7MNI.js +1015 -0
- package/dist/init-Ch6t7MNI.js.map +1 -0
- package/dist/init-DJQOdVlN.d.ts +1157 -0
- package/dist/init-DJQOdVlN.d.ts.map +1 -0
- package/dist/init-DvapOXCc.cjs +1092 -0
- package/dist/init-DvapOXCc.cjs.map +1 -0
- package/dist/instrumentation.cjs +159 -185
- package/dist/instrumentation.cjs.map +1 -1
- package/dist/instrumentation.d.cts +42 -40
- package/dist/instrumentation.d.cts.map +1 -0
- package/dist/instrumentation.d.ts +42 -40
- package/dist/instrumentation.d.ts.map +1 -0
- package/dist/instrumentation.js +158 -183
- package/dist/instrumentation.js.map +1 -1
- package/dist/logger-BauSUhUv.d.cts +313 -0
- package/dist/logger-BauSUhUv.d.cts.map +1 -0
- package/dist/logger-BauSUhUv.d.ts +313 -0
- package/dist/logger-BauSUhUv.d.ts.map +1 -0
- package/dist/logger.cjs +225 -25
- package/dist/logger.cjs.map +1 -1
- package/dist/logger.d.cts +2 -348
- package/dist/logger.d.ts +2 -348
- package/dist/logger.js +204 -4
- package/dist/logger.js.map +1 -1
- package/dist/messaging-adapters.cjs +292 -187
- package/dist/messaging-adapters.cjs.map +1 -1
- package/dist/messaging-adapters.d.cts +28 -66
- package/dist/messaging-adapters.d.cts.map +1 -0
- package/dist/messaging-adapters.d.ts +28 -66
- package/dist/messaging-adapters.d.ts.map +1 -0
- package/dist/messaging-adapters.js +291 -185
- package/dist/messaging-adapters.js.map +1 -1
- package/dist/messaging-testing.cjs +306 -372
- package/dist/messaging-testing.cjs.map +1 -1
- package/dist/messaging-testing.d.cts +194 -223
- package/dist/messaging-testing.d.cts.map +1 -0
- package/dist/messaging-testing.d.ts +194 -223
- package/dist/messaging-testing.d.ts.map +1 -0
- package/dist/messaging-testing.js +305 -371
- package/dist/messaging-testing.js.map +1 -1
- package/dist/messaging.cjs +757 -36
- package/dist/messaging.cjs.map +1 -1
- package/dist/messaging.d.cts +603 -644
- package/dist/messaging.d.cts.map +1 -0
- package/dist/messaging.d.ts +603 -644
- package/dist/messaging.d.ts.map +1 -0
- package/dist/messaging.js +756 -21
- package/dist/messaging.js.map +1 -1
- package/dist/metric-helpers.cjs +27 -27
- package/dist/metric-helpers.cjs.map +1 -1
- package/dist/metric-helpers.d.cts +4 -2
- package/dist/metric-helpers.d.cts.map +1 -0
- package/dist/metric-helpers.d.ts +4 -2
- package/dist/metric-helpers.d.ts.map +1 -0
- package/dist/metric-helpers.js +24 -4
- package/dist/metric-helpers.js.map +1 -1
- package/dist/metric-testing-DXdK3-Q3.d.ts +106 -0
- package/dist/metric-testing-DXdK3-Q3.d.ts.map +1 -0
- package/dist/metric-testing-MxvzChDp.d.cts +106 -0
- package/dist/metric-testing-MxvzChDp.d.cts.map +1 -0
- package/dist/metric-testing.cjs +93 -17
- package/dist/metric-testing.cjs.map +1 -1
- package/dist/metric-testing.d.cts +2 -110
- package/dist/metric-testing.d.ts +2 -110
- package/dist/metric-testing.js +91 -2
- package/dist/metric-testing.js.map +1 -1
- package/dist/metric.cjs +306 -22
- package/dist/metric.cjs.map +1 -1
- package/dist/metric.d.cts +170 -198
- package/dist/metric.d.cts.map +1 -0
- package/dist/metric.d.ts +170 -198
- package/dist/metric.d.ts.map +1 -0
- package/dist/metric.js +277 -7
- package/dist/metric.js.map +1 -1
- package/dist/node-require-DF5QBX6z.cjs +99 -0
- package/dist/node-require-DF5QBX6z.cjs.map +1 -0
- package/dist/node-require-Db1oDpLj.js +88 -0
- package/dist/node-require-Db1oDpLj.js.map +1 -0
- package/dist/operation-context-C-2hmmtP.js +59 -0
- package/dist/operation-context-C-2hmmtP.js.map +1 -0
- package/dist/operation-context-n4_obUwq.cjs +70 -0
- package/dist/operation-context-n4_obUwq.cjs.map +1 -0
- package/dist/parse-error.cjs +55 -9
- package/dist/parse-error.cjs.map +1 -1
- package/dist/parse-error.d.cts +12 -10
- package/dist/parse-error.d.cts.map +1 -0
- package/dist/parse-error.d.ts +12 -10
- package/dist/parse-error.d.ts.map +1 -0
- package/dist/parse-error.js +55 -2
- package/dist/parse-error.js.map +1 -1
- package/dist/pretty-console-exporter-CMzlrRNg.cjs +232 -0
- package/dist/pretty-console-exporter-CMzlrRNg.cjs.map +1 -0
- package/dist/pretty-console-exporter-DqKl_q9z.js +227 -0
- package/dist/pretty-console-exporter-DqKl_q9z.js.map +1 -0
- package/dist/processors.cjs +13 -17
- package/dist/processors.d.cts +3 -171
- package/dist/processors.d.ts +3 -171
- package/dist/processors.js +4 -4
- package/dist/register.cjs +35 -6
- package/dist/register.cjs.map +1 -1
- package/dist/register.d.cts +1 -2
- package/dist/register.d.ts +1 -2
- package/dist/register.js +36 -3
- package/dist/register.js.map +1 -1
- package/dist/registry-DVSmWg6Y.js +175 -0
- package/dist/registry-DVSmWg6Y.js.map +1 -0
- package/dist/registry-DYgvb62e.cjs +319 -0
- package/dist/registry-DYgvb62e.cjs.map +1 -0
- package/dist/sampling-CR0Va1VB.d.ts +351 -0
- package/dist/sampling-CR0Va1VB.d.ts.map +1 -0
- package/dist/sampling-DfYhDJij.d.cts +351 -0
- package/dist/sampling-DfYhDJij.d.cts.map +1 -0
- package/dist/sampling.cjs +452 -60
- package/dist/sampling.cjs.map +1 -1
- package/dist/sampling.d.cts +2 -379
- package/dist/sampling.d.ts +2 -379
- package/dist/sampling.js +441 -5
- package/dist/sampling.js.map +1 -1
- package/dist/security-schema.cjs +65 -46
- package/dist/security-schema.cjs.map +1 -1
- package/dist/security-schema.d.cts +23 -26
- package/dist/security-schema.d.cts.map +1 -0
- package/dist/security-schema.d.ts +23 -26
- package/dist/security-schema.d.ts.map +1 -0
- package/dist/security-schema.js +64 -45
- package/dist/security-schema.js.map +1 -1
- package/dist/semantic-conventions-FhSxv-bK.d.cts +32 -0
- package/dist/semantic-conventions-FhSxv-bK.d.cts.map +1 -0
- package/dist/semantic-conventions-FhSxv-bK.d.ts +32 -0
- package/dist/semantic-conventions-FhSxv-bK.d.ts.map +1 -0
- package/dist/semantic-conventions.cjs +15 -26
- package/dist/semantic-conventions.cjs.map +1 -1
- package/dist/semantic-conventions.d.cts +2 -29
- package/dist/semantic-conventions.d.ts +2 -29
- package/dist/semantic-conventions.js +12 -3
- package/dist/semantic-conventions.js.map +1 -1
- package/dist/semantic-helpers.cjs +327 -39
- package/dist/semantic-helpers.cjs.map +1 -1
- package/dist/semantic-helpers.d.cts +30 -150
- package/dist/semantic-helpers.d.cts.map +1 -0
- package/dist/semantic-helpers.d.ts +30 -150
- package/dist/semantic-helpers.d.ts.map +1 -0
- package/dist/semantic-helpers.js +326 -20
- package/dist/semantic-helpers.js.map +1 -1
- package/dist/span-name-normalizer-8ZOGJuwv.d.cts +70 -0
- package/dist/span-name-normalizer-8ZOGJuwv.d.cts.map +1 -0
- package/dist/span-name-normalizer-8ZOGJuwv.d.ts +70 -0
- package/dist/span-name-normalizer-8ZOGJuwv.d.ts.map +1 -0
- package/dist/span-name-normalizer.cjs +95 -17
- package/dist/span-name-normalizer.cjs.map +1 -1
- package/dist/span-name-normalizer.d.cts +2 -94
- package/dist/span-name-normalizer.d.ts +2 -94
- package/dist/span-name-normalizer.js +93 -2
- package/dist/span-name-normalizer.js.map +1 -1
- package/dist/stable-hash-BNTMrmdB.cjs +28 -0
- package/dist/stable-hash-BNTMrmdB.cjs.map +1 -0
- package/dist/stable-hash-Cg5cT34Q.js +23 -0
- package/dist/stable-hash-Cg5cT34Q.js.map +1 -0
- package/dist/structured-error-9--cxBay.js +143 -0
- package/dist/structured-error-9--cxBay.js.map +1 -0
- package/dist/structured-error-CHg7DoIQ.cjs +178 -0
- package/dist/structured-error-CHg7DoIQ.cjs.map +1 -0
- package/dist/tail-sampling-processor.cjs +26 -13
- package/dist/tail-sampling-processor.cjs.map +1 -1
- package/dist/tail-sampling-processor.d.cts +11 -23
- package/dist/tail-sampling-processor.d.cts.map +1 -0
- package/dist/tail-sampling-processor.d.ts +11 -23
- package/dist/tail-sampling-processor.d.ts.map +1 -0
- package/dist/tail-sampling-processor.js +27 -6
- package/dist/tail-sampling-processor.js.map +1 -1
- package/dist/test-span-collector.cjs +70 -72
- package/dist/test-span-collector.cjs.map +1 -1
- package/dist/test-span-collector.d.cts +25 -43
- package/dist/test-span-collector.d.cts.map +1 -0
- package/dist/test-span-collector.d.ts +25 -43
- package/dist/test-span-collector.d.ts.map +1 -0
- package/dist/test-span-collector.js +69 -70
- package/dist/test-span-collector.js.map +1 -1
- package/dist/testing.cjs +389 -278
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +39 -62
- package/dist/testing.d.cts.map +1 -0
- package/dist/testing.d.ts +39 -62
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +386 -265
- package/dist/testing.js.map +1 -1
- package/dist/trace-context-Cijqoi6e.d.cts +212 -0
- package/dist/trace-context-Cijqoi6e.d.cts.map +1 -0
- package/dist/trace-context-Cijqoi6e.d.ts +212 -0
- package/dist/trace-context-Cijqoi6e.d.ts.map +1 -0
- package/dist/trace-helpers.cjs +634 -54
- package/dist/trace-helpers.cjs.map +1 -1
- package/dist/trace-helpers.d.cts +17 -49
- package/dist/trace-helpers.d.cts.map +1 -0
- package/dist/trace-helpers.d.ts +17 -49
- package/dist/trace-helpers.d.ts.map +1 -0
- package/dist/trace-helpers.js +624 -3
- package/dist/trace-helpers.js.map +1 -1
- package/dist/tracer-provider.cjs +227 -16
- package/dist/tracer-provider.cjs.map +1 -1
- package/dist/tracer-provider.d.cts +5 -4
- package/dist/tracer-provider.d.cts.map +1 -0
- package/dist/tracer-provider.d.ts +5 -4
- package/dist/tracer-provider.d.ts.map +1 -0
- package/dist/tracer-provider.js +227 -2
- package/dist/tracer-provider.js.map +1 -1
- package/dist/track-3HY4NGV-.cjs +1212 -0
- package/dist/track-3HY4NGV-.cjs.map +1 -0
- package/dist/track-nsKVy-pj.js +1111 -0
- package/dist/track-nsKVy-pj.js.map +1 -0
- package/dist/validate.cjs +178 -115
- package/dist/validate.cjs.map +1 -1
- package/dist/validate.d.cts +40 -64
- package/dist/validate.d.cts.map +1 -0
- package/dist/validate.d.ts +40 -64
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +177 -113
- package/dist/validate.js.map +1 -1
- package/dist/validation-attributes.cjs +42 -17
- package/dist/validation-attributes.cjs.map +1 -1
- package/dist/validation-attributes.d.cts +13 -20
- package/dist/validation-attributes.d.cts.map +1 -0
- package/dist/validation-attributes.d.ts +13 -20
- package/dist/validation-attributes.d.ts.map +1 -0
- package/dist/validation-attributes.js +40 -2
- package/dist/validation-attributes.js.map +1 -1
- package/dist/webhook.cjs +286 -256
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +157 -192
- package/dist/webhook.d.cts.map +1 -0
- package/dist/webhook.d.ts +157 -192
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +285 -254
- package/dist/webhook.js.map +1 -1
- package/dist/workflow-distributed.cjs +498 -412
- package/dist/workflow-distributed.cjs.map +1 -1
- package/dist/workflow-distributed.d.cts +163 -173
- package/dist/workflow-distributed.d.cts.map +1 -0
- package/dist/workflow-distributed.d.ts +163 -173
- package/dist/workflow-distributed.d.ts.map +1 -0
- package/dist/workflow-distributed.js +497 -410
- package/dist/workflow-distributed.js.map +1 -1
- package/dist/workflow.cjs +405 -40
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +78 -131
- package/dist/workflow.d.cts.map +1 -0
- package/dist/workflow.d.ts +78 -131
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +403 -21
- package/dist/workflow.js.map +1 -1
- package/dist/yaml-config-B3dQ82GR.cjs +272 -0
- package/dist/yaml-config-B3dQ82GR.cjs.map +1 -0
- package/dist/yaml-config.cjs +5 -24
- package/dist/yaml-config.d.cts +30 -64
- package/dist/yaml-config.d.cts.map +1 -0
- package/dist/yaml-config.d.ts +30 -64
- package/dist/yaml-config.d.ts.map +1 -0
- package/dist/yaml-config.js +226 -7
- package/dist/yaml-config.js.map +1 -1
- package/package.json +4 -4
- package/skills/analyze-traces/SKILL.md +14 -12
- package/skills/review-otel-patterns/SKILL.md +4 -2
- package/skills/tune-sampling/SKILL.md +8 -3
- package/src/attributes/builders.ts +2 -20
- package/src/attributes/index.ts +0 -1
- package/src/attributes/registry.ts +2 -9
- package/src/attributes/types.ts +0 -8
- package/src/index.ts +7 -41
- package/src/request-logger.test.ts +53 -1
- package/src/request-logger.ts +58 -0
- package/src/semantic-helpers.test.ts +2 -87
- package/src/semantic-helpers.ts +0 -146
- package/src/validate.test.ts +3 -1
- package/src/validate.ts +9 -3
- package/dist/attributes.cjs.map +0 -1
- package/dist/attributes.js.map +0 -1
- package/dist/chunk-2ZKEORFN.cjs +0 -14
- package/dist/chunk-2ZKEORFN.cjs.map +0 -1
- package/dist/chunk-3QXBFGKP.js +0 -344
- package/dist/chunk-3QXBFGKP.js.map +0 -1
- package/dist/chunk-454CH4OV.js +0 -744
- package/dist/chunk-454CH4OV.js.map +0 -1
- package/dist/chunk-4A53YIAX.js +0 -180
- package/dist/chunk-4A53YIAX.js.map +0 -1
- package/dist/chunk-4IFSYQVX.js +0 -337
- package/dist/chunk-4IFSYQVX.js.map +0 -1
- package/dist/chunk-4P6ZOARG.cjs +0 -33
- package/dist/chunk-4P6ZOARG.cjs.map +0 -1
- package/dist/chunk-55ER2KD5.js +0 -228
- package/dist/chunk-55ER2KD5.js.map +0 -1
- package/dist/chunk-5ZN622AO.js +0 -73
- package/dist/chunk-5ZN622AO.js.map +0 -1
- package/dist/chunk-66YJ66GG.js +0 -1021
- package/dist/chunk-66YJ66GG.js.map +0 -1
- package/dist/chunk-6S5RUKU3.cjs +0 -347
- package/dist/chunk-6S5RUKU3.cjs.map +0 -1
- package/dist/chunk-6UQRVUN3.js +0 -222
- package/dist/chunk-6UQRVUN3.js.map +0 -1
- package/dist/chunk-7552UTQW.js +0 -11
- package/dist/chunk-7552UTQW.js.map +0 -1
- package/dist/chunk-7EQ4G4SI.cjs +0 -146
- package/dist/chunk-7EQ4G4SI.cjs.map +0 -1
- package/dist/chunk-7SAWIN74.js +0 -285
- package/dist/chunk-7SAWIN74.js.map +0 -1
- package/dist/chunk-A4E5AQFK.js +0 -30
- package/dist/chunk-A4E5AQFK.js.map +0 -1
- package/dist/chunk-ALPYR2GC.js +0 -1061
- package/dist/chunk-ALPYR2GC.js.map +0 -1
- package/dist/chunk-B7SWBE4P.cjs +0 -799
- package/dist/chunk-B7SWBE4P.cjs.map +0 -1
- package/dist/chunk-BZHG5IZ4.js +0 -73
- package/dist/chunk-BZHG5IZ4.js.map +0 -1
- package/dist/chunk-CEAQK2QY.cjs +0 -32
- package/dist/chunk-CEAQK2QY.cjs.map +0 -1
- package/dist/chunk-CMHVQR6P.js +0 -170
- package/dist/chunk-CMHVQR6P.js.map +0 -1
- package/dist/chunk-CU6IDACR.cjs +0 -224
- package/dist/chunk-CU6IDACR.cjs.map +0 -1
- package/dist/chunk-D4TM63S3.js +0 -795
- package/dist/chunk-D4TM63S3.js.map +0 -1
- package/dist/chunk-DCEDJQGG.js +0 -28
- package/dist/chunk-DCEDJQGG.js.map +0 -1
- package/dist/chunk-DPSA4QLA.js +0 -344
- package/dist/chunk-DPSA4QLA.js.map +0 -1
- package/dist/chunk-E6TERL5O.cjs +0 -23
- package/dist/chunk-E6TERL5O.cjs.map +0 -1
- package/dist/chunk-EE6CPXKH.cjs +0 -164
- package/dist/chunk-EE6CPXKH.cjs.map +0 -1
- package/dist/chunk-EOFB7XCL.cjs +0 -837
- package/dist/chunk-EOFB7XCL.cjs.map +0 -1
- package/dist/chunk-ESLWRGAG.cjs +0 -92
- package/dist/chunk-ESLWRGAG.cjs.map +0 -1
- package/dist/chunk-ESMHTKLJ.cjs +0 -206
- package/dist/chunk-ESMHTKLJ.cjs.map +0 -1
- package/dist/chunk-FMTHVSYY.cjs +0 -1039
- package/dist/chunk-FMTHVSYY.cjs.map +0 -1
- package/dist/chunk-FU6R566Y.cjs +0 -236
- package/dist/chunk-FU6R566Y.cjs.map +0 -1
- package/dist/chunk-GYR5K654.js +0 -91
- package/dist/chunk-GYR5K654.js.map +0 -1
- package/dist/chunk-HA2WBOGQ.js +0 -57
- package/dist/chunk-HA2WBOGQ.js.map +0 -1
- package/dist/chunk-HT5JQKN2.js +0 -118
- package/dist/chunk-HT5JQKN2.js.map +0 -1
- package/dist/chunk-INJD3G4K.cjs +0 -340
- package/dist/chunk-INJD3G4K.cjs.map +0 -1
- package/dist/chunk-IOYFAFHJ.cjs +0 -95
- package/dist/chunk-IOYFAFHJ.cjs.map +0 -1
- package/dist/chunk-J5QENANM.js +0 -87
- package/dist/chunk-J5QENANM.js.map +0 -1
- package/dist/chunk-J7VGRIAJ.js +0 -64
- package/dist/chunk-J7VGRIAJ.js.map +0 -1
- package/dist/chunk-KFOHQK7X.js +0 -144
- package/dist/chunk-KFOHQK7X.js.map +0 -1
- package/dist/chunk-KIL5CUN6.js +0 -31
- package/dist/chunk-KIL5CUN6.js.map +0 -1
- package/dist/chunk-KYXZS3EA.cjs +0 -100
- package/dist/chunk-KYXZS3EA.cjs.map +0 -1
- package/dist/chunk-LITNXTTT.js +0 -3
- package/dist/chunk-LITNXTTT.js.map +0 -1
- package/dist/chunk-LVIPBYFE.js +0 -157
- package/dist/chunk-LVIPBYFE.js.map +0 -1
- package/dist/chunk-M3LFHHTN.cjs +0 -764
- package/dist/chunk-M3LFHHTN.cjs.map +0 -1
- package/dist/chunk-N25JDZSC.js +0 -95
- package/dist/chunk-N25JDZSC.js.map +0 -1
- package/dist/chunk-NEIB3TLD.cjs +0 -360
- package/dist/chunk-NEIB3TLD.cjs.map +0 -1
- package/dist/chunk-NENU7E6V.cjs +0 -344
- package/dist/chunk-NENU7E6V.cjs.map +0 -1
- package/dist/chunk-NVAI5CCN.cjs +0 -39
- package/dist/chunk-NVAI5CCN.cjs.map +0 -1
- package/dist/chunk-NZ72VDNY.cjs +0 -4
- package/dist/chunk-NZ72VDNY.cjs.map +0 -1
- package/dist/chunk-OPPXYVEZ.cjs +0 -131
- package/dist/chunk-OPPXYVEZ.cjs.map +0 -1
- package/dist/chunk-Q4EULJQY.js +0 -35
- package/dist/chunk-Q4EULJQY.js.map +0 -1
- package/dist/chunk-QF7ARNUM.js +0 -339
- package/dist/chunk-QF7ARNUM.js.map +0 -1
- package/dist/chunk-QWW3E3JM.cjs +0 -178
- package/dist/chunk-QWW3E3JM.cjs.map +0 -1
- package/dist/chunk-R7QYGZUP.cjs +0 -1075
- package/dist/chunk-R7QYGZUP.cjs.map +0 -1
- package/dist/chunk-RUPKBKUF.js +0 -352
- package/dist/chunk-RUPKBKUF.js.map +0 -1
- package/dist/chunk-SEO6NAQT.js +0 -14
- package/dist/chunk-SEO6NAQT.js.map +0 -1
- package/dist/chunk-T4B5LB6E.cjs +0 -66
- package/dist/chunk-T4B5LB6E.cjs.map +0 -1
- package/dist/chunk-T5WRA76K.cjs +0 -32
- package/dist/chunk-T5WRA76K.cjs.map +0 -1
- package/dist/chunk-T7JO2TCP.js +0 -1233
- package/dist/chunk-T7JO2TCP.js.map +0 -1
- package/dist/chunk-TC5ZPWM4.cjs +0 -289
- package/dist/chunk-TC5ZPWM4.cjs.map +0 -1
- package/dist/chunk-TQ5UWA7S.js +0 -26
- package/dist/chunk-TQ5UWA7S.js.map +0 -1
- package/dist/chunk-UIKYE2QZ.js +0 -833
- package/dist/chunk-UIKYE2QZ.js.map +0 -1
- package/dist/chunk-UNPLAVE7.js +0 -21
- package/dist/chunk-UNPLAVE7.js.map +0 -1
- package/dist/chunk-UY3UYPBZ.cjs +0 -77
- package/dist/chunk-UY3UYPBZ.cjs.map +0 -1
- package/dist/chunk-V7UBMJAB.cjs +0 -1242
- package/dist/chunk-V7UBMJAB.cjs.map +0 -1
- package/dist/chunk-VH77IPJN.cjs +0 -358
- package/dist/chunk-VH77IPJN.cjs.map +0 -1
- package/dist/chunk-VQTCQKHQ.cjs +0 -17
- package/dist/chunk-VQTCQKHQ.cjs.map +0 -1
- package/dist/chunk-WGWSHJ2N.js +0 -38
- package/dist/chunk-WGWSHJ2N.js.map +0 -1
- package/dist/chunk-WJH6IYU2.cjs +0 -32
- package/dist/chunk-WJH6IYU2.cjs.map +0 -1
- package/dist/chunk-YREV3LGG.cjs +0 -61
- package/dist/chunk-YREV3LGG.cjs.map +0 -1
- package/dist/chunk-YTXEZ4SD.cjs +0 -77
- package/dist/chunk-YTXEZ4SD.cjs.map +0 -1
- package/dist/chunk-ZNMBW67B.cjs +0 -40
- package/dist/chunk-ZNMBW67B.cjs.map +0 -1
- package/dist/correlation-id.cjs.map +0 -1
- package/dist/correlation-id.js.map +0 -1
- package/dist/define-event-BL6Li7CM.d.ts +0 -23
- package/dist/define-event-ClP3T1Jx.d.cts +0 -23
- package/dist/event-subscriber.cjs.map +0 -1
- package/dist/event-subscriber.js.map +0 -1
- package/dist/event.cjs.map +0 -1
- package/dist/event.js.map +0 -1
- package/dist/exporters.cjs.map +0 -1
- package/dist/exporters.js.map +0 -1
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.js.map +0 -1
- package/dist/init-DIowiiCh.d.ts +0 -1167
- package/dist/init-j-A1zI16.d.cts +0 -1167
- package/dist/processors.cjs.map +0 -1
- package/dist/processors.js.map +0 -1
- package/dist/trace-context-DbGKd1Rn.d.cts +0 -213
- package/dist/trace-context-DbGKd1Rn.d.ts +0 -213
- package/dist/utils-BahBCFtJ.d.cts +0 -712
- package/dist/utils-CLKwaUlG.d.ts +0 -712
- package/dist/yaml-config.cjs.map +0 -1
- package/src/gen-ai-cost.test.ts +0 -81
- package/src/gen-ai-cost.ts +0 -145
- package/src/gen-ai-events.test.ts +0 -135
- package/src/gen-ai-events.ts +0 -208
- package/src/gen-ai-metrics.test.ts +0 -96
- package/src/gen-ai-metrics.ts +0 -128
package/dist/yaml-config.js
CHANGED
|
@@ -1,8 +1,227 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { AdaptiveSampler, AlwaysSampler, NeverSampler, RandomSampler } from "./sampling.js";
|
|
2
|
+
import { t as requireModule } from "./node-require-Db1oDpLj.js";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
//#region src/yaml-config.ts
|
|
7
|
+
/**
|
|
8
|
+
* YAML configuration loader for autotel
|
|
9
|
+
*
|
|
10
|
+
* Supports:
|
|
11
|
+
* - Auto-discovery of autotel.yaml in cwd
|
|
12
|
+
* - AUTOTEL_CONFIG_FILE env var override
|
|
13
|
+
* - Environment variable substitution: ${env:VAR} and ${env:VAR:-default}
|
|
14
|
+
*
|
|
15
|
+
* @example Auto-discovery
|
|
16
|
+
* ```yaml
|
|
17
|
+
* # autotel.yaml in project root
|
|
18
|
+
* service:
|
|
19
|
+
* name: my-service
|
|
20
|
+
* exporter:
|
|
21
|
+
* endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example Explicit path
|
|
25
|
+
* ```bash
|
|
26
|
+
* AUTOTEL_CONFIG_FILE=./config/otel.yaml tsx --import autotel/auto src/index.ts
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Lazy-load yaml parser (optional peer dependency)
|
|
31
|
+
* Only loads when a YAML config file is actually found
|
|
32
|
+
*/
|
|
33
|
+
function loadYamlParser() {
|
|
34
|
+
try {
|
|
35
|
+
return requireModule("yaml").parse;
|
|
36
|
+
} catch {
|
|
37
|
+
throw new Error("YAML parser not found. Install with: pnpm add yaml");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Environment variable substitution regex
|
|
42
|
+
* Matches ${env:VAR_NAME} and ${env:VAR_NAME:-default}
|
|
43
|
+
*/
|
|
44
|
+
const ENV_VAR_PATTERN = /\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g;
|
|
45
|
+
/**
|
|
46
|
+
* Substitute ${env:VAR} and ${env:VAR:-default} in a string
|
|
47
|
+
*
|
|
48
|
+
* @param value - String potentially containing env var references
|
|
49
|
+
* @returns String with env vars substituted
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* substituteEnvVars('${env:NODE_ENV:-development}')
|
|
53
|
+
* // Returns 'production' if NODE_ENV=production, else 'development'
|
|
54
|
+
*/
|
|
55
|
+
function substituteEnvVars(value) {
|
|
56
|
+
return value.replaceAll(ENV_VAR_PATTERN, (_match, varName, defaultValue) => {
|
|
57
|
+
const envValue = process.env[varName];
|
|
58
|
+
if (envValue !== void 0) return envValue;
|
|
59
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
60
|
+
console.warn(`[autotel] Environment variable ${varName} not set and no default provided`);
|
|
61
|
+
return "";
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Recursively substitute env vars in an object
|
|
66
|
+
*
|
|
67
|
+
* @param obj - Object to process
|
|
68
|
+
* @returns Object with all string values having env vars substituted
|
|
69
|
+
*/
|
|
70
|
+
function substituteEnvVarsDeep(obj) {
|
|
71
|
+
if (typeof obj === "string") return substituteEnvVars(obj);
|
|
72
|
+
if (Array.isArray(obj)) return obj.map((item) => substituteEnvVarsDeep(item));
|
|
73
|
+
if (obj && typeof obj === "object") {
|
|
74
|
+
const result = {};
|
|
75
|
+
for (const [key, value] of Object.entries(obj)) result[key] = substituteEnvVarsDeep(value);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
return obj;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Find YAML config file path
|
|
82
|
+
*
|
|
83
|
+
* Priority:
|
|
84
|
+
* 1. AUTOTEL_CONFIG_FILE env var (explicit path)
|
|
85
|
+
* 2. autotel.yaml in cwd (convention)
|
|
86
|
+
* 3. autotel.yml in cwd (alternative extension)
|
|
87
|
+
*
|
|
88
|
+
* @returns File path if found, null otherwise
|
|
89
|
+
*/
|
|
90
|
+
function findConfigFile() {
|
|
91
|
+
const envPath = process.env.AUTOTEL_CONFIG_FILE;
|
|
92
|
+
if (envPath) {
|
|
93
|
+
const resolved = path.resolve(envPath);
|
|
94
|
+
if (existsSync(resolved)) return resolved;
|
|
95
|
+
console.warn(`[autotel] Config file not found: ${envPath}`);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const conventionPath = path.resolve(process.cwd(), "autotel.yaml");
|
|
99
|
+
if (existsSync(conventionPath)) return conventionPath;
|
|
100
|
+
const altPath = path.resolve(process.cwd(), "autotel.yml");
|
|
101
|
+
if (existsSync(altPath)) return altPath;
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convert YAML config structure to AutotelConfig
|
|
106
|
+
*
|
|
107
|
+
* @param yaml - Parsed and env-substituted YAML config
|
|
108
|
+
* @returns Partial AutotelConfig ready for merging
|
|
109
|
+
*/
|
|
110
|
+
function yamlToAutotelConfig(yaml) {
|
|
111
|
+
const config = {};
|
|
112
|
+
if (yaml.service?.name) config.service = yaml.service.name;
|
|
113
|
+
if (yaml.service?.version) config.version = yaml.service.version;
|
|
114
|
+
if (yaml.service?.environment) config.environment = yaml.service.environment;
|
|
115
|
+
if (yaml.exporter?.endpoint) config.endpoint = yaml.exporter.endpoint;
|
|
116
|
+
if (yaml.exporter?.protocol) config.protocol = yaml.exporter.protocol;
|
|
117
|
+
if (yaml.exporter?.headers) config.headers = yaml.exporter.headers;
|
|
118
|
+
if (yaml.resource) config.resourceAttributes = yaml.resource;
|
|
119
|
+
if (yaml.autoInstrumentations) config.autoInstrumentations = yaml.autoInstrumentations;
|
|
120
|
+
if (yaml.debug !== void 0) config.debug = yaml.debug;
|
|
121
|
+
if (yaml.sampling?.preset) {
|
|
122
|
+
warnOnIgnoredPresetOverrides(yaml.sampling);
|
|
123
|
+
config.sampling = yaml.sampling.preset;
|
|
124
|
+
} else {
|
|
125
|
+
const sampler = createSamplerFromYaml(yaml.sampling);
|
|
126
|
+
if (sampler) config.sampler = sampler;
|
|
127
|
+
}
|
|
128
|
+
return config;
|
|
129
|
+
}
|
|
130
|
+
function createSamplerFromYaml(sampling) {
|
|
131
|
+
if (!sampling) return void 0;
|
|
132
|
+
if (sampling.preset) return void 0;
|
|
133
|
+
const type = sampling.type ?? "adaptive";
|
|
134
|
+
try {
|
|
135
|
+
switch (type) {
|
|
136
|
+
case "adaptive": return new AdaptiveSampler({
|
|
137
|
+
baselineSampleRate: sampling.baseline_rate,
|
|
138
|
+
alwaysSampleErrors: sampling.always_sample_errors,
|
|
139
|
+
alwaysSampleSlow: sampling.always_sample_slow,
|
|
140
|
+
slowThresholdMs: sampling.slow_threshold_ms
|
|
141
|
+
});
|
|
142
|
+
case "always_on": return new AlwaysSampler();
|
|
143
|
+
case "always_off": return new NeverSampler();
|
|
144
|
+
case "ratio":
|
|
145
|
+
if (sampling.ratio === void 0) {
|
|
146
|
+
console.warn("[autotel] sampling.ratio missing in YAML sampling config. Falling back to adaptive sampler.");
|
|
147
|
+
return new AdaptiveSampler();
|
|
148
|
+
}
|
|
149
|
+
return new RandomSampler(sampling.ratio);
|
|
150
|
+
default:
|
|
151
|
+
console.warn(`[autotel] Unknown sampling type "${type}" in YAML config. Falling back to defaults.`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.warn(`[autotel] Failed to configure sampling from YAML: ${error instanceof Error ? error.message : String(error)}`);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function warnOnIgnoredPresetOverrides(sampling) {
|
|
160
|
+
const ignoredFields = [
|
|
161
|
+
"type",
|
|
162
|
+
"ratio",
|
|
163
|
+
"baseline_rate",
|
|
164
|
+
"always_sample_errors",
|
|
165
|
+
"always_sample_slow",
|
|
166
|
+
"slow_threshold_ms"
|
|
167
|
+
].filter((field) => sampling[field] !== void 0);
|
|
168
|
+
if (ignoredFields.length === 0) return;
|
|
169
|
+
console.warn(`[autotel] sampling.preset="${sampling.preset}" ignores these YAML fields: ${ignoredFields.join(", ")}. Use the programmatic API with sampler or samplingPresets.*(...) for tuned presets.`);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Load and parse YAML config file (auto-discovery)
|
|
173
|
+
*
|
|
174
|
+
* Automatically finds and loads autotel.yaml or uses AUTOTEL_CONFIG_FILE.
|
|
175
|
+
* Returns null if no config file found (not an error - YAML config is optional).
|
|
176
|
+
*
|
|
177
|
+
* @returns Partial AutotelConfig or null if no config file found
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* const yamlConfig = loadYamlConfig();
|
|
181
|
+
* if (yamlConfig) {
|
|
182
|
+
* init({ ...yamlConfig, debug: true });
|
|
183
|
+
* }
|
|
184
|
+
*/
|
|
185
|
+
function loadYamlConfig() {
|
|
186
|
+
const filePath = findConfigFile();
|
|
187
|
+
if (!filePath) return null;
|
|
188
|
+
try {
|
|
189
|
+
const content = readFileSync(filePath, "utf8");
|
|
190
|
+
return yamlToAutotelConfig(substituteEnvVarsDeep(loadYamlParser()(content)));
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.error(`[autotel] Failed to load YAML config from ${filePath}:`, error);
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Load YAML config from a specific file path
|
|
198
|
+
*
|
|
199
|
+
* Unlike loadYamlConfig(), this throws if the file cannot be read.
|
|
200
|
+
*
|
|
201
|
+
* @param filePath - Path to YAML config file
|
|
202
|
+
* @returns Partial AutotelConfig
|
|
203
|
+
* @throws Error if file cannot be read or parsed
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* import { loadYamlConfigFromFile } from 'autotel/yaml';
|
|
207
|
+
* import { init } from 'autotel';
|
|
208
|
+
*
|
|
209
|
+
* const config = loadYamlConfigFromFile('./config/otel.yaml');
|
|
210
|
+
* init({ ...config, debug: true });
|
|
211
|
+
*/
|
|
212
|
+
function loadYamlConfigFromFile(filePath) {
|
|
213
|
+
const content = readFileSync(path.resolve(filePath), "utf8");
|
|
214
|
+
return yamlToAutotelConfig(substituteEnvVarsDeep(loadYamlParser()(content)));
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Check if a YAML config file exists (without loading it)
|
|
218
|
+
*
|
|
219
|
+
* @returns true if a config file would be found by loadYamlConfig()
|
|
220
|
+
*/
|
|
221
|
+
function hasYamlConfig() {
|
|
222
|
+
return findConfigFile() !== null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
//#endregion
|
|
226
|
+
export { hasYamlConfig, loadYamlConfig, loadYamlConfigFromFile };
|
|
8
227
|
//# sourceMappingURL=yaml-config.js.map
|
package/dist/yaml-config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"yaml-config.js"}
|
|
1
|
+
{"version":3,"file":"yaml-config.js","names":[],"sources":["../src/yaml-config.ts"],"sourcesContent":["/**\n * YAML configuration loader for autotel\n *\n * Supports:\n * - Auto-discovery of autotel.yaml in cwd\n * - AUTOTEL_CONFIG_FILE env var override\n * - Environment variable substitution: ${env:VAR} and ${env:VAR:-default}\n *\n * @example Auto-discovery\n * ```yaml\n * # autotel.yaml in project root\n * service:\n * name: my-service\n * exporter:\n * endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}\n * ```\n *\n * @example Explicit path\n * ```bash\n * AUTOTEL_CONFIG_FILE=./config/otel.yaml tsx --import autotel/auto src/index.ts\n * ```\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport path from 'node:path';\nimport type { AutotelConfig } from './init';\nimport {\n AdaptiveSampler,\n AlwaysSampler,\n NeverSampler,\n RandomSampler,\n type SamplingPreset,\n} from './sampling';\n\n/**\n * Lazy-load yaml parser (optional peer dependency)\n * Only loads when a YAML config file is actually found\n */\nimport { requireModule } from './node-require';\n\nfunction loadYamlParser(): (content: string) => unknown {\n try {\n const mod = requireModule<{ parse: (content: string) => unknown }>('yaml');\n return mod.parse;\n } catch {\n throw new Error('YAML parser not found. Install with: pnpm add yaml');\n }\n}\n\n/**\n * YAML config structure\n * Maps to AutotelConfig with user-friendly naming\n */\nexport interface YamlConfig {\n service?: {\n name?: string;\n version?: string;\n environment?: string;\n };\n exporter?: {\n endpoint?: string;\n protocol?: 'http' | 'grpc';\n headers?: Record<string, string>;\n };\n resource?: Record<string, string | number | boolean>;\n sampling?: {\n preset?: SamplingPreset;\n type?: 'adaptive' | 'always_on' | 'always_off' | 'ratio';\n ratio?: number;\n baseline_rate?: number;\n always_sample_errors?: boolean;\n always_sample_slow?: boolean;\n slow_threshold_ms?: number;\n };\n autoInstrumentations?: string[] | Record<string, { enabled?: boolean }>;\n debug?: boolean;\n}\n\n/**\n * Environment variable substitution regex\n * Matches ${env:VAR_NAME} and ${env:VAR_NAME:-default}\n */\nconst ENV_VAR_PATTERN = /\\$\\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\\}/g;\n\n/**\n * Substitute ${env:VAR} and ${env:VAR:-default} in a string\n *\n * @param value - String potentially containing env var references\n * @returns String with env vars substituted\n *\n * @example\n * substituteEnvVars('${env:NODE_ENV:-development}')\n * // Returns 'production' if NODE_ENV=production, else 'development'\n */\nfunction substituteEnvVars(value: string): string {\n return value.replaceAll(\n ENV_VAR_PATTERN,\n (_match, varName: string, defaultValue?: string) => {\n const envValue = process.env[varName];\n if (envValue !== undefined) return envValue;\n if (defaultValue !== undefined) return defaultValue;\n console.warn(\n `[autotel] Environment variable ${varName} not set and no default provided`,\n );\n return '';\n },\n );\n}\n\n/**\n * Recursively substitute env vars in an object\n *\n * @param obj - Object to process\n * @returns Object with all string values having env vars substituted\n */\nfunction substituteEnvVarsDeep(obj: unknown): unknown {\n if (typeof obj === 'string') {\n return substituteEnvVars(obj);\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => substituteEnvVarsDeep(item));\n }\n if (obj && typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = substituteEnvVarsDeep(value);\n }\n return result;\n }\n return obj;\n}\n\n/**\n * Find YAML config file path\n *\n * Priority:\n * 1. AUTOTEL_CONFIG_FILE env var (explicit path)\n * 2. autotel.yaml in cwd (convention)\n * 3. autotel.yml in cwd (alternative extension)\n *\n * @returns File path if found, null otherwise\n */\nfunction findConfigFile(): string | null {\n // Check env var first (explicit takes priority)\n const envPath = process.env.AUTOTEL_CONFIG_FILE;\n if (envPath) {\n const resolved = path.resolve(envPath);\n if (existsSync(resolved)) return resolved;\n console.warn(`[autotel] Config file not found: ${envPath}`);\n return null;\n }\n\n // Auto-discover autotel.yaml in cwd\n const conventionPath = path.resolve(process.cwd(), 'autotel.yaml');\n if (existsSync(conventionPath)) return conventionPath;\n\n // Also check .yml extension\n const altPath = path.resolve(process.cwd(), 'autotel.yml');\n if (existsSync(altPath)) return altPath;\n\n return null;\n}\n\n/**\n * Convert YAML config structure to AutotelConfig\n *\n * @param yaml - Parsed and env-substituted YAML config\n * @returns Partial AutotelConfig ready for merging\n */\nfunction yamlToAutotelConfig(yaml: YamlConfig): Partial<AutotelConfig> {\n const config: Partial<AutotelConfig> = {};\n\n // Service configuration\n if (yaml.service?.name) config.service = yaml.service.name;\n if (yaml.service?.version) config.version = yaml.service.version;\n if (yaml.service?.environment) config.environment = yaml.service.environment;\n\n // Exporter configuration\n if (yaml.exporter?.endpoint) config.endpoint = yaml.exporter.endpoint;\n if (yaml.exporter?.protocol) config.protocol = yaml.exporter.protocol;\n if (yaml.exporter?.headers) config.headers = yaml.exporter.headers;\n\n // Resource attributes (flattened)\n if (yaml.resource) config.resourceAttributes = yaml.resource;\n\n // Integrations\n if (yaml.autoInstrumentations)\n config.autoInstrumentations = yaml.autoInstrumentations;\n\n // Debug mode\n if (yaml.debug !== undefined) config.debug = yaml.debug;\n\n // Sampling configuration\n if (yaml.sampling?.preset) {\n warnOnIgnoredPresetOverrides(yaml.sampling);\n config.sampling = yaml.sampling.preset;\n } else {\n const sampler = createSamplerFromYaml(yaml.sampling);\n if (sampler) config.sampler = sampler;\n }\n\n return config;\n}\n\nfunction createSamplerFromYaml(\n sampling?: YamlConfig['sampling'],\n): AutotelConfig['sampler'] {\n if (!sampling) return undefined;\n if (sampling.preset) return undefined;\n\n const type = sampling.type ?? 'adaptive';\n\n try {\n switch (type) {\n case 'adaptive': {\n return new AdaptiveSampler({\n baselineSampleRate: sampling.baseline_rate,\n alwaysSampleErrors: sampling.always_sample_errors,\n alwaysSampleSlow: sampling.always_sample_slow,\n slowThresholdMs: sampling.slow_threshold_ms,\n });\n }\n case 'always_on': {\n return new AlwaysSampler();\n }\n case 'always_off': {\n return new NeverSampler();\n }\n case 'ratio': {\n if (sampling.ratio === undefined) {\n console.warn(\n '[autotel] sampling.ratio missing in YAML sampling config. Falling back to adaptive sampler.',\n );\n return new AdaptiveSampler();\n }\n return new RandomSampler(sampling.ratio);\n }\n default: {\n console.warn(\n `[autotel] Unknown sampling type \"${type}\" in YAML config. Falling back to defaults.`,\n );\n return undefined;\n }\n }\n } catch (error) {\n console.warn(\n `[autotel] Failed to configure sampling from YAML: ${error instanceof Error ? error.message : String(error)}`,\n );\n return undefined;\n }\n}\n\nfunction warnOnIgnoredPresetOverrides(\n sampling: NonNullable<YamlConfig['sampling']>,\n): void {\n const ignoredFields = [\n 'type',\n 'ratio',\n 'baseline_rate',\n 'always_sample_errors',\n 'always_sample_slow',\n 'slow_threshold_ms',\n ].filter((field) => sampling[field as keyof typeof sampling] !== undefined);\n\n if (ignoredFields.length === 0) {\n return;\n }\n\n console.warn(\n `[autotel] sampling.preset=\"${sampling.preset}\" ignores these YAML fields: ${ignoredFields.join(', ')}. ` +\n 'Use the programmatic API with sampler or samplingPresets.*(...) for tuned presets.',\n );\n}\n\n/**\n * Load and parse YAML config file (auto-discovery)\n *\n * Automatically finds and loads autotel.yaml or uses AUTOTEL_CONFIG_FILE.\n * Returns null if no config file found (not an error - YAML config is optional).\n *\n * @returns Partial AutotelConfig or null if no config file found\n *\n * @example\n * const yamlConfig = loadYamlConfig();\n * if (yamlConfig) {\n * init({ ...yamlConfig, debug: true });\n * }\n */\nexport function loadYamlConfig(): Partial<AutotelConfig> | null {\n const filePath = findConfigFile();\n if (!filePath) return null;\n\n try {\n const content = readFileSync(filePath, 'utf8');\n const parseYaml = loadYamlParser();\n const rawYaml = parseYaml(content) as YamlConfig;\n const substituted = substituteEnvVarsDeep(rawYaml) as YamlConfig;\n return yamlToAutotelConfig(substituted);\n } catch (error) {\n console.error(\n `[autotel] Failed to load YAML config from ${filePath}:`,\n error,\n );\n return null;\n }\n}\n\n/**\n * Load YAML config from a specific file path\n *\n * Unlike loadYamlConfig(), this throws if the file cannot be read.\n *\n * @param filePath - Path to YAML config file\n * @returns Partial AutotelConfig\n * @throws Error if file cannot be read or parsed\n *\n * @example\n * import { loadYamlConfigFromFile } from 'autotel/yaml';\n * import { init } from 'autotel';\n *\n * const config = loadYamlConfigFromFile('./config/otel.yaml');\n * init({ ...config, debug: true });\n */\nexport function loadYamlConfigFromFile(\n filePath: string,\n): Partial<AutotelConfig> {\n const resolved = path.resolve(filePath);\n const content = readFileSync(resolved, 'utf8');\n const parseYaml = loadYamlParser();\n const rawYaml = parseYaml(content) as YamlConfig;\n const substituted = substituteEnvVarsDeep(rawYaml) as YamlConfig;\n return yamlToAutotelConfig(substituted);\n}\n\n/**\n * Check if a YAML config file exists (without loading it)\n *\n * @returns true if a config file would be found by loadYamlConfig()\n */\nexport function hasYamlConfig(): boolean {\n return findConfigFile() !== null;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Write Once, Observe Anywhere",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -355,7 +355,7 @@
|
|
|
355
355
|
"pino": "^10.3.1",
|
|
356
356
|
"prettier": "^3.8.3",
|
|
357
357
|
"rimraf": "^6.1.3",
|
|
358
|
-
"
|
|
358
|
+
"tsdown": "^0.22.2",
|
|
359
359
|
"tsx": "^4.22.4",
|
|
360
360
|
"typescript": "^6.0.3",
|
|
361
361
|
"typescript-eslint": "^8.60.1",
|
|
@@ -375,9 +375,9 @@
|
|
|
375
375
|
},
|
|
376
376
|
"homepage": "https://github.com/jagreehal/autotel#readme",
|
|
377
377
|
"scripts": {
|
|
378
|
-
"build": "
|
|
378
|
+
"build": "tsdown",
|
|
379
379
|
"ci": "npm run build && npm run check-format && npm run check-exports && npm run lint && npm run test",
|
|
380
|
-
"dev": "
|
|
380
|
+
"dev": "tsdown --watch",
|
|
381
381
|
"lint": "eslint src/**/*.ts",
|
|
382
382
|
"lint:fix": "eslint src/**/*.ts --fix",
|
|
383
383
|
"format": "prettier --write .",
|
|
@@ -90,7 +90,7 @@ Key conventions to recognise:
|
|
|
90
90
|
- **Sequential awaits that should be parallel** — sibling spans run end-to-end instead of overlapping.
|
|
91
91
|
- **N+1 queries** — many short same-named spans (`SELECT * FROM …`) under one parent.
|
|
92
92
|
- **Cold starts** — `faas.coldstart=true` in Workers or Lambda.
|
|
93
|
-
- **Tool retries** — gen-ai spans with `gen_ai.response.
|
|
93
|
+
- **Tool retries** — gen-ai spans with `gen_ai.response.finish_reasons` containing `error` followed by another call.
|
|
94
94
|
|
|
95
95
|
### "Follow this user across services"
|
|
96
96
|
|
|
@@ -137,21 +137,23 @@ init({ service: 'my-app', debug: 'pretty', spanDumpPath: '.autotel/spans' });
|
|
|
137
137
|
|
|
138
138
|
LLM calls produce a parent span (kind `CLIENT`) with children for each tool call:
|
|
139
139
|
|
|
140
|
-
| Attribute
|
|
141
|
-
|
|
|
142
|
-
| `gen_ai.system`
|
|
143
|
-
| `gen_ai.request.model`
|
|
144
|
-
| `gen_ai.usage.input_tokens` / `output_tokens`
|
|
145
|
-
| `gen_ai.usage.
|
|
146
|
-
| `gen_ai.response.
|
|
147
|
-
| `gen_ai.tool.name`
|
|
148
|
-
| `gen_ai.cost.usd`
|
|
140
|
+
| Attribute | Meaning |
|
|
141
|
+
| ---------------------------------------------------------------------- | ---------------------------------------- |
|
|
142
|
+
| `gen_ai.provider.name` (legacy: `gen_ai.system`) | Provider (`openai`, `anthropic`, …) |
|
|
143
|
+
| `gen_ai.request.model` | Model id |
|
|
144
|
+
| `gen_ai.usage.input_tokens` / `output_tokens` | Token count |
|
|
145
|
+
| `gen_ai.usage.cache_read.input_tokens` / `cache_creation.input_tokens` | Cache hits |
|
|
146
|
+
| `gen_ai.response.finish_reasons` | `stop`, `tool_calls`, `length`, `error` |
|
|
147
|
+
| `gen_ai.tool.name` | Tool invoked (on tool-call child spans) |
|
|
148
|
+
| `gen_ai.usage.cost.usd` | Estimated cost (if pricing map provided) |
|
|
149
|
+
|
|
150
|
+
These canonical `gen_ai.*` attributes are emitted by the `autotel-genai` package (third-party instrumentations may still emit the deprecated `gen_ai.system`).
|
|
149
151
|
|
|
150
152
|
Common findings:
|
|
151
153
|
|
|
152
|
-
- High `gen_ai.usage.input_tokens` with low `
|
|
154
|
+
- High `gen_ai.usage.input_tokens` with low `gen_ai.usage.cache_read.input_tokens` → enable prompt caching.
|
|
153
155
|
- Many sequential tool-call spans → consider parallel tool calls if the model supports it.
|
|
154
|
-
- `gen_ai.response.
|
|
156
|
+
- `gen_ai.response.finish_reasons` contains `length` → bump `max_tokens`.
|
|
155
157
|
|
|
156
158
|
## When the trace is missing
|
|
157
159
|
|
|
@@ -385,7 +385,9 @@ Compose them at build time with `composeSpanProcessors([...])` — no boilerplat
|
|
|
385
385
|
|
|
386
386
|
## AI SDK integration (gen-ai semantic conventions)
|
|
387
387
|
|
|
388
|
-
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.
|
|
388
|
+
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.
|
|
389
|
+
|
|
390
|
+
> 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.
|
|
389
391
|
|
|
390
392
|
```typescript
|
|
391
393
|
import { trace } from 'autotel';
|
|
@@ -402,7 +404,7 @@ const handler = trace(async (req) => {
|
|
|
402
404
|
});
|
|
403
405
|
```
|
|
404
406
|
|
|
405
|
-
Captured attributes per call: `gen_ai.
|
|
407
|
+
Captured attributes per call: `gen_ai.provider.name`, `gen_ai.request.model`, `gen_ai.usage.input_tokens` / `output_tokens` / `reasoning.output_tokens` / `cache_read.input_tokens`, `gen_ai.response.finish_reasons`, `gen_ai.response.id`, plus per-tool spans with `gen_ai.tool.name`. Cost estimation (`gen_ai.usage.cost.usd`) comes for free if you pass a pricing map to `withAiTelemetry`.
|
|
406
408
|
|
|
407
409
|
Anti-patterns to detect:
|
|
408
410
|
|
|
@@ -108,7 +108,12 @@ const tail = new TailSamplingProcessor({
|
|
|
108
108
|
|
|
109
109
|
// 4. Always keep AI traces (rare + expensive — full visibility helps)
|
|
110
110
|
if (
|
|
111
|
-
trace.spans.some(
|
|
111
|
+
trace.spans.some(
|
|
112
|
+
(s) =>
|
|
113
|
+
typeof s.attributes['gen_ai.provider.name'] === 'string' ||
|
|
114
|
+
// legacy: third-party instrumentations may still emit gen_ai.system
|
|
115
|
+
typeof s.attributes['gen_ai.system'] === 'string',
|
|
116
|
+
)
|
|
112
117
|
)
|
|
113
118
|
return true;
|
|
114
119
|
|
|
@@ -142,8 +147,8 @@ keep: (trace) => {
|
|
|
142
147
|
const cost = trace.spans.reduce(
|
|
143
148
|
(acc, s) =>
|
|
144
149
|
acc +
|
|
145
|
-
(typeof s.attributes['gen_ai.cost.usd'] === 'number'
|
|
146
|
-
? (s.attributes['gen_ai.cost.usd'] as number)
|
|
150
|
+
(typeof s.attributes['gen_ai.usage.cost.usd'] === 'number'
|
|
151
|
+
? (s.attributes['gen_ai.usage.cost.usd'] as number)
|
|
147
152
|
: 0),
|
|
148
153
|
0,
|
|
149
154
|
);
|
|
@@ -38,7 +38,6 @@ import {
|
|
|
38
38
|
FaaSAttributes,
|
|
39
39
|
FeatureFlagAttributes,
|
|
40
40
|
MessagingAttributes,
|
|
41
|
-
GenAIAttributes,
|
|
42
41
|
RPCAttributes,
|
|
43
42
|
GraphQLAttributes,
|
|
44
43
|
OTelAttributes,
|
|
@@ -477,25 +476,8 @@ export const attrs = {
|
|
|
477
476
|
},
|
|
478
477
|
},
|
|
479
478
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
requestModel: (value: string) => ({
|
|
483
|
-
[GenAIAttributes.requestModel]: value,
|
|
484
|
-
}),
|
|
485
|
-
responseModel: (value: string) => ({
|
|
486
|
-
[GenAIAttributes.responseModel]: value,
|
|
487
|
-
}),
|
|
488
|
-
operationName: (value: 'chat' | 'completion' | 'embedding') => ({
|
|
489
|
-
[GenAIAttributes.operationName]: value,
|
|
490
|
-
}),
|
|
491
|
-
usagePromptTokens: (value: number) => ({
|
|
492
|
-
[GenAIAttributes.usagePromptTokens]: value,
|
|
493
|
-
}),
|
|
494
|
-
usageCompletionTokens: (value: number) => ({
|
|
495
|
-
[GenAIAttributes.usageCompletionTokens]: value,
|
|
496
|
-
}),
|
|
497
|
-
provider: (value: string) => ({ [GenAIAttributes.provider]: value }),
|
|
498
|
-
},
|
|
479
|
+
// GenAI/LLM attribute builders moved to the `autotel-genai` package
|
|
480
|
+
// (canonical `gen_ai.*` semantic conventions).
|
|
499
481
|
|
|
500
482
|
rpc: {
|
|
501
483
|
system: (value: string) => ({ [RPCAttributes.system]: value }),
|
package/src/attributes/index.ts
CHANGED
|
@@ -155,15 +155,8 @@ export const MessagingAttributes = {
|
|
|
155
155
|
consumerGroup: 'messaging.consumer.group' as const,
|
|
156
156
|
} as const;
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
requestModel: 'gen.ai.request.model' as const,
|
|
161
|
-
responseModel: 'gen.ai.response.model' as const,
|
|
162
|
-
operationName: 'gen.ai.operation.name' as const,
|
|
163
|
-
usagePromptTokens: 'gen.ai.usage.prompt_tokens' as const,
|
|
164
|
-
usageCompletionTokens: 'gen.ai.usage.completion_tokens' as const,
|
|
165
|
-
provider: 'gen.ai.provider' as const,
|
|
166
|
-
} as const;
|
|
158
|
+
// GenAI attribute registry moved to the `autotel-genai` package, which uses the
|
|
159
|
+
// canonical `gen_ai.*` namespace (these legacy `gen.ai.*` keys were non-spec).
|
|
167
160
|
|
|
168
161
|
export const RPCAttributes = {
|
|
169
162
|
system: 'rpc.system' as const,
|
package/src/attributes/types.ts
CHANGED
|
@@ -155,14 +155,6 @@ export interface ThreadAttrs {
|
|
|
155
155
|
name?: string;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
export interface GenAIAttrs {
|
|
159
|
-
system?: string;
|
|
160
|
-
requestModel?: string;
|
|
161
|
-
responseModel?: string;
|
|
162
|
-
operationName?: 'chat' | 'completion' | 'embedding';
|
|
163
|
-
provider?: string;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
158
|
export interface RPCAttrs {
|
|
167
159
|
system?: string;
|
|
168
160
|
service?: string;
|
package/src/index.ts
CHANGED
|
@@ -136,6 +136,9 @@ export { flush, shutdown } from './shutdown';
|
|
|
136
136
|
// Request logger
|
|
137
137
|
export {
|
|
138
138
|
getRequestLogger,
|
|
139
|
+
getRequestLoggerSafe,
|
|
140
|
+
createNoopRequestLogger,
|
|
141
|
+
hasRequestContext,
|
|
139
142
|
runWithRequestContext,
|
|
140
143
|
type RequestLogger,
|
|
141
144
|
type RequestLogSnapshot,
|
|
@@ -238,43 +241,9 @@ export {
|
|
|
238
241
|
createObservableGauge,
|
|
239
242
|
} from './metric-helpers';
|
|
240
243
|
|
|
241
|
-
// LLM
|
|
242
|
-
//
|
|
243
|
-
|
|
244
|
-
GEN_AI_DURATION_BUCKETS_SECONDS,
|
|
245
|
-
GEN_AI_TOKEN_USAGE_BUCKETS,
|
|
246
|
-
GEN_AI_COST_USD_BUCKETS,
|
|
247
|
-
genAiMetricViews,
|
|
248
|
-
llmHistogramAdvice,
|
|
249
|
-
} from './gen-ai-metrics';
|
|
250
|
-
|
|
251
|
-
// OTel GenAI span event helpers — record prompt-sent / response-received
|
|
252
|
-
// / retry / tool-call / stream-first-token as timestamped events aligned
|
|
253
|
-
// with the published GenAI semantic conventions.
|
|
254
|
-
export {
|
|
255
|
-
recordPromptSent,
|
|
256
|
-
recordResponseReceived,
|
|
257
|
-
recordRetry,
|
|
258
|
-
recordToolCall,
|
|
259
|
-
recordStreamFirstToken,
|
|
260
|
-
type PromptSentEvent,
|
|
261
|
-
type ResponseReceivedEvent,
|
|
262
|
-
type RetryEvent,
|
|
263
|
-
type ToolCallEvent,
|
|
264
|
-
type StreamFirstTokenEvent,
|
|
265
|
-
} from './gen-ai-events';
|
|
266
|
-
|
|
267
|
-
// Per-model LLM cost estimation — estimate USD cost from token usage and
|
|
268
|
-
// record it as the gen_ai.usage.cost.usd span attribute.
|
|
269
|
-
export {
|
|
270
|
-
estimateLLMCost,
|
|
271
|
-
recordLLMCost,
|
|
272
|
-
MODEL_PRICING,
|
|
273
|
-
GEN_AI_COST_ATTRIBUTE,
|
|
274
|
-
type ModelPricing,
|
|
275
|
-
type TokenUsage,
|
|
276
|
-
type EstimateCostOptions,
|
|
277
|
-
} from './gen-ai-cost';
|
|
244
|
+
// GenAI / LLM instrumentation (cost, token usage, metric buckets, span event
|
|
245
|
+
// helpers, traceLLM) lives in the dedicated `autotel-genai` package — canonical
|
|
246
|
+
// `gen_ai.*` semantic conventions. Core stays generic and AI-free.
|
|
278
247
|
|
|
279
248
|
// Tracer helpers for custom spans
|
|
280
249
|
export {
|
|
@@ -300,13 +269,11 @@ export {
|
|
|
300
269
|
getAutotelTracer,
|
|
301
270
|
} from './tracer-provider';
|
|
302
271
|
|
|
303
|
-
// Semantic convention helpers
|
|
272
|
+
// Semantic convention helpers (GenAI/LLM helpers moved to `autotel-genai`).
|
|
304
273
|
export {
|
|
305
|
-
traceLLM,
|
|
306
274
|
traceDB,
|
|
307
275
|
traceHTTP,
|
|
308
276
|
traceMessaging,
|
|
309
|
-
type LLMConfig,
|
|
310
277
|
type DBConfig,
|
|
311
278
|
type HTTPConfig,
|
|
312
279
|
type MessagingConfig,
|
|
@@ -386,7 +353,6 @@ export {
|
|
|
386
353
|
type K8sAttrs,
|
|
387
354
|
type FaaSAttrs,
|
|
388
355
|
type ThreadAttrs,
|
|
389
|
-
type GenAIAttrs,
|
|
390
356
|
type RPCAttrs,
|
|
391
357
|
type GraphQLAttrs,
|
|
392
358
|
type ClientAttrs,
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import { trace as otelTrace } from '@opentelemetry/api';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
createNoopRequestLogger,
|
|
5
|
+
getRequestLogger,
|
|
6
|
+
getRequestLoggerSafe,
|
|
7
|
+
hasRequestContext,
|
|
8
|
+
runWithRequestContext,
|
|
9
|
+
} from './request-logger';
|
|
4
10
|
import type { TraceContext } from './trace-context';
|
|
5
11
|
|
|
6
12
|
function createMockContext(): TraceContext {
|
|
@@ -491,3 +497,49 @@ describe('getRequestLogger', () => {
|
|
|
491
497
|
});
|
|
492
498
|
});
|
|
493
499
|
});
|
|
500
|
+
|
|
501
|
+
describe('best-effort helpers', () => {
|
|
502
|
+
it('hasRequestContext is false with no ctx, ALS, or active span', () => {
|
|
503
|
+
vi.spyOn(otelTrace, 'getActiveSpan').mockReturnValue(undefined);
|
|
504
|
+
expect(hasRequestContext()).toBe(false);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('hasRequestContext is true when an explicit ctx is passed', () => {
|
|
508
|
+
vi.spyOn(otelTrace, 'getActiveSpan').mockReturnValue(undefined);
|
|
509
|
+
expect(hasRequestContext(createMockContext())).toBe(true);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('hasRequestContext is true inside runWithRequestContext', () => {
|
|
513
|
+
vi.spyOn(otelTrace, 'getActiveSpan').mockReturnValue(undefined);
|
|
514
|
+
runWithRequestContext(createMockContext(), () => {
|
|
515
|
+
expect(hasRequestContext()).toBe(true);
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
it('getRequestLoggerSafe returns null when no context is available', () => {
|
|
520
|
+
vi.spyOn(otelTrace, 'getActiveSpan').mockReturnValue(undefined);
|
|
521
|
+
expect(getRequestLoggerSafe()).toBeNull();
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
it('getRequestLoggerSafe returns a working logger when ctx is provided', () => {
|
|
525
|
+
const ctx = createMockContext();
|
|
526
|
+
const log = getRequestLoggerSafe(ctx);
|
|
527
|
+
expect(log).not.toBeNull();
|
|
528
|
+
log?.set({ user: { id: 'safe-user' } });
|
|
529
|
+
expect(ctx.setAttributes).toHaveBeenCalledWith({ 'user.id': 'safe-user' });
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('createNoopRequestLogger never throws and emits an empty snapshot', () => {
|
|
533
|
+
const log = createNoopRequestLogger();
|
|
534
|
+
expect(() => {
|
|
535
|
+
log.set({ a: 1 });
|
|
536
|
+
log.info('hi', { b: 2 });
|
|
537
|
+
log.warn('careful');
|
|
538
|
+
log.error(new Error('boom'));
|
|
539
|
+
}).not.toThrow();
|
|
540
|
+
expect(log.getContext()).toEqual({});
|
|
541
|
+
const snapshot = log.emitNow();
|
|
542
|
+
expect(snapshot.traceId).toBe('');
|
|
543
|
+
expect(snapshot.context).toEqual({});
|
|
544
|
+
});
|
|
545
|
+
});
|