autotel 2.25.5 → 2.26.1
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 +47 -1
- package/dist/attribute-redacting-processor.cjs +14 -6
- package/dist/attribute-redacting-processor.d.cts +63 -1
- package/dist/attribute-redacting-processor.d.ts +63 -1
- package/dist/attribute-redacting-processor.js +1 -1
- package/dist/attributes.cjs +21 -21
- package/dist/attributes.js +2 -2
- package/dist/auto.cjs +8 -8
- package/dist/auto.js +6 -6
- package/dist/{chunk-RUD7KS4R.js → chunk-3SDILILG.js} +3 -3
- package/dist/{chunk-RUD7KS4R.js.map → chunk-3SDILILG.js.map} +1 -1
- package/dist/{chunk-B33XPEKY.js → chunk-55ER2KD5.js} +4 -4
- package/dist/chunk-55ER2KD5.js.map +1 -0
- package/dist/{chunk-ITYASFHQ.cjs → chunk-563EL6O6.cjs} +153 -15
- package/dist/chunk-563EL6O6.cjs.map +1 -0
- package/dist/{chunk-EEJGUBWV.cjs → chunk-6YGUN7IY.cjs} +5 -5
- package/dist/{chunk-EEJGUBWV.cjs.map → chunk-6YGUN7IY.cjs.map} +1 -1
- package/dist/{chunk-XDKK53OL.js → chunk-A4E5AQFK.js} +3 -3
- package/dist/{chunk-XDKK53OL.js.map → chunk-A4E5AQFK.js.map} +1 -1
- package/dist/{chunk-XB2GITM5.js → chunk-BJ2XPN77.js} +3 -3
- package/dist/{chunk-XB2GITM5.js.map → chunk-BJ2XPN77.js.map} +1 -1
- package/dist/{chunk-KZEC4CHV.cjs → chunk-CEAQK2QY.cjs} +5 -5
- package/dist/{chunk-KZEC4CHV.cjs.map → chunk-CEAQK2QY.cjs.map} +1 -1
- package/dist/chunk-CMNGGTQL.cjs +349 -0
- package/dist/chunk-CMNGGTQL.cjs.map +1 -0
- package/dist/{chunk-VYA6QDNA.js → chunk-DPSA4QLA.js} +4 -2
- package/dist/chunk-DPSA4QLA.js.map +1 -0
- package/dist/{chunk-M4US3P4K.js → chunk-ER43K7ES.js} +3 -3
- package/dist/{chunk-M4US3P4K.js.map → chunk-ER43K7ES.js.map} +1 -1
- package/dist/{chunk-AZ24DJAG.cjs → chunk-FU6R566Y.cjs} +4 -4
- package/dist/chunk-FU6R566Y.cjs.map +1 -0
- package/dist/{chunk-OPTGXEVN.js → chunk-HPUGKUMZ.js} +4 -4
- package/dist/{chunk-OPTGXEVN.js.map → chunk-HPUGKUMZ.js.map} +1 -1
- package/dist/{chunk-XRBP4RYL.cjs → chunk-JKIMEPI2.cjs} +4 -4
- package/dist/{chunk-XRBP4RYL.cjs.map → chunk-JKIMEPI2.cjs.map} +1 -1
- package/dist/{chunk-I6JPSD4R.cjs → chunk-OBWXM4NN.cjs} +9 -9
- package/dist/{chunk-I6JPSD4R.cjs.map → chunk-OBWXM4NN.cjs.map} +1 -1
- package/dist/{chunk-OFPZULMQ.cjs → chunk-OC6X2VIN.cjs} +8 -8
- package/dist/{chunk-OFPZULMQ.cjs.map → chunk-OC6X2VIN.cjs.map} +1 -1
- package/dist/{chunk-QDREXAD7.js → chunk-QC5MNKVF.js} +4 -4
- package/dist/{chunk-QDREXAD7.js.map → chunk-QC5MNKVF.js.map} +1 -1
- package/dist/chunk-TDNKIHKT.js +341 -0
- package/dist/chunk-TDNKIHKT.js.map +1 -0
- package/dist/{chunk-CMUM4JQI.js → chunk-U54FTVFH.js} +3 -3
- package/dist/{chunk-CMUM4JQI.js.map → chunk-U54FTVFH.js.map} +1 -1
- package/dist/{chunk-QQLP4M6W.cjs → chunk-UTZR7P7E.cjs} +36 -36
- package/dist/{chunk-QQLP4M6W.cjs.map → chunk-UTZR7P7E.cjs.map} +1 -1
- package/dist/{chunk-7FIGORWI.cjs → chunk-VH77IPJN.cjs} +4 -2
- package/dist/chunk-VH77IPJN.cjs.map +1 -0
- package/dist/{chunk-MNBAXRVG.js → chunk-W35FVJBC.js} +144 -9
- package/dist/chunk-W35FVJBC.js.map +1 -0
- package/dist/{chunk-A5ZUL2RZ.cjs → chunk-WZOKY3PW.cjs} +13 -13
- package/dist/{chunk-A5ZUL2RZ.cjs.map → chunk-WZOKY3PW.cjs.map} +1 -1
- package/dist/{chunk-MN6PZ4AN.cjs → chunk-YEVCD6DR.cjs} +7 -7
- package/dist/{chunk-MN6PZ4AN.cjs.map → chunk-YEVCD6DR.cjs.map} +1 -1
- package/dist/{chunk-WYP6OOCT.js → chunk-YN7USLHW.js} +3 -3
- package/dist/{chunk-WYP6OOCT.js.map → chunk-YN7USLHW.js.map} +1 -1
- package/dist/decorators.cjs +7 -7
- package/dist/decorators.js +7 -7
- package/dist/event.cjs +10 -10
- package/dist/event.js +7 -7
- package/dist/functional.cjs +14 -14
- package/dist/functional.js +7 -7
- package/dist/index.cjs +214 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +142 -33
- package/dist/index.js.map +1 -1
- package/dist/{init-CIzpC5kZ.d.cts → init-CMuTaFAV.d.cts} +49 -1
- package/dist/{init-C_PiC_Su.d.ts → init-D6JfWEjL.d.ts} +49 -1
- package/dist/instrumentation.cjs +14 -14
- package/dist/instrumentation.js +6 -6
- package/dist/logger.cjs +8 -8
- package/dist/logger.js +1 -1
- package/dist/messaging.cjs +11 -11
- package/dist/messaging.js +8 -8
- package/dist/metric.cjs +1 -1
- package/dist/metric.js +1 -1
- package/dist/sampling.cjs +15 -15
- package/dist/sampling.js +2 -2
- package/dist/semantic-helpers.cjs +12 -12
- package/dist/semantic-helpers.js +8 -8
- package/dist/tail-sampling-processor.cjs +4 -4
- package/dist/tail-sampling-processor.js +3 -3
- package/dist/testing.cjs +1 -1
- package/dist/testing.js +1 -1
- package/dist/webhook.cjs +9 -8
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.js +8 -7
- package/dist/webhook.js.map +1 -1
- package/dist/workflow-distributed.cjs +9 -9
- package/dist/workflow-distributed.js +7 -7
- package/dist/workflow.cjs +12 -12
- package/dist/workflow.js +8 -8
- package/dist/yaml-config.cjs +6 -6
- package/dist/yaml-config.d.cts +1 -1
- package/dist/yaml-config.d.ts +1 -1
- package/dist/yaml-config.js +3 -3
- package/package.json +41 -41
- package/src/attribute-redacting-processor.test.ts +81 -16
- package/src/attribute-redacting-processor.ts +278 -24
- package/src/autotel-logger.ts +2 -2
- package/src/devtools.ts +60 -0
- package/src/hook.mjs +2 -2
- package/src/index.ts +2 -1
- package/src/init.customization.test.ts +81 -0
- package/src/init.ts +188 -3
- package/src/request-logger.test.ts +266 -1
- package/src/request-logger.ts +115 -16
- package/src/shutdown.test.ts +35 -1
- package/src/shutdown.ts +3 -1
- package/src/structured-error.ts +54 -1
- package/dist/chunk-7FIGORWI.cjs.map +0 -1
- package/dist/chunk-AZ24DJAG.cjs.map +0 -1
- package/dist/chunk-B33XPEKY.js.map +0 -1
- package/dist/chunk-ELW34S4C.cjs +0 -173
- package/dist/chunk-ELW34S4C.cjs.map +0 -1
- package/dist/chunk-ITYASFHQ.cjs.map +0 -1
- package/dist/chunk-MNBAXRVG.js.map +0 -1
- package/dist/chunk-SNINLBEE.js +0 -167
- package/dist/chunk-SNINLBEE.js.map +0 -1
- package/dist/chunk-VYA6QDNA.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/baggage-span-processor.ts","../src/redact-values.ts","../src/posthog-logs.ts","../src/env-config.ts","../src/devtools.ts","../src/init.ts"],"names":["propagation","otelContext","requireModule","config","REDACTOR_PRESETS","safeRequire","AlwaysOnSampler","AlwaysOffSampler","TraceIdRatioBasedSampler","ParentBasedSampler","SamplingDecision","OTLPTraceExporterHTTP","OTLPMetricExporterHTTP","OTLPLogExporterHTTP","loadYamlConfig","normalizeAttributeRedactorConfig","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","TailSamplingSpanProcessor","BatchSpanProcessor","SimpleSpanProcessor","PrettyConsoleExporter","ConsoleSpanExporter","CanonicalLogLineProcessor","AttributeRedactingProcessor","SpanNameNormalizingProcessor","FilteringSpanProcessor","PeriodicExportingMetricReader","BatchLogRecordProcessor","resolveSamplingPreset","samplingPresets","NodeSDK"],"mappings":"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","file":"chunk-563EL6O6.cjs","sourcesContent":["/**\n * Span processor that copies baggage entries to span attributes\n *\n * This makes baggage visible in trace UIs without manual attribute setting.\n * Enabled via init({ baggage: true }) or init({ baggage: 'custom-prefix' })\n */\n\nimport type { Span, Context } from '@opentelemetry/api';\nimport { propagation, context as otelContext } from '@opentelemetry/api';\nimport type { SpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-base';\nimport { requireModule } from './node-require';\n\nexport interface BaggageSpanProcessorOptions {\n /**\n * Prefix for baggage attributes\n * @default 'baggage.'\n */\n prefix?: string;\n}\n\n/**\n * Span processor that automatically copies baggage entries to span attributes\n *\n * This makes baggage visible in trace UIs (Jaeger, Grafana, DataDog, etc.)\n * without manually calling ctx.setAttribute() for each baggage entry.\n *\n * @example Enable in init()\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: true // Uses default 'baggage.' prefix\n * });\n *\n * // Now baggage automatically appears as span attributes\n * await withBaggage({\n * baggage: { 'tenant.id': 't1', 'user.id': 'u1' },\n * fn: async () => {\n * // Span has baggage.tenant.id and baggage.user.id attributes!\n * }\n * });\n * ```\n *\n * @example Custom prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: 'ctx' // Uses 'ctx.' prefix\n * });\n * // Creates attributes: ctx.tenant.id, ctx.user.id\n * ```\n */\nexport class BaggageSpanProcessor implements SpanProcessor {\n private readonly prefix: string;\n\n constructor(options: BaggageSpanProcessorOptions = {}) {\n this.prefix = options.prefix ?? 'baggage.';\n }\n\n onStart(span: Span, parentContext: Context): void {\n // Read baggage from parentContext first (spans created with explicit context)\n // Then fall back to active context (spans created without explicit context)\n // Also check getActiveContextWithBaggage() to see baggage set via ctx.setBaggage()\n let baggage = propagation.getBaggage(parentContext);\n if (!baggage) {\n baggage = propagation.getBaggage(otelContext.active());\n }\n // Check stored context from ctx.setBaggage() if still no baggage\n if (!baggage) {\n try {\n const { getActiveContextWithBaggage } = requireModule<{\n getActiveContextWithBaggage: () => Context;\n }>('./trace-context');\n const storedContext = getActiveContextWithBaggage();\n baggage = propagation.getBaggage(storedContext);\n } catch {\n // Fallback if trace-context isn't available\n }\n }\n if (!baggage) return;\n\n // Copy all baggage entries to span attributes\n for (const [key, entry] of baggage.getAllEntries()) {\n span.setAttribute(`${this.prefix}${key}`, entry.value);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onEnd(_span: ReadableSpan): void {\n // No-op - required by SpanProcessor interface\n }\n\n async shutdown(): Promise<void> {\n // No-op\n }\n\n async forceFlush(): Promise<void> {\n // No-op\n }\n}\n","/** Standalone string redaction for use outside the span processor pipeline. */\n\nimport {\n REDACTOR_PRESETS,\n type AttributeRedactorConfig,\n type AttributeRedactorPreset,\n type ValuePatternConfig,\n} from './attribute-redacting-processor';\n\nexport type StringRedactor = (value: string) => string;\nexport function createStringRedactor(\n config: AttributeRedactorConfig | AttributeRedactorPreset,\n): StringRedactor {\n const resolved =\n typeof config === 'string' ? REDACTOR_PRESETS[config] : config;\n const valuePatterns: ValuePatternConfig[] = resolved.valuePatterns ?? [];\n const defaultReplacement = resolved.replacement ?? '[REDACTED]';\n\n return (value: string): string => {\n let result = value;\n for (const { pattern, replacement } of valuePatterns) {\n pattern.lastIndex = 0;\n result = result.replaceAll(pattern, replacement ?? defaultReplacement);\n }\n return result;\n };\n}\n","import type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { safeRequire } from './node-require';\nimport type { StringRedactor } from './redact-values';\n\nexport class RedactingLogRecordProcessor implements LogRecordProcessor {\n constructor(\n private wrapped: LogRecordProcessor,\n private redact: StringRedactor,\n ) {}\n\n onEmit(logRecord: any, context?: any): void {\n if (logRecord.body && typeof logRecord.body === 'string') {\n logRecord.body = this.redact(logRecord.body);\n }\n if (logRecord.attributes) {\n for (const [key, value] of Object.entries(logRecord.attributes)) {\n if (typeof value === 'string') {\n logRecord.attributes[key] = this.redact(value);\n } else if (Array.isArray(value)) {\n logRecord.attributes[key] = value.map((item: unknown) =>\n typeof item === 'string' ? this.redact(item) : item,\n );\n }\n }\n }\n this.wrapped.onEmit(logRecord, context);\n }\n\n shutdown(): Promise<void> {\n return this.wrapped.shutdown();\n }\n\n forceFlush(): Promise<void> {\n return this.wrapped.forceFlush();\n }\n}\n\nexport interface PostHogConfig {\n /** OTLP logs endpoint URL (e.g., https://us.i.posthog.com/i/v1/logs?token=phc_xxx) */\n url: string;\n}\n\n/**\n * Build log record processors for PostHog OTLP logs integration.\n *\n * Resolution order:\n * 1. config.url if provided\n * 2. POSTHOG_LOGS_URL env var\n * 3. Empty array (disabled)\n */\nexport function buildPostHogLogProcessors(\n config: PostHogConfig | undefined,\n stringRedactor?: StringRedactor | null,\n): LogRecordProcessor[] {\n const url = config?.url || process.env.POSTHOG_LOGS_URL;\n if (!url) return [];\n\n const sdkLogs = safeRequire<{\n BatchLogRecordProcessor: new (exporter: unknown) => LogRecordProcessor;\n }>('@opentelemetry/sdk-logs');\n\n const exporterModule = safeRequire<{\n OTLPLogExporter: new (config: { url: string }) => unknown;\n }>('@opentelemetry/exporter-logs-otlp-http');\n\n if (!sdkLogs || !exporterModule) return [];\n\n const exporter = new exporterModule.OTLPLogExporter({ url });\n let processor: LogRecordProcessor = new sdkLogs.BatchLogRecordProcessor(\n exporter,\n );\n if (stringRedactor) {\n processor = new RedactingLogRecordProcessor(processor, stringRedactor);\n }\n\n return [processor];\n}\n","/**\n * Standard OpenTelemetry environment variables\n */\nimport type { Sampler as OtelSampler } from '@opentelemetry/sdk-trace-base';\nimport {\n AlwaysOffSampler,\n AlwaysOnSampler,\n ParentBasedSampler,\n TraceIdRatioBasedSampler,\n} from '@opentelemetry/sdk-trace-base';\n\nexport interface OtelEnvVars {\n OTEL_SERVICE_NAME?: string;\n OTEL_EXPORTER_OTLP_ENDPOINT?: string;\n OTEL_EXPORTER_OTLP_HEADERS?: string;\n OTEL_RESOURCE_ATTRIBUTES?: string;\n OTEL_EXPORTER_OTLP_PROTOCOL?: 'http' | 'grpc';\n OTEL_TRACES_SAMPLER?: string;\n OTEL_TRACES_SAMPLER_ARG?: string;\n}\n\n/**\n * Parsed resource attributes as key-value pairs\n */\nexport interface ResourceAttributes {\n [key: string]: string;\n}\n\n/**\n * Parsed OTLP headers as key-value pairs\n */\nexport interface OtlpHeaders {\n [key: string]: string;\n}\n\n/**\n * Environment-resolved configuration (subset of AutotelConfig)\n * Defined locally to avoid circular dependency with init.ts\n */\nexport interface EnvConfig {\n service?: string;\n endpoint?: string;\n protocol?: 'http' | 'grpc';\n headers?: Record<string, string>;\n resourceAttributes?: Record<string, string>;\n otelSampler?: OtelSampler;\n}\n\n/**\n * Validate URL format\n */\nfunction isValidUrl(urlString: string): boolean {\n try {\n const url = new URL(urlString);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve OpenTelemetry environment variables from process.env\n */\nexport function resolveOtelEnv(): OtelEnvVars {\n const env: OtelEnvVars = {};\n\n // OTEL_SERVICE_NAME - optional string\n if (process.env.OTEL_SERVICE_NAME) {\n const value = process.env.OTEL_SERVICE_NAME.trim();\n if (value) {\n env.OTEL_SERVICE_NAME = value;\n }\n }\n\n // OTEL_EXPORTER_OTLP_ENDPOINT - optional URL\n if (process.env.OTEL_EXPORTER_OTLP_ENDPOINT) {\n const value = process.env.OTEL_EXPORTER_OTLP_ENDPOINT.trim();\n if (value && isValidUrl(value)) {\n env.OTEL_EXPORTER_OTLP_ENDPOINT = value;\n }\n }\n\n // OTEL_EXPORTER_OTLP_HEADERS - optional string\n if (process.env.OTEL_EXPORTER_OTLP_HEADERS) {\n const value = process.env.OTEL_EXPORTER_OTLP_HEADERS.trim();\n if (value) {\n env.OTEL_EXPORTER_OTLP_HEADERS = value;\n }\n }\n\n // OTEL_RESOURCE_ATTRIBUTES - optional string\n if (process.env.OTEL_RESOURCE_ATTRIBUTES) {\n const value = process.env.OTEL_RESOURCE_ATTRIBUTES.trim();\n if (value) {\n env.OTEL_RESOURCE_ATTRIBUTES = value;\n }\n }\n\n // OTEL_EXPORTER_OTLP_PROTOCOL - optional enum ('http' | 'grpc')\n if (process.env.OTEL_EXPORTER_OTLP_PROTOCOL) {\n const value = process.env.OTEL_EXPORTER_OTLP_PROTOCOL.trim().toLowerCase();\n if (value === 'http' || value === 'grpc') {\n env.OTEL_EXPORTER_OTLP_PROTOCOL = value;\n }\n }\n\n if (process.env.OTEL_TRACES_SAMPLER) {\n const value = process.env.OTEL_TRACES_SAMPLER.trim();\n if (value) {\n env.OTEL_TRACES_SAMPLER = value;\n }\n }\n\n if (process.env.OTEL_TRACES_SAMPLER_ARG) {\n const value = process.env.OTEL_TRACES_SAMPLER_ARG.trim();\n if (value) {\n env.OTEL_TRACES_SAMPLER_ARG = value;\n }\n }\n\n return env;\n}\n\nfunction parseRatioSamplerArg(\n samplerName: string,\n samplerArg: string | undefined,\n): number {\n if (samplerArg === undefined) {\n return 1.0;\n }\n\n const ratio = Number(samplerArg);\n if (!Number.isFinite(ratio) || ratio < 0 || ratio > 1) {\n console.error(\n `[autotel] Invalid OTEL_TRACES_SAMPLER_ARG=\"${samplerArg}\" for ${samplerName}. Expected a number in [0..1]. Falling back to 1.0.`,\n );\n return 1.0;\n }\n\n return ratio;\n}\n\nfunction warnOnUnusedSamplerArg(\n samplerName: string,\n samplerArg: string | undefined,\n): void {\n if (samplerArg !== undefined) {\n console.error(\n `[autotel] OTEL_TRACES_SAMPLER_ARG is not used by OTEL_TRACES_SAMPLER=\"${samplerName}\". Ignoring value \"${samplerArg}\".`,\n );\n }\n}\n\nexport function createSamplerFromEnv(\n env: Pick<OtelEnvVars, 'OTEL_TRACES_SAMPLER' | 'OTEL_TRACES_SAMPLER_ARG'>,\n): OtelSampler | undefined {\n const samplerName = env.OTEL_TRACES_SAMPLER;\n if (!samplerName) {\n return undefined;\n }\n\n switch (samplerName) {\n case 'always_on':\n warnOnUnusedSamplerArg(samplerName, env.OTEL_TRACES_SAMPLER_ARG);\n return new AlwaysOnSampler();\n case 'always_off':\n warnOnUnusedSamplerArg(samplerName, env.OTEL_TRACES_SAMPLER_ARG);\n return new AlwaysOffSampler();\n case 'traceidratio':\n return new TraceIdRatioBasedSampler(\n parseRatioSamplerArg(samplerName, env.OTEL_TRACES_SAMPLER_ARG),\n );\n case 'parentbased_always_on':\n warnOnUnusedSamplerArg(samplerName, env.OTEL_TRACES_SAMPLER_ARG);\n return new ParentBasedSampler({ root: new AlwaysOnSampler() });\n case 'parentbased_always_off':\n warnOnUnusedSamplerArg(samplerName, env.OTEL_TRACES_SAMPLER_ARG);\n return new ParentBasedSampler({ root: new AlwaysOffSampler() });\n case 'parentbased_traceidratio':\n return new ParentBasedSampler({\n root: new TraceIdRatioBasedSampler(\n parseRatioSamplerArg(samplerName, env.OTEL_TRACES_SAMPLER_ARG),\n ),\n });\n case 'jaeger_remote':\n case 'parentbased_jaeger_remote':\n case 'xray':\n console.error(\n `[autotel] OTEL_TRACES_SAMPLER=\"${samplerName}\" is not supported yet by autotel. Falling back to the next sampler source.`,\n );\n return undefined;\n default:\n console.error(\n `[autotel] Unknown OTEL_TRACES_SAMPLER=\"${samplerName}\". Falling back to the next sampler source.`,\n );\n return undefined;\n }\n}\n\n/**\n * Parse OTEL_RESOURCE_ATTRIBUTES from comma-separated key=value pairs\n * Example: \"service.version=1.0.0,deployment.environment=production\"\n */\nexport function parseResourceAttributes(\n input: string | undefined,\n): ResourceAttributes {\n if (!input || input.trim() === '') {\n return {};\n }\n\n const attributes: ResourceAttributes = {};\n const pairs = input.split(',');\n\n for (const pair of pairs) {\n const trimmedPair = pair.trim();\n if (!trimmedPair) continue;\n\n const equalIndex = trimmedPair.indexOf('=');\n if (equalIndex === -1) {\n // Invalid format, skip this pair\n continue;\n }\n\n const key = trimmedPair.slice(0, equalIndex).trim();\n const value = trimmedPair.slice(equalIndex + 1).trim();\n\n if (key && value) {\n attributes[key] = value;\n }\n }\n\n return attributes;\n}\n\n/**\n * Parse OTEL_EXPORTER_OTLP_HEADERS from comma-separated key=value pairs\n * Example: \"api-key=secret123,x-custom-header=value\"\n */\nexport function parseOtlpHeaders(input: string | undefined): OtlpHeaders {\n if (!input || input.trim() === '') {\n return {};\n }\n\n const headers: OtlpHeaders = {};\n const pairs = input.split(',');\n\n for (const pair of pairs) {\n const trimmedPair = pair.trim();\n if (!trimmedPair) continue;\n\n const equalIndex = trimmedPair.indexOf('=');\n if (equalIndex === -1) {\n // Invalid format, skip this pair\n continue;\n }\n\n const key = trimmedPair.slice(0, equalIndex).trim();\n const value = trimmedPair.slice(equalIndex + 1).trim();\n\n if (key && value) {\n headers[key] = value;\n }\n }\n\n return headers;\n}\n\n/**\n * Convert resolved environment variables to config\n */\nexport function envToConfig(env: OtelEnvVars): EnvConfig {\n const config: EnvConfig = {};\n\n if (env.OTEL_SERVICE_NAME) {\n config.service = env.OTEL_SERVICE_NAME;\n }\n\n if (env.OTEL_EXPORTER_OTLP_ENDPOINT) {\n config.endpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT;\n }\n\n if (env.OTEL_EXPORTER_OTLP_PROTOCOL) {\n config.protocol = env.OTEL_EXPORTER_OTLP_PROTOCOL;\n }\n\n if (env.OTEL_EXPORTER_OTLP_HEADERS) {\n config.headers = parseOtlpHeaders(env.OTEL_EXPORTER_OTLP_HEADERS);\n }\n\n const resourceAttrs = parseResourceAttributes(env.OTEL_RESOURCE_ATTRIBUTES);\n if (Object.keys(resourceAttrs).length > 0) {\n config.resourceAttributes = resourceAttrs;\n }\n\n const sampler = createSamplerFromEnv(env);\n if (sampler) {\n config.otelSampler = sampler;\n }\n\n return config;\n}\n\n/**\n * Main function to resolve config from environment variables\n */\nexport function resolveConfigFromEnv(): EnvConfig {\n const env = resolveOtelEnv();\n return envToConfig(env);\n}\n","export interface AutotelDevtoolsConfig {\n enabled?: boolean;\n endpoint?: string;\n embedded?: boolean;\n host?: string;\n port?: number;\n verbose?: boolean;\n}\n\nexport interface ResolvedAutotelDevtoolsConfig {\n enabled: boolean;\n endpoint?: string;\n embedded: boolean;\n host: string;\n port: number;\n verbose: boolean;\n}\n\nconst defaultHost = '127.0.0.1';\nconst defaultPort = 4318;\n\nexport function resolveDevtoolsConfig(\n config: boolean | AutotelDevtoolsConfig | undefined,\n): ResolvedAutotelDevtoolsConfig {\n if (!config) {\n return {\n enabled: false,\n endpoint: undefined,\n embedded: false,\n host: defaultHost,\n port: defaultPort,\n verbose: false,\n };\n }\n\n if (config === true) {\n return {\n enabled: true,\n endpoint: `http://${defaultHost}:${defaultPort}`,\n embedded: false,\n host: defaultHost,\n port: defaultPort,\n verbose: false,\n };\n }\n\n const enabled = config.enabled ?? true;\n const host = config.host ?? defaultHost;\n const port = config.port ?? defaultPort;\n const endpoint = config.endpoint ?? `http://${host}:${port}`;\n\n return {\n enabled,\n endpoint: enabled ? endpoint : undefined,\n embedded: enabled && (config.embedded ?? false),\n host,\n port,\n verbose: config.verbose ?? false,\n };\n}\n","/**\n * Simplified initialization for autotel\n *\n * Single init() function with sensible defaults.\n * Replaces initInstrumentation() and separate events config.\n */\n\nimport { NodeSDK } from '@opentelemetry/sdk-node';\nimport type { NodeSDKConfiguration } from '@opentelemetry/sdk-node';\nimport {\n BatchSpanProcessor,\n type SpanProcessor,\n SimpleSpanProcessor,\n ConsoleSpanExporter,\n SamplingDecision,\n type SpanExporter,\n type Sampler as OtelSampler,\n type SamplingResult,\n} from '@opentelemetry/sdk-trace-base';\nimport {\n resourceFromAttributes,\n type Resource,\n} from '@opentelemetry/resources';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions';\nimport type { Sampler, SamplingPreset } from './sampling';\nimport { samplingPresets, resolveSamplingPreset } from './sampling';\nimport type { EventSubscriber } from './event-subscriber';\nimport type { Logger } from './logger';\nimport type { Attributes, Context, SpanKind, Link } from '@opentelemetry/api';\nimport type { ValidationConfig } from './validation';\nimport {\n PeriodicExportingMetricReader,\n type MetricReader,\n} from '@opentelemetry/sdk-metrics';\nimport { OTLPMetricExporter as OTLPMetricExporterHTTP } from '@opentelemetry/exporter-metrics-otlp-http';\nimport { OTLPTraceExporter as OTLPTraceExporterHTTP } from '@opentelemetry/exporter-trace-otlp-http';\nimport { OTLPLogExporter as OTLPLogExporterHTTP } from '@opentelemetry/exporter-logs-otlp-http';\nimport type { PushMetricExporter } from '@opentelemetry/sdk-metrics';\nimport {\n BatchLogRecordProcessor,\n type LogRecordExporter,\n type LogRecordProcessor,\n} from '@opentelemetry/sdk-logs';\nimport {\n buildPostHogLogProcessors,\n RedactingLogRecordProcessor,\n} from './posthog-logs';\nimport { TailSamplingSpanProcessor } from './tail-sampling-processor';\nimport { BaggageSpanProcessor } from './baggage-span-processor';\nimport {\n FilteringSpanProcessor,\n type SpanFilterPredicate,\n} from './filtering-span-processor';\nimport {\n SpanNameNormalizingProcessor,\n type SpanNameNormalizerConfig,\n} from './span-name-normalizer';\nimport {\n AttributeRedactingProcessor,\n normalizeAttributeRedactorConfig,\n type AttributeRedactorConfig,\n type AttributeRedactorPreset,\n} from './attribute-redacting-processor';\nimport { createStringRedactor, type StringRedactor } from './redact-values';\nimport { PrettyConsoleExporter } from './pretty-console-exporter';\nimport { resolveConfigFromEnv } from './env-config';\nimport { loadYamlConfig } from './yaml-config';\nimport { requireModule, safeRequire } from './node-require';\nimport {\n CanonicalLogLineProcessor,\n type CanonicalLogLineOptions,\n} from './processors/canonical-log-line-processor';\nimport type { EventsConfig } from './events-config';\nimport { resolveDevtoolsConfig, type AutotelDevtoolsConfig } from './devtools';\n\n/**\n * Silent logger (no-op) - used as default when user doesn't provide one.\n * Internal autotel logs are silent by default to avoid spam.\n * Users can import { autotelLogger } from 'autotel/logger' to create their own.\n */\nconst silentLogger: Logger = {\n info: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n};\n\n/**\n * Adapts an Autotel Sampler to the OTel SDK Sampler interface.\n */\nfunction toOtelSampler(sampler: Sampler): OtelSampler {\n return {\n shouldSample(\n _context: Context,\n _traceId: string,\n spanName: string,\n _spanKind: SpanKind,\n _attributes: Attributes,\n links: Link[],\n ): SamplingResult {\n const shouldTrace = sampler.shouldSample({\n operationName: spanName,\n args: [],\n links,\n });\n return {\n decision: shouldTrace\n ? SamplingDecision.RECORD_AND_SAMPLED\n : SamplingDecision.NOT_RECORD,\n };\n },\n toString(): string {\n return `AutotelSamplerAdapter`;\n },\n };\n}\n\n// Type imports for exporters\ntype OTLPExporterConfig = {\n url?: string;\n headers?: Record<string, string>;\n timeoutMillis?: number;\n concurrencyLimit?: number;\n};\n\n// Lazy-load gRPC exporters (optional peer dependencies)\nlet OTLPTraceExporterGRPC:\n | (new (config: OTLPExporterConfig) => SpanExporter)\n | undefined;\nlet OTLPMetricExporterGRPC:\n | (new (config: OTLPExporterConfig) => PushMetricExporter)\n | undefined;\nlet OTLPLogExporterGRPC:\n | (new (config: OTLPExporterConfig) => LogRecordExporter)\n | undefined;\n\n/**\n * Helper: Lazy-load gRPC trace exporter\n */\nfunction loadGRPCTraceExporter(): new (\n config: OTLPExporterConfig,\n) => SpanExporter {\n if (OTLPTraceExporterGRPC) return OTLPTraceExporterGRPC;\n\n try {\n // Dynamic import for optional peer dependency\n const grpcModule = requireModule<{\n OTLPTraceExporter: new (config: OTLPExporterConfig) => SpanExporter;\n }>('@opentelemetry/exporter-trace-otlp-grpc');\n OTLPTraceExporterGRPC = grpcModule.OTLPTraceExporter;\n return OTLPTraceExporterGRPC;\n } catch {\n throw new Error(\n 'gRPC trace exporter not found. Install @opentelemetry/exporter-trace-otlp-grpc',\n );\n }\n}\n\n/**\n * Helper: Lazy-load gRPC metric exporter\n */\nfunction loadGRPCMetricExporter(): new (\n config: OTLPExporterConfig,\n) => PushMetricExporter {\n if (OTLPMetricExporterGRPC) return OTLPMetricExporterGRPC;\n\n try {\n // Dynamic import for optional peer dependency\n const grpcModule = requireModule<{\n OTLPMetricExporter: new (\n config: OTLPExporterConfig,\n ) => PushMetricExporter;\n }>('@opentelemetry/exporter-metrics-otlp-grpc');\n OTLPMetricExporterGRPC = grpcModule.OTLPMetricExporter;\n return OTLPMetricExporterGRPC;\n } catch {\n throw new Error(\n 'gRPC metric exporter not found. Install @opentelemetry/exporter-metrics-otlp-grpc',\n );\n }\n}\n\n/**\n * Helper: Create trace exporter based on protocol\n */\nfunction createTraceExporter(\n protocol: 'http' | 'grpc',\n config: OTLPExporterConfig,\n): SpanExporter {\n if (protocol === 'grpc') {\n const Exporter = loadGRPCTraceExporter();\n return new Exporter(config);\n }\n\n // Default: HTTP\n return new OTLPTraceExporterHTTP(config);\n}\n\n/**\n * Helper: Create metric exporter based on protocol\n */\nfunction createMetricExporter(\n protocol: 'http' | 'grpc',\n config: OTLPExporterConfig,\n): PushMetricExporter {\n if (protocol === 'grpc') {\n const Exporter = loadGRPCMetricExporter();\n return new Exporter(config);\n }\n\n // Default: HTTP\n return new OTLPMetricExporterHTTP(config);\n}\n\n/**\n * Helper: Lazy-load gRPC log exporter\n */\nfunction loadGRPCLogExporter(): new (\n config: OTLPExporterConfig,\n) => LogRecordExporter {\n if (OTLPLogExporterGRPC) return OTLPLogExporterGRPC;\n\n try {\n const grpcModule = requireModule<{\n OTLPLogExporter: new (config: OTLPExporterConfig) => LogRecordExporter;\n }>('@opentelemetry/exporter-logs-otlp-grpc');\n OTLPLogExporterGRPC = grpcModule.OTLPLogExporter;\n return OTLPLogExporterGRPC;\n } catch {\n throw new Error(\n 'gRPC log exporter not found. Install @opentelemetry/exporter-logs-otlp-grpc',\n );\n }\n}\n\n/**\n * Helper: Create log exporter based on protocol\n */\nfunction createLogExporter(\n protocol: 'http' | 'grpc',\n config: OTLPExporterConfig,\n): LogRecordExporter {\n if (protocol === 'grpc') {\n const Exporter = loadGRPCLogExporter();\n return new Exporter(config);\n }\n\n // Default: HTTP\n return new OTLPLogExporterHTTP(config);\n}\n\n/**\n * Helper: Resolve protocol from config and environment\n */\nfunction resolveProtocol(configProtocol?: 'http' | 'grpc'): 'http' | 'grpc' {\n // 1. Check config parameter (highest priority)\n if (configProtocol === 'grpc' || configProtocol === 'http') {\n return configProtocol;\n }\n\n // 2. Check OTEL_EXPORTER_OTLP_PROTOCOL env var\n const envProtocol = process.env.OTEL_EXPORTER_OTLP_PROTOCOL;\n if (envProtocol === 'grpc') return 'grpc';\n if (envProtocol === 'http/protobuf' || envProtocol === 'http') return 'http';\n\n // 3. Default to HTTP\n return 'http';\n}\n\n/**\n * Helper: Adjust endpoint URL for protocol\n * gRPC exporters don't need the /v1/traces or /v1/metrics path\n * HTTP exporters need the full path\n */\nfunction formatEndpointUrl(\n endpoint: string,\n signal: 'traces' | 'metrics' | 'logs',\n protocol: 'http' | 'grpc',\n): string {\n if (protocol === 'grpc') {\n // gRPC: strip any paths, return base endpoint\n return endpoint.replace(/\\/(v1\\/)?(traces|metrics|logs)$/, '');\n }\n\n // HTTP: append signal path if not present\n if (!endpoint.endsWith(`/v1/${signal}`)) {\n return `${endpoint}/v1/${signal}`;\n }\n\n return endpoint;\n}\n\n// Built-in logger is created dynamically in init() with service name\n\nexport interface AutotelConfig {\n /** Service name (required) */\n service: string;\n\n /**\n * Local developer UX for autotel-devtools.\n *\n * - `true`: send traces, metrics, and logs to `http://127.0.0.1:4318`\n * - `{ embedded: true }`: attempt to start `autotel-devtools` automatically\n *\n * When enabled:\n * - `endpoint` defaults to the local devtools URL\n * - `logs` default to `true` unless explicitly set\n *\n * This keeps production config unchanged while making local debugging\n * effectively zero-config.\n */\n devtools?: boolean | AutotelDevtoolsConfig;\n\n /** Event subscribers - bring your own (PostHog, Mixpanel, etc.) */\n subscribers?: EventSubscriber[];\n\n /**\n * Additional OpenTelemetry instrumentations to register (raw OTel classes).\n * Useful when you need custom instrumentation configs or instrumentations\n * not covered by autoInstrumentations.\n *\n * **Important:** If you need custom instrumentation configs (like `requireParentSpan: false`),\n * use EITHER manual instrumentations OR autoInstrumentations, not both for the same library.\n * Manual instrumentations always take precedence over auto-instrumentations.\n *\n * @example Manual instrumentations with custom config\n * ```typescript\n * import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'\n *\n * init({\n * service: 'my-app',\n * autoInstrumentations: false, // Disable auto-instrumentations\n * instrumentations: [\n * new MongoDBInstrumentation({\n * requireParentSpan: false // Custom config\n * })\n * ]\n * })\n * ```\n *\n * @example Mix auto + manual (auto for most, manual for specific configs)\n * ```typescript\n * import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'\n *\n * init({\n * service: 'my-app',\n * autoInstrumentations: ['http', 'express'], // Auto for these\n * instrumentations: [\n * new MongoDBInstrumentation({\n * requireParentSpan: false // Manual config for MongoDB\n * })\n * ]\n * })\n * ```\n */\n instrumentations?: NodeSDKConfiguration['instrumentations'];\n\n /**\n * Simple names for auto-instrumentation.\n * Uses @opentelemetry/auto-instrumentations-node (peer dependency).\n *\n * **Important:** If you provide manual instrumentations for the same library,\n * the manual config takes precedence and auto-instrumentation for that library is disabled.\n *\n * @example Enable all auto-instrumentations (simple approach)\n * ```typescript\n * init({\n * service: 'my-app',\n * autoInstrumentations: true // Enable all with defaults\n * })\n * ```\n *\n * @example Enable specific auto-instrumentations\n * ```typescript\n * init({\n * service: 'my-app',\n * autoInstrumentations: ['express', 'pino', 'http']\n * })\n * ```\n *\n * @example Configure specific auto-instrumentations\n * ```typescript\n * init({\n * service: 'my-app',\n * autoInstrumentations: {\n * express: { enabled: true },\n * pino: { enabled: true },\n * http: { enabled: false }\n * }\n * })\n * ```\n *\n * @example Manual config when you need custom settings\n * ```typescript\n * import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'\n *\n * init({\n * service: 'my-app',\n * autoInstrumentations: false, // Use manual control\n * instrumentations: [\n * new MongoDBInstrumentation({\n * requireParentSpan: false // Custom config not available with auto\n * })\n * ]\n * })\n * ```\n */\n autoInstrumentations?:\n | string[]\n | boolean\n | Record<string, { enabled?: boolean }>;\n\n /**\n * OTLP endpoint for traces/metrics/logs\n * Only used if you don't provide custom exporters/processors\n * @default process.env.OTLP_ENDPOINT || 'http://localhost:4318'\n */\n endpoint?: string;\n\n /**\n * Custom span processors for traces (supports multiple processors)\n * Allows you to use any backend: Jaeger, Zipkin, Datadog, New Relic, etc.\n * If not provided, defaults to OTLP with tail sampling\n *\n * @example Multiple processors\n * ```typescript\n * import { JaegerExporter } from '@opentelemetry/exporter-jaeger'\n * import { BatchSpanProcessor, SimpleSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base'\n *\n * init({\n * service: 'my-app',\n * spanProcessors: [\n * new BatchSpanProcessor(new JaegerExporter()),\n * new SimpleSpanProcessor(new ConsoleSpanExporter()) // Debug alongside production\n * ]\n * })\n * ```\n *\n * @example Single processor\n * ```typescript\n * import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\n *\n * init({\n * service: 'my-app',\n * spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())]\n * })\n * ```\n */\n spanProcessors?: SpanProcessor[];\n\n /**\n * Custom span exporters for traces (alternative to spanProcessors, supports multiple exporters)\n * Provide either spanProcessors OR spanExporters, not both\n * Each exporter will be wrapped in TailSamplingSpanProcessor + BatchSpanProcessor\n *\n * @example Multiple exporters\n * ```typescript\n * import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'\n * import { JaegerExporter } from '@opentelemetry/exporter-jaeger'\n *\n * init({\n * service: 'my-app',\n * spanExporters: [\n * new ZipkinExporter({ url: 'http://localhost:9411/api/v2/spans' }),\n * new JaegerExporter() // Send to multiple backends simultaneously\n * ]\n * })\n * ```\n *\n * @example Single exporter\n * ```typescript\n * import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'\n *\n * init({\n * service: 'my-app',\n * spanExporters: [new ZipkinExporter({ url: 'http://localhost:9411/api/v2/spans' })]\n * })\n * ```\n */\n spanExporters?: SpanExporter[];\n\n /**\n * Custom metric readers (supports multiple readers)\n * Allows sending metrics to multiple backends: OTLP, Prometheus, custom readers\n * Defaults to OTLP metrics exporter when metrics are enabled.\n *\n * @example Multiple metric readers\n * ```typescript\n * import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\n * import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'\n * import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'\n *\n * init({\n * service: 'my-app',\n * metricReaders: [\n * new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter() }),\n * new PrometheusExporter() // Export to multiple backends\n * ]\n * })\n * ```\n */\n metricReaders?: MetricReader[];\n\n /**\n * Custom log record processors. When omitted, logs are not configured.\n */\n logRecordProcessors?: LogRecordProcessor[];\n\n /**\n * PostHog integration - auto-configures OTLP log exporter.\n *\n * @example\n * ```typescript\n * init({\n * service: 'my-app',\n * posthog: { url: 'https://us.i.posthog.com/i/v1/logs?token=phc_xxx' }\n * });\n * ```\n *\n * Also reads from POSTHOG_LOGS_URL environment variable as fallback.\n */\n posthog?: { url: string };\n\n /** Additional resource attributes to merge with defaults. */\n resourceAttributes?: Attributes;\n\n /** Provide a fully custom Resource to merge (advanced use case). */\n resource?: Resource;\n\n /**\n * Headers for OTLP exporters. Accepts either an object map or\n * a \"key=value\" comma separated string.\n *\n * @example\n * ```typescript\n * init({\n * service: 'my-app',\n * endpoint: 'https://api.honeycomb.io',\n * headers: { 'x-honeycomb-team': 'YOUR_API_KEY' }\n * })\n * ```\n */\n headers?: Record<string, string> | string;\n\n /**\n * OTLP protocol to use for traces, metrics, and logs\n * - 'http': HTTP/protobuf (default, uses port 4318)\n * - 'grpc': gRPC (uses port 4317)\n *\n * Can be overridden with OTEL_EXPORTER_OTLP_PROTOCOL env var.\n *\n * Note: gRPC exporters are optional peer dependencies. Install them with:\n * ```bash\n * pnpm add @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/exporter-metrics-otlp-grpc\n * ```\n *\n * @example HTTP (default)\n * ```typescript\n * init({\n * service: 'my-app',\n * protocol: 'http', // or omit (defaults to http)\n * endpoint: 'http://localhost:4318'\n * })\n * ```\n *\n * @example gRPC\n * ```typescript\n * init({\n * service: 'my-app',\n * protocol: 'grpc',\n * endpoint: 'grpc://localhost:4317'\n * })\n * ```\n *\n * @default 'http'\n */\n protocol?: 'http' | 'grpc';\n\n /**\n * Optional factory to build a customised NodeSDK instance from our defaults.\n */\n sdkFactory?: (defaults: Partial<NodeSDKConfiguration>) => NodeSDK;\n\n /**\n * Infrastructure metrics configuration\n * - true: always enabled (default)\n * - false: always disabled\n * - 'auto': always enabled (same as true)\n *\n * Can be overridden with AUTOTEL_METRICS=on|off env var\n */\n metrics?: boolean | 'auto';\n\n /**\n * OTLP logs configuration\n * - true: auto-configure OTLP log exporter from endpoint\n * - false: disabled (default)\n * - 'auto': same as false (opt-in only)\n *\n * When enabled and an endpoint is configured, autotel will automatically\n * create a BatchLogRecordProcessor with an OTLPLogExporter - no manual\n * imports needed. Works alongside logRecordProcessors (additive).\n *\n * Requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http\n * (or -grpc) as peer dependencies.\n *\n * Can be overridden with AUTOTEL_LOGS=on|off env var.\n *\n * @example\n * ```typescript\n * init({\n * service: 'my-app',\n * endpoint: 'http://localhost:4318',\n * logs: true,\n * });\n * ```\n */\n logs?: boolean | 'auto';\n\n /** Sampling strategy - takes precedence over `sampling` preset */\n sampler?: Sampler;\n\n /**\n * Sampling preset shorthand — resolves to a pre-configured sampler.\n * If both `sampler` and `sampling` are provided, `sampler` takes precedence.\n *\n * @default 'production'\n */\n sampling?: SamplingPreset;\n\n /** Service version (default: auto-detect from package.json or '1.0.0') */\n version?: string;\n\n /** Environment (default: process.env.NODE_ENV || 'development') */\n environment?: string;\n\n /**\n * Logger instance for internal autotel diagnostic messages\n *\n * This logger is used by autotel internally to log initialization, warnings,\n * and debug information. Any logger with info/warn/error/debug methods works.\n *\n * **For OTel instrumentation of your application logs**, use the `autoInstrumentations` option:\n * - `autoInstrumentations: ['pino']` - Injects traceId/spanId into Pino logs\n * - `autoInstrumentations: ['winston']` - Injects traceId/spanId into Winston logs\n *\n * Default: silent logger (no-op)\n *\n * @example Pino with OTel instrumentation\n * ```typescript\n * import pino from 'pino'\n * import { init } from 'autotel'\n *\n * const logger = pino({ level: 'info' })\n * init({\n * service: 'my-app',\n * logger, // For autotel's internal logs\n * autoInstrumentations: ['pino'] // For OTel trace context in YOUR logs\n * })\n * ```\n *\n * @example Custom logger for autotel diagnostics\n * ```typescript\n * const logger = {\n * info: (msg, extra) => console.log(msg, extra),\n * warn: (msg, extra) => console.warn(msg, extra),\n * error: (msg, err, extra) => console.error(msg, err, extra),\n * debug: (msg, extra) => console.debug(msg, extra),\n * }\n * init({ service: 'my-app', logger })\n * ```\n */\n logger?: Logger;\n\n /**\n * Flush events queue when root spans end\n * - true: Flush on root span completion (default)\n * - false: Use batching (events flush every 10 seconds automatically)\n *\n * Only flushes on root spans to avoid excessive network calls.\n * Default is true for serverless/short-lived processes. Set to false\n * for long-running services where batching is more efficient.\n */\n flushOnRootSpanEnd?: boolean;\n\n /**\n * Force-flush OpenTelemetry spans on shutdown (default: false)\n *\n * When enabled, spans are force-flushed along with events on root\n * span completion. This is useful for serverless/short-lived processes where\n * spans may not export before the process ends.\n *\n * - true: Force-flush spans on root span completion (~50-200ms latency)\n * - false: Spans export via normal batch processor (default behavior)\n *\n * Only applies when flushOnRootSpanEnd is also enabled.\n *\n * Note: For edge runtimes (Cloudflare Workers, Vercel Edge), use the\n * 'autotel-edge' package instead, which handles this automatically.\n *\n * @example Serverless with force-flush\n * ```typescript\n * init({\n * service: 'my-lambda',\n * flushOnRootSpanEnd: true,\n * forceFlushOnShutdown: true, // Force-flush spans\n * });\n * ```\n */\n forceFlushOnShutdown?: boolean;\n\n /**\n * Automatically copy baggage entries to span attributes\n *\n * When enabled, all baggage entries are automatically added as span attributes,\n * making them visible in trace UIs (Jaeger, Grafana, DataDog, etc.) without\n * manually calling ctx.setAttribute() for each entry.\n *\n * - `true`: adds baggage with 'baggage.' prefix (e.g. baggage.tenant.id)\n * - `string`: uses custom prefix (e.g. 'ctx' → ctx.tenant.id, '' → tenant.id)\n * - `false` or omit: disabled (default)\n *\n * @default false\n *\n * @example Enable with default prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: true\n * });\n *\n * // Now baggage automatically appears as span attributes\n * await withBaggage({\n * baggage: { 'tenant.id': 't1', 'user.id': 'u1' },\n * fn: async () => {\n * // Span has baggage.tenant.id and baggage.user.id attributes!\n * }\n * });\n * ```\n *\n * @example Custom prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: 'ctx' // Uses 'ctx.' prefix\n * });\n * // Creates attributes: ctx.tenant.id, ctx.user.id\n * ```\n *\n * @example No prefix\n * ```typescript\n * init({\n * service: 'my-app',\n * baggage: '' // No prefix\n * });\n * // Creates attributes: tenant.id, user.id\n * ```\n */\n baggage?: boolean | string;\n\n /**\n * Validation configuration for events events\n * - Override default sensitive field patterns for redaction\n * - Customize max lengths, nesting depth, etc.\n *\n * @example Disable redaction for development\n * ```typescript\n * init({\n * service: 'my-app',\n * validation: {\n * sensitivePatterns: [] // Disable all redaction\n * }\n * })\n * ```\n *\n * @example Add custom patterns\n * ```typescript\n * init({\n * service: 'my-app',\n * validation: {\n * sensitivePatterns: [\n * /password/i,\n * /apiKey/i,\n * /customSecret/i // Your custom pattern\n * ]\n * }\n * })\n * ```\n */\n validation?: Partial<ValidationConfig>;\n\n /**\n * Events configuration for trace context, correlation IDs, and enrichment\n *\n * Controls how product events integrate with distributed tracing:\n * - `includeTraceContext`: Automatically include trace context in events\n * - `includeLinkedTraceIds`: Include full array of linked trace IDs (for batch/fan-in)\n * - `traceUrl`: Generate clickable trace URLs in events\n * - `enrichFromBaggage`: Auto-enrich events from baggage with guardrails\n *\n * @example Basic trace context\n * ```typescript\n * init({\n * service: 'my-app',\n * events: {\n * includeTraceContext: true\n * }\n * });\n * // Events now include autotel.trace_id, autotel.span_id, autotel.correlation_id\n * ```\n *\n * @example With clickable trace URLs\n * ```typescript\n * init({\n * service: 'my-app',\n * events: {\n * includeTraceContext: true,\n * traceUrl: (ctx) => `https://grafana.internal/explore?traceId=${ctx.traceId}`\n * }\n * });\n * ```\n *\n * @example With baggage enrichment\n * ```typescript\n * init({\n * service: 'my-app',\n * events: {\n * includeTraceContext: true,\n * enrichFromBaggage: {\n * allow: ['tenant.id', 'user.id'],\n * prefix: 'ctx.',\n * maxKeys: 10,\n * maxBytes: 1024\n * }\n * }\n * });\n * ```\n */\n events?: EventsConfig;\n\n /**\n * Debug mode for local span inspection.\n * Enables console output to help you see spans as they're created.\n *\n * - `true`: Raw JSON output (ConsoleSpanExporter)\n * - `'pretty'`: Colorized, hierarchical output (PrettyConsoleExporter)\n * - `false`/undefined: No console output (default)\n *\n * When enabled: Outputs spans to console AND sends to backend (if endpoint/exporter configured)\n *\n * Perfect for progressive development:\n * - Start with debug: 'pretty' (no endpoint) → see traces immediately with nice formatting\n * - Add endpoint later → console + backend, verify before choosing provider\n * - Remove debug in production → backend only, clean production config\n *\n * Can be overridden with AUTOTEL_DEBUG environment variable.\n *\n * @example Pretty debug output (recommended for development)\n * ```typescript\n * init({\n * service: 'my-app',\n * debug: 'pretty' // Colorized, hierarchical output\n * })\n * ```\n *\n * @example Raw JSON output (verbose)\n * ```typescript\n * init({\n * service: 'my-app',\n * debug: true // Raw ConsoleSpanExporter output\n * })\n * ```\n *\n * @example Environment variable\n * ```bash\n * AUTOTEL_DEBUG=pretty node server.js\n * AUTOTEL_DEBUG=true node server.js\n * ```\n */\n debug?: boolean | 'pretty';\n\n /**\n * Filter predicate to drop unwanted spans before processing.\n *\n * Useful for filtering out noisy spans from specific instrumentations\n * (e.g., Next.js internal spans, health check endpoints).\n *\n * The filter runs on completed spans (onEnd), so you have access to:\n * - `span.name` - Span name\n * - `span.attributes` - All span attributes\n * - `span.instrumentationScope` - `{ name, version }` of the instrumentation\n * - `span.status` - Span status code and message\n * - `span.duration` - Span duration as `[seconds, nanoseconds]`\n *\n * Return `true` to keep the span, `false` to drop it.\n *\n * @example Filter out Next.js instrumentation spans\n * ```typescript\n * init({\n * service: 'my-app',\n * spanFilter: (span) => span.instrumentationScope.name !== 'next.js'\n * })\n * ```\n *\n * @example Filter out health check spans\n * ```typescript\n * init({\n * service: 'my-app',\n * spanFilter: (span) => !span.name.includes('/health')\n * })\n * ```\n *\n * @example Complex filtering (multiple conditions)\n * ```typescript\n * init({\n * service: 'my-app',\n * spanFilter: (span) => {\n * // Drop Next.js internal spans\n * if (span.instrumentationScope.name === 'next.js') return false;\n * // Drop health checks\n * if (span.name.includes('/health')) return false;\n * // Drop very short spans (less than 1ms)\n * const [secs, nanos] = span.duration;\n * if (secs === 0 && nanos < 1_000_000) return false;\n * return true;\n * }\n * })\n * ```\n */\n spanFilter?: SpanFilterPredicate;\n\n /**\n * Normalize span names to reduce cardinality from dynamic path segments.\n *\n * High-cardinality span names (e.g., `/users/123/posts/456`) cause issues:\n * - Cost explosions in observability backends\n * - Cardinality limits exceeded\n * - Poor UX when searching/filtering traces\n *\n * The normalizer transforms dynamic segments into placeholders:\n * - `/users/123` → `/users/:id`\n * - `/items/550e8400-e29b-...` → `/items/:uuid`\n *\n * Provide either a custom function or use a built-in preset:\n * - `'rest-api'` - Numeric IDs, UUIDs, ObjectIds, dates, timestamps, emails\n * - `'graphql'` - GraphQL operation name normalization\n * - `'minimal'` - Only numeric IDs and UUIDs\n *\n * @example Custom normalizer function\n * ```typescript\n * init({\n * service: 'my-app',\n * spanNameNormalizer: (name) => {\n * return name\n * .replace(/\\/[0-9]+/g, '/:id')\n * .replace(/\\/[a-f0-9-]{36}/gi, '/:uuid');\n * }\n * })\n * ```\n *\n * @example Using built-in preset\n * ```typescript\n * init({\n * service: 'my-app',\n * spanNameNormalizer: 'rest-api'\n * })\n * ```\n *\n * @example Combining with spanFilter\n * ```typescript\n * init({\n * service: 'my-app',\n * spanNameNormalizer: 'rest-api',\n * spanFilter: (span) => span.instrumentationScope.name !== 'next.js'\n * })\n * ```\n */\n spanNameNormalizer?: SpanNameNormalizerConfig;\n\n /**\n * Automatically redact PII and sensitive data from span attributes before export.\n * Critical for compliance (GDPR, PCI-DSS, HIPAA) and data security.\n *\n * Can be a preset name or custom configuration:\n * - `'default'`: Emails, phones, SSNs, credit cards, sensitive keys (password, secret, token)\n * - `'strict'`: Default + Bearer tokens, JWTs, API keys in values\n * - `'pci-dss'`: Payment card industry focus (credit cards, CVV, card-related keys)\n *\n * @example Use default preset\n * ```typescript\n * init({\n * service: 'my-app',\n * attributeRedactor: 'default'\n * })\n * ```\n *\n * @example Custom patterns\n * ```typescript\n * init({\n * service: 'my-app',\n * attributeRedactor: {\n * keyPatterns: [/password/i, /secret/i],\n * valuePatterns: [\n * { name: 'customerId', pattern: /CUST-\\d{8}/g, replacement: 'CUST-***' }\n * ]\n * }\n * })\n * ```\n *\n * @example Custom redactor function\n * ```typescript\n * init({\n * service: 'my-app',\n * attributeRedactor: {\n * redactor: (key, value) => {\n * if (key === 'user.email' && typeof value === 'string') {\n * return value.replace(/@.+/, '@[REDACTED]');\n * }\n * return value;\n * }\n * }\n * })\n * ```\n */\n attributeRedactor?: AttributeRedactorConfig | AttributeRedactorPreset;\n\n /**\n * OpenLLMetry integration for LLM observability.\n * Requires @traceloop/node-server-sdk as an optional peer dependency.\n *\n * @example Enable OpenLLMetry with default settings\n * ```typescript\n * init({\n * service: 'my-app',\n * openllmetry: { enabled: true }\n * })\n * ```\n *\n * @example Enable with custom options\n * ```typescript\n * init({\n * service: 'my-app',\n * openllmetry: {\n * enabled: true,\n * options: {\n * disableBatch: process.env.NODE_ENV !== 'production',\n * apiKey: process.env.TRACELOOP_API_KEY\n * }\n * }\n * })\n * ```\n */\n openllmetry?: {\n enabled: boolean;\n options?: Record<string, unknown>;\n };\n\n /**\n * Canonical log lines - automatically emit spans as wide events (canonical log lines)\n *\n * When enabled, each span (or root span only) is automatically emitted as a\n * comprehensive log record with ALL span attributes. This implements the\n * \"canonical log line\" pattern: one comprehensive event per request with all context.\n *\n * **Benefits:**\n * - One log line per request with all context (wide event)\n * - High-cardinality, high-dimensionality data for powerful queries\n * - Automatic - no manual logging needed\n * - Queryable as structured data instead of string search\n *\n * @example Basic usage (one canonical log line per request)\n * ```typescript\n * init({\n * service: 'checkout-api',\n * canonicalLogLines: {\n * enabled: true,\n * rootSpansOnly: true, // One canonical log line per request\n * },\n * });\n * ```\n *\n * @example With custom logger\n * ```typescript\n * import pino from 'pino';\n * const logger = pino();\n * init({\n * service: 'my-app',\n * logger,\n * canonicalLogLines: {\n * enabled: true,\n * logger, // Use Pino for canonical log lines\n * rootSpansOnly: true,\n * },\n * });\n * ```\n *\n * @example Custom message format\n * ```typescript\n * init({\n * service: 'my-app',\n * canonicalLogLines: {\n * enabled: true,\n * messageFormat: (span) => {\n * const status = span.status.code === 2 ? 'ERROR' : 'SUCCESS';\n * return `${span.name} [${status}]`;\n * },\n * },\n * });\n * ```\n */\n canonicalLogLines?: {\n enabled: boolean;\n /** Logger to use for emitting canonical log lines (defaults to OTel Logs API) */\n logger?: Logger;\n /** Only emit canonical log lines for root spans (default: false) */\n rootSpansOnly?: boolean;\n /** Minimum log level for canonical log lines (default: 'info') */\n minLevel?: 'debug' | 'info' | 'warn' | 'error';\n /** Custom message format (default: uses span name) */\n messageFormat?: (\n span: import('@opentelemetry/sdk-trace-base').ReadableSpan,\n ) => string;\n /** Whether to include resource attributes (default: true) */\n includeResourceAttributes?: boolean;\n /** Predicate to decide whether to emit (runs after event is built). */\n shouldEmit?: CanonicalLogLineOptions['shouldEmit'];\n /**\n * Declarative tail sampling conditions (OR logic).\n * Ignored when `shouldEmit` is provided.\n * @example keep: [{ status: 500 }, { durationMs: 1000 }]\n */\n keep?: CanonicalLogLineOptions['keep'];\n /** Callback invoked after emit for custom fan-out. */\n drain?: CanonicalLogLineOptions['drain'];\n /** Handler for drain failures. */\n onDrainError?: CanonicalLogLineOptions['onDrainError'];\n /**\n * Pretty-print canonical log lines to console.\n * Defaults to true when NODE_ENV is 'development'.\n */\n pretty?: boolean;\n };\n\n /**\n * Suppress console output while keeping OTel exporters running.\n * Useful for platforms like GCP Cloud Run / AWS Lambda where stdout\n * is managed externally by the platform's log collector.\n *\n * @default false\n */\n silent?: boolean;\n\n /**\n * Minimum log level for internal autotel diagnostic messages.\n * Messages below this level are dropped before processing.\n *\n * @default 'info'\n */\n minLevel?: 'debug' | 'info' | 'warn' | 'error';\n}\n\n// Internal state\nlet initialized = false;\nlet locked = false;\nlet config: AutotelConfig | null = null;\nlet sdk: NodeSDK | null = null;\nlet warnedOnce = false;\nlet logger: Logger = silentLogger; // Silent by default - no spam\nlet validationConfig: Partial<ValidationConfig> | null = null;\nlet eventsConfig: EventsConfig | null = null;\nlet _stringRedactor: StringRedactor | null = null;\nlet _optionalRequire: typeof safeRequire = safeRequire;\nlet _devtoolsClose: (() => Promise<void> | void) | null = null;\n\nconst LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3 } as const;\ntype LogLevelKey = keyof typeof LOG_LEVELS;\n\n/**\n * Lock the logger to prevent further `init()` calls.\n * Use this when framework plugins set up instrumentation and you want\n * to prevent accidental re-initialization from user code.\n */\nexport function lockLogger(): void {\n locked = true;\n}\n\n/**\n * Check if the logger has been locked.\n */\nexport function isLoggerLocked(): boolean {\n return locked;\n}\n\nfunction createSilentLogger(): Logger {\n return {\n info: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n };\n}\n\nfunction wrapLogger(\n base: Logger,\n silent: boolean,\n minLevel: LogLevelKey,\n): Logger {\n if (silent) return createSilentLogger();\n const threshold = LOG_LEVELS[minLevel];\n const wrap = (fn: Logger['info'], level: LogLevelKey): Logger['info'] => {\n if (LOG_LEVELS[level] < threshold) {\n return (() => {}) as Logger['info'];\n }\n return ((...args: Parameters<Logger['info']>) =>\n fn(...args)) as Logger['info'];\n };\n return {\n debug: wrap(base.debug, 'debug'),\n info: wrap(base.info, 'info'),\n warn: wrap(base.warn, 'warn'),\n error: wrap(base.error, 'error'),\n };\n}\n\nfunction detectEnvironmentAttributes(): Record<string, string> {\n const attrs: Record<string, string> = {};\n\n const commitSha =\n process.env.COMMIT_SHA ||\n process.env.GITHUB_SHA ||\n process.env.VERCEL_GIT_COMMIT_SHA ||\n process.env.CF_PAGES_COMMIT_SHA ||\n process.env.AWS_CODEPIPELINE_EXECUTION_ID;\n if (commitSha) attrs['service.commit.sha'] = commitSha;\n\n const region =\n process.env.VERCEL_REGION ||\n process.env.AWS_REGION ||\n process.env.AWS_DEFAULT_REGION ||\n process.env.FLY_REGION ||\n process.env.CF_REGION ||\n process.env.GOOGLE_CLOUD_REGION;\n if (region) attrs['service.region'] = region;\n\n const version =\n process.env.APP_VERSION ||\n process.env.HEROKU_RELEASE_VERSION ||\n process.env.VERCEL_GIT_COMMIT_REF;\n if (version) attrs['service.deploy.version'] = version;\n\n return attrs;\n}\n\n/**\n * Resolve metrics flag with env var override support\n */\nexport function resolveMetricsFlag(\n configFlag: boolean | 'auto' = 'auto',\n): boolean {\n // 1. Check env var override (highest priority)\n const envFlag = process.env.AUTOTEL_METRICS;\n if (envFlag === 'on' || envFlag === 'true') return true;\n if (envFlag === 'off' || envFlag === 'false') return false;\n\n // 2. Check config flag\n if (configFlag === true) return true;\n if (configFlag === false) return false;\n\n // 3. Default: enabled in all environments (simpler)\n return true;\n}\n\n/**\n * Resolve logs flag with env var override support.\n * Defaults to disabled (opt-in only) to avoid unexpected log export\n * and to preserve the upstream SDK's OTEL_LOGS_EXPORTER handling.\n */\nexport function resolveLogsFlag(\n configFlag: boolean | 'auto' = 'auto',\n): boolean {\n // 1. Check env var override (highest priority)\n const envFlag = process.env.AUTOTEL_LOGS;\n if (envFlag === 'on' || envFlag === 'true') return true;\n if (envFlag === 'off' || envFlag === 'false') return false;\n\n // 2. Check config flag\n if (configFlag === true) return true;\n if (configFlag === false) return false;\n\n // 3. Default: disabled (opt-in only)\n return false;\n}\n\n/**\n * Resolve debug flag with env var override support\n *\n * Supports:\n * - `'pretty'`: Colorized, hierarchical output (PrettyConsoleExporter)\n * - `true` / `'true'` / `'1'`: Raw JSON output (ConsoleSpanExporter)\n * - `false` / `'false'` / `'0'`: Disabled\n */\nexport function resolveDebugFlag(\n configFlag?: boolean | 'pretty',\n): boolean | 'pretty' {\n // 1. Check env var override (highest priority)\n const envFlag = process.env.AUTOTEL_DEBUG;\n if (envFlag === 'pretty') return 'pretty';\n if (envFlag === 'true' || envFlag === '1') return true;\n if (envFlag === 'false' || envFlag === '0') return false;\n\n // 2. Return config flag (defaults to false)\n return configFlag ?? false;\n}\n\nfunction normalizeOtlpHeaders(\n headers?: Record<string, string> | string,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n if (typeof headers !== 'string') return headers;\n\n const parsed: Record<string, string> = {};\n for (const pair of headers.split(',')) {\n const [key, ...valueParts] = pair.split('=');\n if (!key || valueParts.length === 0) continue;\n parsed[key.trim()] = valueParts.join('=').trim();\n }\n return parsed;\n}\n\n/**\n * Initialize autotel - Write Once, Observe Everywhere\n *\n * Follows OpenTelemetry standards: opinionated defaults with full flexibility\n * Idempotent: multiple calls are safe, last one wins\n *\n * @example Minimal setup (OTLP default)\n * ```typescript\n * init({ service: 'my-app' })\n * ```\n *\n * @example With events (observe in PostHog, Mixpanel, etc.)\n * ```typescript\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * init({\n * service: 'my-app',\n * subscribers: [new PostHogSubscriber({ apiKey: '...' })]\n * })\n * ```\n *\n * @example Observe in Jaeger\n * ```typescript\n * import { JaegerExporter } from '@opentelemetry/exporter-jaeger'\n *\n * init({\n * service: 'my-app',\n * spanExporter: new JaegerExporter({ endpoint: 'http://localhost:14268/api/traces' })\n * })\n * ```\n *\n * @example Observe in Zipkin\n * ```typescript\n * import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'\n *\n * init({\n * service: 'my-app',\n * spanExporter: new ZipkinExporter({ url: 'http://localhost:9411/api/v2/spans' })\n * })\n * ```\n *\n * @example Observe in Datadog\n * ```typescript\n * import { DatadogSpanProcessor } from '@opentelemetry/exporter-datadog'\n *\n * init({\n * service: 'my-app',\n * spanProcessor: new DatadogSpanProcessor({ ... })\n * })\n * ```\n *\n * @example Console output (dev)\n * ```typescript\n * import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\n *\n * init({\n * service: 'my-app',\n * spanProcessor: new SimpleSpanProcessor(new ConsoleSpanExporter())\n * })\n * ```\n */\n\nexport function init(cfg: AutotelConfig): void {\n if (locked) {\n return;\n }\n\n // Resolve configs in priority order: explicit > yaml > env > defaults\n const envConfig = resolveConfigFromEnv();\n const yamlConfig = loadYamlConfig() ?? {};\n\n // Merge configs: explicit config > yaml file > env vars > defaults\n const mergedConfig: AutotelConfig = {\n ...envConfig, // Environment variables (lowest priority)\n ...yamlConfig, // YAML file (middle priority)\n ...cfg, // Explicit config (highest priority)\n // Deep merge for resourceAttributes\n resourceAttributes: {\n ...envConfig.resourceAttributes,\n ...yamlConfig.resourceAttributes,\n ...detectEnvironmentAttributes(),\n ...cfg.resourceAttributes,\n },\n // Handle headers merge (can be string or object)\n headers: cfg.headers ?? yamlConfig.headers ?? envConfig.headers,\n } as AutotelConfig;\n\n if (mergedConfig.attributeRedactor !== undefined) {\n const normalizedRedactor = normalizeAttributeRedactorConfig(\n mergedConfig.attributeRedactor,\n );\n if (!normalizedRedactor) {\n throw new Error('Invalid attributeRedactor config');\n }\n mergedConfig.attributeRedactor = normalizedRedactor;\n }\n\n const devtoolsConfig = resolveDevtoolsConfig(mergedConfig.devtools);\n if (devtoolsConfig.enabled && mergedConfig.logs === undefined) {\n mergedConfig.logs = true;\n }\n\n const silent = mergedConfig.silent ?? false;\n const minLevel = mergedConfig.minLevel ?? 'info';\n const baseLogger = mergedConfig.logger || silentLogger;\n logger = wrapLogger(baseLogger, silent, minLevel);\n\n // Warn if re-initializing (same behavior in all environments)\n if (initialized) {\n logger.warn(\n {},\n '[autotel] init() called again - last config wins. This may cause unexpected behavior.',\n );\n }\n\n config = mergedConfig;\n validationConfig = mergedConfig.validation || null;\n eventsConfig = mergedConfig.events || null;\n\n // Initialize OpenTelemetry\n // Only use endpoint if explicitly configured (no default fallback)\n let endpoint = mergedConfig.endpoint ?? devtoolsConfig.endpoint;\n const otlpHeaders = normalizeOtlpHeaders(mergedConfig.headers);\n const version = mergedConfig.version || detectVersion();\n const environment =\n mergedConfig.environment || process.env.NODE_ENV || 'development';\n const metricsEnabled = resolveMetricsFlag(mergedConfig.metrics);\n const logsEnabled = resolveLogsFlag(mergedConfig.logs);\n\n if (devtoolsConfig.enabled && devtoolsConfig.embedded) {\n const devtoolsModule = _optionalRequire<{\n createDevtools?: (options?: {\n port?: number;\n host?: string;\n verbose?: boolean;\n }) => { port: number; close: () => Promise<void> | void };\n }>('autotel-devtools');\n\n if (devtoolsModule?.createDevtools) {\n const devtoolsInstance = devtoolsModule.createDevtools({\n port: devtoolsConfig.port,\n host: devtoolsConfig.host,\n verbose: devtoolsConfig.verbose,\n });\n _devtoolsClose = devtoolsInstance.close;\n endpoint = `http://${devtoolsConfig.host}:${devtoolsInstance.port}`;\n logger.info(\n {},\n `[autotel] autotel-devtools embedded server started at ${endpoint}`,\n );\n } else {\n logger.warn(\n {},\n '[autotel] devtools.embedded requested but autotel-devtools is not installed. Falling back to endpoint-only mode.',\n );\n }\n }\n\n // Detect hostname for proper Datadog correlation and Service Catalog discovery\n const hostname = detectHostname();\n\n let resource = resourceFromAttributes({\n [ATTR_SERVICE_NAME]: mergedConfig.service,\n [ATTR_SERVICE_VERSION]: version,\n // Support both old and new OpenTelemetry semantic conventions for environment\n 'deployment.environment': environment, // Deprecated but widely supported\n 'deployment.environment.name': environment, // OTel v1.27.0+ standard\n });\n\n // Add hostname attributes for Datadog Service Catalog and infrastructure correlation\n if (hostname) {\n resource = resource.merge(\n resourceFromAttributes({\n 'host.name': hostname, // OpenTelemetry standard\n 'datadog.host.name': hostname, // Datadog-specific, highest priority for Datadog\n }),\n );\n }\n\n if (mergedConfig.resource) {\n resource = resource.merge(mergedConfig.resource);\n }\n\n if (mergedConfig.resourceAttributes) {\n resource = resource.merge(\n resourceFromAttributes(mergedConfig.resourceAttributes),\n );\n }\n\n // Resolve OTLP protocol (http or grpc)\n const protocol = resolveProtocol(mergedConfig.protocol);\n\n // Build array of span processors (supports multiple)\n let spanProcessors: SpanProcessor[] = [];\n\n if (mergedConfig.spanProcessors && mergedConfig.spanProcessors.length > 0) {\n // User provided custom processors (full control)\n spanProcessors.push(...mergedConfig.spanProcessors);\n } else if (\n mergedConfig.spanExporters &&\n mergedConfig.spanExporters.length > 0\n ) {\n // User provided custom exporters (wrap each with tail sampling)\n for (const exporter of mergedConfig.spanExporters) {\n spanProcessors.push(\n new TailSamplingSpanProcessor(new BatchSpanProcessor(exporter)),\n );\n }\n } else if (endpoint) {\n // Default: OTLP with tail sampling (only if endpoint is configured)\n const traceExporter = createTraceExporter(protocol, {\n url: formatEndpointUrl(endpoint, 'traces', protocol),\n headers: otlpHeaders,\n });\n\n spanProcessors.push(\n new TailSamplingSpanProcessor(new BatchSpanProcessor(traceExporter)),\n );\n }\n // If no endpoint and no custom processors/exporters, array remains empty\n // SDK will still work but won't export traces\n\n // Add baggage span processor if enabled\n if (mergedConfig.baggage) {\n const prefix =\n typeof mergedConfig.baggage === 'string'\n ? mergedConfig.baggage\n ? `${mergedConfig.baggage}.`\n : ''\n : 'baggage.';\n spanProcessors.push(new BaggageSpanProcessor({ prefix }));\n }\n\n // Apply debug mode configuration\n const debugMode = resolveDebugFlag(mergedConfig.debug);\n\n if (debugMode === 'pretty') {\n // Pretty debug: colorized, hierarchical output\n spanProcessors.push(new SimpleSpanProcessor(new PrettyConsoleExporter()));\n } else if (debugMode === true) {\n // Raw debug: JSON output\n spanProcessors.push(new SimpleSpanProcessor(new ConsoleSpanExporter()));\n }\n\n // Add canonical log line processor BEFORE wrapping processors\n // This ensures it gets wrapped with the same filter/normalizer/redactor as other processors,\n // so canonical logs respect spanFilter (filtered spans aren't logged), spanNameNormalizer\n // (normalized names are used), and attributeRedactor (sensitive data is redacted).\n if (mergedConfig.canonicalLogLines?.enabled) {\n const canonicalOptions: CanonicalLogLineOptions = {\n logger: mergedConfig.canonicalLogLines.logger || mergedConfig.logger,\n rootSpansOnly: mergedConfig.canonicalLogLines.rootSpansOnly,\n minLevel: mergedConfig.canonicalLogLines.minLevel,\n messageFormat: mergedConfig.canonicalLogLines.messageFormat,\n includeResourceAttributes:\n mergedConfig.canonicalLogLines.includeResourceAttributes,\n shouldEmit: mergedConfig.canonicalLogLines.shouldEmit,\n keep: mergedConfig.canonicalLogLines.keep,\n drain: mergedConfig.canonicalLogLines.drain,\n onDrainError: mergedConfig.canonicalLogLines.onDrainError,\n pretty: mergedConfig.canonicalLogLines.pretty,\n };\n spanProcessors.push(new CanonicalLogLineProcessor(canonicalOptions));\n }\n\n // Wrap processors in order: redactor (innermost) → normalizer → filter (outermost)\n // This ensures onEnd() execution order is: filter → normalizer → redactor\n // So filtering sees original attributes, and redaction happens last before export.\n\n // Step 1: Wrap with AttributeRedactingProcessor (innermost - executes last in onEnd)\n if (mergedConfig.attributeRedactor && spanProcessors.length > 0) {\n spanProcessors = spanProcessors.map(\n (processor) =>\n new AttributeRedactingProcessor(processor, {\n redactor: mergedConfig.attributeRedactor!,\n }),\n );\n }\n\n // Store string redactor for use by PostHog log/subscriber paths\n if (mergedConfig.attributeRedactor) {\n _stringRedactor = createStringRedactor(mergedConfig.attributeRedactor);\n }\n\n // Wire string redactor to subscribers that support it (e.g., PostHogSubscriber)\n if (_stringRedactor && mergedConfig.subscribers) {\n for (const subscriber of mergedConfig.subscribers) {\n if (\n 'setStringRedactor' in subscriber &&\n typeof (subscriber as any).setStringRedactor === 'function'\n ) {\n (subscriber as any).setStringRedactor(_stringRedactor);\n }\n }\n }\n\n // Step 2: Wrap with SpanNameNormalizingProcessor (middle)\n // Normalizer runs in onStart(), so span names are normalized before any onEnd processing\n if (mergedConfig.spanNameNormalizer && spanProcessors.length > 0) {\n spanProcessors = spanProcessors.map(\n (processor) =>\n new SpanNameNormalizingProcessor(processor, {\n normalizer: mergedConfig.spanNameNormalizer!,\n }),\n );\n }\n\n // Step 3: Wrap with FilteringSpanProcessor (outermost - executes first in onEnd)\n // Filter sees original (unredacted) attributes, so it can match on sensitive values\n if (mergedConfig.spanFilter && spanProcessors.length > 0) {\n spanProcessors = spanProcessors.map(\n (processor) =>\n new FilteringSpanProcessor(processor, {\n filter: mergedConfig.spanFilter!,\n }),\n );\n }\n\n // Build array of metric readers (supports multiple)\n const metricReaders: MetricReader[] = [];\n\n if (mergedConfig.metricReaders && mergedConfig.metricReaders.length > 0) {\n // User provided custom metric readers\n metricReaders.push(...mergedConfig.metricReaders);\n } else if (metricsEnabled && endpoint) {\n // Default: OTLP metrics exporter (only if endpoint is configured)\n const metricExporter = createMetricExporter(protocol, {\n url: formatEndpointUrl(endpoint, 'metrics', protocol),\n headers: otlpHeaders,\n });\n\n metricReaders.push(\n new PeriodicExportingMetricReader({\n exporter: metricExporter,\n }),\n );\n }\n\n let logRecordProcessors: LogRecordProcessor[] | undefined;\n if (\n mergedConfig.logRecordProcessors &&\n mergedConfig.logRecordProcessors.length > 0\n ) {\n logRecordProcessors = [...mergedConfig.logRecordProcessors];\n }\n\n // Auto-configure OTLP log exporter when logs are enabled and endpoint is set\n if (logsEnabled && endpoint) {\n const logExporter = createLogExporter(protocol, {\n url: formatEndpointUrl(endpoint, 'logs', protocol),\n headers: otlpHeaders,\n });\n\n let processor: LogRecordProcessor = new BatchLogRecordProcessor(\n logExporter,\n );\n if (_stringRedactor) {\n processor = new RedactingLogRecordProcessor(processor, _stringRedactor);\n }\n if (!logRecordProcessors) {\n logRecordProcessors = [];\n }\n logRecordProcessors.push(processor);\n logger.info({}, '[autotel] OTLP log exporter configured');\n }\n\n // PostHog OTLP logs integration\n const posthogProcessors = buildPostHogLogProcessors(\n mergedConfig.posthog,\n _stringRedactor,\n );\n if (posthogProcessors.length > 0) {\n if (!logRecordProcessors) {\n logRecordProcessors = [];\n }\n logRecordProcessors.push(...posthogProcessors);\n logger.info({}, '[autotel] PostHog OTLP logs configured');\n }\n\n // Handle instrumentations: merge manual instrumentations with auto-instrumentations\n let finalInstrumentations: NodeSDKConfiguration['instrumentations'] =\n mergedConfig.instrumentations ? [...mergedConfig.instrumentations] : [];\n\n if (\n mergedConfig.autoInstrumentations !== undefined &&\n mergedConfig.autoInstrumentations !== false\n ) {\n // Check for ESM mode and provide guidance\n const isESM = isESMMode();\n if (isESM) {\n logger.info(\n {},\n '[autotel] ESM mode detected. For auto-instrumentation to work:\\n' +\n ' 1. Install @opentelemetry/auto-instrumentations-node as a direct dependency\\n' +\n ' 2. Import autotel/register FIRST in your instrumentation file\\n' +\n ' 3. Use getNodeAutoInstrumentations() directly instead of autoInstrumentations\\n' +\n ' See: https://github.com/jagreehal/autotel#esm-setup',\n );\n }\n\n try {\n // Detect manual instrumentations to avoid conflicts\n const manualInstrumentationNames = getInstrumentationNames(\n mergedConfig.instrumentations ?? [],\n );\n\n // Warn if both autoInstrumentations and manual instrumentations are provided\n if (manualInstrumentationNames.size > 0) {\n const manualNames = [...manualInstrumentationNames].join(', ');\n logger.info(\n {},\n `[autotel] Detected manual instrumentations (${manualNames}). ` +\n 'These will take precedence over auto-instrumentations. ' +\n 'Tip: Set autoInstrumentations:false if you want full manual control, or remove manual configs to use auto-instrumentations.',\n );\n }\n\n const autoInstrumentations = getAutoInstrumentations(\n mergedConfig.autoInstrumentations,\n manualInstrumentationNames,\n );\n if (autoInstrumentations && autoInstrumentations.length > 0) {\n // Cast to proper type - getNodeAutoInstrumentations returns the correct type\n finalInstrumentations = [\n ...finalInstrumentations,\n ...(autoInstrumentations as NodeSDKConfiguration['instrumentations']),\n ];\n }\n } catch (error) {\n logger.warn(\n {},\n `[autotel] Failed to configure auto-instrumentations: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n const autotelSampler =\n mergedConfig.sampler ??\n (mergedConfig.sampling\n ? resolveSamplingPreset(mergedConfig.sampling)\n : undefined);\n if (autotelSampler) {\n mergedConfig.sampler = autotelSampler;\n }\n const sampler: OtelSampler = autotelSampler\n ? toOtelSampler(autotelSampler)\n : (envConfig.otelSampler ?? toOtelSampler(samplingPresets.production()));\n\n const sdkOptions: Partial<NodeSDKConfiguration> = {\n resource,\n sampler,\n instrumentations: finalInstrumentations,\n };\n\n if (spanProcessors.length > 0) {\n sdkOptions.spanProcessors = spanProcessors;\n }\n\n if (metricReaders.length > 0) {\n sdkOptions.metricReaders = metricReaders;\n }\n\n if (logRecordProcessors && logRecordProcessors.length > 0) {\n sdkOptions.logRecordProcessors = logRecordProcessors;\n }\n\n sdk = mergedConfig.sdkFactory\n ? mergedConfig.sdkFactory(sdkOptions)\n : new NodeSDK(sdkOptions);\n\n if (!sdk) {\n throw new Error('[autotel] sdkFactory must return a NodeSDK instance');\n }\n\n sdk.start();\n\n // Initialize OpenLLMetry if enabled (after SDK starts to reuse tracer provider)\n if (mergedConfig.openllmetry?.enabled) {\n const traceloop = _optionalRequire<{\n initialize?: (options?: Record<string, unknown>) => void;\n }>('@traceloop/node-server-sdk');\n\n if (traceloop) {\n const initOptions: Record<string, unknown> = {\n ...mergedConfig.openllmetry.options,\n };\n\n // Reuse autotel's tracer provider\n try {\n // Type assertion needed as getTracerProvider is not in the public NodeSDK interface\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tracerProvider = (sdk as any).getTracerProvider();\n initOptions.tracerProvider = tracerProvider;\n } catch {\n // Ignore if tracer provider not available\n }\n\n // Pass span exporter to OpenLLMetry if provided\n if (mergedConfig.spanExporters?.[0]) {\n initOptions.exporter = mergedConfig.spanExporters[0];\n }\n\n if (typeof traceloop.initialize === 'function') {\n traceloop.initialize(initOptions);\n logger.info({}, '[autotel] OpenLLMetry initialized successfully');\n } else {\n logger.warn(\n {},\n '[autotel] OpenLLMetry initialize function not found. Check @traceloop/node-server-sdk version.',\n );\n }\n } else {\n logger.warn(\n {},\n '[autotel] OpenLLMetry enabled but @traceloop/node-server-sdk is not installed. ' +\n 'Install it as a peer dependency to use OpenLLMetry integration.',\n );\n }\n }\n\n initialized = true;\n}\n\n/**\n * Extract instrumentation class names from instrumentation instances\n * Used to detect duplicates between manual and auto instrumentations\n */\nfunction getInstrumentationNames(\n instrumentations: NodeSDKConfiguration['instrumentations'],\n): Set<string> {\n const names = new Set<string>();\n\n if (!instrumentations) return names;\n\n for (const instrumentation of instrumentations) {\n if (instrumentation && typeof instrumentation === 'object') {\n names.add(instrumentation.constructor.name);\n }\n }\n\n return names;\n}\n\n/**\n * Map common instrumentation class names to their package names\n * Used to disable auto-instrumentations when user provides manual configs\n */\nconst INSTRUMENTATION_CLASS_TO_PACKAGE: Record<string, string> = {\n HttpInstrumentation: '@opentelemetry/instrumentation-http',\n HttpsInstrumentation: '@opentelemetry/instrumentation-http',\n ExpressInstrumentation: '@opentelemetry/instrumentation-express',\n FastifyInstrumentation: '@opentelemetry/instrumentation-fastify',\n MongoDBInstrumentation: '@opentelemetry/instrumentation-mongodb',\n MongooseInstrumentation: '@opentelemetry/instrumentation-mongoose',\n PrismaInstrumentation: '@opentelemetry/instrumentation-prisma',\n PinoInstrumentation: '@opentelemetry/instrumentation-pino',\n WinstonInstrumentation: '@opentelemetry/instrumentation-winston',\n RedisInstrumentation: '@opentelemetry/instrumentation-redis',\n GraphQLInstrumentation: '@opentelemetry/instrumentation-graphql',\n GrpcInstrumentation: '@opentelemetry/instrumentation-grpc',\n IORedisInstrumentation: '@opentelemetry/instrumentation-ioredis',\n KnexInstrumentation: '@opentelemetry/instrumentation-knex',\n NestJsInstrumentation: '@opentelemetry/instrumentation-nestjs-core',\n PgInstrumentation: '@opentelemetry/instrumentation-pg',\n MySQLInstrumentation: '@opentelemetry/instrumentation-mysql',\n MySQL2Instrumentation: '@opentelemetry/instrumentation-mysql2',\n};\n\n/**\n * Type for the auto-instrumentations loader function\n * @internal Used for testing injection\n */\nexport type AutoInstrumentationsLoader = (\n config?: Record<string, { enabled?: boolean }>,\n) => unknown[];\n\n/**\n * Detect if we're running in ESM mode\n */\nfunction isESMMode(): boolean {\n // Check if we're in an ESM context by looking for common ESM indicators\n try {\n // In ESM, module.exports doesn't exist in the global scope the same way\n // Also check if the package.json type is \"module\"\n const fs = requireModule<typeof import('node:fs')>('node:fs');\n try {\n const pkg = JSON.parse(\n fs.readFileSync(`${process.cwd()}/package.json`, 'utf8'),\n );\n return pkg.type === 'module';\n } catch {\n return false;\n }\n } catch {\n return false;\n }\n}\n\n/**\n * Lazy-load auto-instrumentations (optional peer dependency)\n * Only loads when integrations config is truthy, avoiding ~40+ package imports at startup.\n */\nfunction loadNodeAutoInstrumentations(): AutoInstrumentationsLoader {\n try {\n const mod = requireModule<{\n getNodeAutoInstrumentations: AutoInstrumentationsLoader;\n }>('@opentelemetry/auto-instrumentations-node');\n return mod.getNodeAutoInstrumentations;\n } catch {\n const isESM = isESMMode();\n const baseMessage = '@opentelemetry/auto-instrumentations-node not found.';\n\n if (isESM) {\n throw new Error(\n `${baseMessage}\\n\\n` +\n 'ESM Setup Required:\\n' +\n '1. Install as a direct dependency: pnpm add @opentelemetry/auto-instrumentations-node\\n' +\n '2. Create instrumentation.mjs with:\\n' +\n \" import 'autotel/register'; // MUST be first!\\n\" +\n \" import { init } from 'autotel';\\n\" +\n \" import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\\n\" +\n ' init({ service: \"my-app\", instrumentations: getNodeAutoInstrumentations() });\\n' +\n '3. Run with: tsx --import ./instrumentation.mjs src/index.ts\\n\\n' +\n 'See: https://github.com/jagreehal/autotel#esm-setup',\n );\n }\n\n throw new Error(\n `${baseMessage} Install it: pnpm add @opentelemetry/auto-instrumentations-node`,\n );\n }\n}\n\n/**\n * Injectable loader for testing. Set to override the default loader.\n * @internal\n */\nlet _autoInstrumentationsLoader: (() => AutoInstrumentationsLoader) | null =\n null;\n\n/**\n * @internal Set custom loader (for testing)\n */\nexport function _setAutoInstrumentationsLoader(\n loader: (() => AutoInstrumentationsLoader) | null,\n): void {\n _autoInstrumentationsLoader = loader;\n}\n\n/**\n * @internal Reset loader to default (for testing cleanup)\n */\nexport function _resetAutoInstrumentationsLoader(): void {\n _autoInstrumentationsLoader = null;\n}\n\n/**\n * Get auto-instrumentations based on simple integration names\n * Excludes instrumentations that are manually provided to avoid conflicts\n */\nfunction getAutoInstrumentations(\n integrations: string[] | boolean | Record<string, { enabled?: boolean }>,\n manualInstrumentationNames: Set<string> = new Set(),\n): unknown[] {\n if (integrations === false) {\n return [];\n }\n\n // Use injected loader if set (for testing), otherwise lazy-load\n const getNodeAutoInstrumentations = _autoInstrumentationsLoader\n ? _autoInstrumentationsLoader()\n : loadNodeAutoInstrumentations();\n\n // Build exclusion config for manual instrumentations\n const exclusionConfig: Record<string, { enabled: boolean }> = {};\n for (const className of manualInstrumentationNames) {\n const packageName = INSTRUMENTATION_CLASS_TO_PACKAGE[className];\n if (packageName) {\n exclusionConfig[packageName] = { enabled: false };\n }\n }\n\n if (integrations === true) {\n // If exclusions exist, pass them to getNodeAutoInstrumentations\n if (Object.keys(exclusionConfig).length > 0) {\n return getNodeAutoInstrumentations(exclusionConfig);\n }\n return getNodeAutoInstrumentations();\n }\n\n if (Array.isArray(integrations)) {\n const config: Record<string, { enabled: boolean }> = { ...exclusionConfig };\n for (const name of integrations) {\n const packageName = `@opentelemetry/instrumentation-${name}`;\n // Don't override exclusions\n if (!exclusionConfig[packageName]) {\n config[packageName] = { enabled: true };\n }\n }\n return getNodeAutoInstrumentations(config);\n }\n\n const config: Record<string, { enabled?: boolean }> = {\n ...exclusionConfig,\n ...integrations,\n };\n\n // Override any integrations that conflict with manual instrumentations\n for (const packageName of Object.keys(exclusionConfig)) {\n const integrationsKey = Object.keys(integrations).find((key) =>\n packageName.includes(key),\n );\n if (integrationsKey) {\n // Manual instrumentation takes precedence\n config[packageName] = { enabled: false };\n }\n }\n\n return getNodeAutoInstrumentations(config);\n}\n\n/**\n * Check if autotel has been initialized\n */\nexport function isInitialized(): boolean {\n return initialized;\n}\n\n/**\n * Get current config (internal use)\n */\nexport function getConfig(): AutotelConfig | null {\n return config;\n}\n\n/**\n * Get current logger (internal use)\n */\nexport function getLogger(): Logger {\n return logger;\n}\n\n/**\n * Get validation config (internal use)\n */\nexport function getValidationConfig(): Partial<ValidationConfig> | null {\n return validationConfig;\n}\n\n/**\n * Get events config (internal use)\n */\nexport function getEventsConfig(): EventsConfig | null {\n return eventsConfig;\n}\n\n/**\n * Warn once if not initialized (same behavior in all environments)\n */\nexport function warnIfNotInitialized(context: string): void {\n if (!initialized && !warnedOnce) {\n logger.warn(\n {},\n `[autotel] ${context} used before init() called. ` +\n 'Call init({ service: \"...\" }) first. See: https://docs.autotel.dev/quickstart',\n );\n warnedOnce = true;\n }\n}\n\n/**\n * Get default sampler\n */\nexport function getDefaultSampler(): Sampler {\n return config?.sampler || samplingPresets.production();\n}\n\n/**\n * Auto-detect version from package.json\n */\nfunction detectVersion(): string {\n try {\n // Try to read package.json from cwd using fs\n const fs = requireModule<typeof import('node:fs')>('node:fs');\n const pkg = JSON.parse(\n fs.readFileSync(`${process.cwd()}/package.json`, 'utf8'),\n );\n return pkg.version || '1.0.0';\n } catch {\n return '1.0.0';\n }\n}\n\n/**\n * Detect hostname for resource attributes.\n * Supports Datadog conventions (DD_HOSTNAME) and falls back to system hostname.\n *\n * Priority order:\n * 1. DD_HOSTNAME environment variable (Datadog convention)\n * 2. HOSTNAME environment variable (common Unix convention)\n * 3. os.hostname() (system hostname)\n *\n * @returns hostname string or undefined if detection fails\n */\nfunction detectHostname(): string | undefined {\n // Priority 1: DD_HOSTNAME (Datadog convention)\n if (process.env.DD_HOSTNAME) {\n return process.env.DD_HOSTNAME;\n }\n\n // Priority 2: HOSTNAME (common in containers and Unix systems)\n if (process.env.HOSTNAME) {\n return process.env.HOSTNAME;\n }\n\n // Priority 3: System hostname\n try {\n const os = requireModule<typeof import('node:os')>('node:os');\n return os.hostname();\n } catch {\n // os module not available (edge runtime, browser, etc.)\n return undefined;\n }\n}\n\n/**\n * Get the string redactor configured via init({ attributeRedactor }).\n * Returns null if no redactor was configured.\n */\nexport function getStringRedactor(): StringRedactor | null {\n return _stringRedactor;\n}\n\n/**\n * @internal Override optional require for deterministic tests.\n */\nexport function _setOptionalRequireForTesting(\n loader: typeof safeRequire,\n): void {\n _optionalRequire = loader;\n}\n\n/**\n * @internal Reset optional require override.\n */\nexport function _resetOptionalRequireForTesting(): void {\n _optionalRequire = safeRequire;\n}\n\n/**\n * @internal Close embedded devtools if running.\n */\nexport async function _closeEmbeddedDevtools(): Promise<void> {\n if (_devtoolsClose) {\n await _devtoolsClose();\n _devtoolsClose = null;\n }\n}\n\n/**\n * @internal Get embedded devtools close handle.\n */\nexport function _getEmbeddedDevtoolsCloseForTesting():\n | (() => Promise<void> | void)\n | null {\n return _devtoolsClose;\n}\n\n/**\n * Get SDK instance (for shutdown)\n */\nexport function getSdk(): NodeSDK | null {\n return sdk;\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkUTZR7P7E_cjs = require('./chunk-UTZR7P7E.cjs');
|
|
4
4
|
var chunkGML3FBOT_cjs = require('./chunk-GML3FBOT.cjs');
|
|
5
5
|
var async_hooks = require('async_hooks');
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ var workflowContextStorage = new async_hooks.AsyncLocalStorage();
|
|
|
9
9
|
function traceWorkflow(config) {
|
|
10
10
|
const spanName = `workflow.${config.name}`;
|
|
11
11
|
return (fnFactory) => {
|
|
12
|
-
return
|
|
12
|
+
return chunkUTZR7P7E_cjs.trace(spanName, (baseCtx) => {
|
|
13
13
|
return async (...args) => {
|
|
14
14
|
const workflowId = typeof config.workflowId === "function" ? config.workflowId(...args) : config.workflowId;
|
|
15
15
|
const ctx = createWorkflowContext(baseCtx, config.name, workflowId);
|
|
@@ -61,7 +61,7 @@ function traceWorkflow(config) {
|
|
|
61
61
|
function traceStep(config) {
|
|
62
62
|
return (fn) => {
|
|
63
63
|
const spanName = `step.${config.name}`;
|
|
64
|
-
return
|
|
64
|
+
return chunkUTZR7P7E_cjs.trace(spanName, (baseCtx) => {
|
|
65
65
|
return async (...args) => {
|
|
66
66
|
const workflowCtx = workflowContextStorage.getStore() ?? null;
|
|
67
67
|
const ctx = createStepContext(baseCtx, config, workflowCtx);
|
|
@@ -339,5 +339,5 @@ exports.getCurrentWorkflowContext = getCurrentWorkflowContext;
|
|
|
339
339
|
exports.isInWorkflow = isInWorkflow;
|
|
340
340
|
exports.traceStep = traceStep;
|
|
341
341
|
exports.traceWorkflow = traceWorkflow;
|
|
342
|
-
//# sourceMappingURL=chunk-
|
|
343
|
-
//# sourceMappingURL=chunk-
|
|
342
|
+
//# sourceMappingURL=chunk-6YGUN7IY.cjs.map
|
|
343
|
+
//# sourceMappingURL=chunk-6YGUN7IY.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/workflow.ts"],"names":["AsyncLocalStorage","trace","getActiveSpan"],"mappings":"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","file":"chunk-EEJGUBWV.cjs","sourcesContent":["/**\n * Workflow and Saga tracing helpers\n *\n * Provides specialized tracing for multi-step workflows and sagas with\n * automatic step linking, compensation tracking, and workflow correlation.\n *\n * @example Simple workflow\n * ```typescript\n * import { traceWorkflow, traceStep } from 'autotel/workflow';\n *\n * export const processOrder = traceWorkflow({\n * name: 'OrderFulfillment',\n * workflowId: (order) => order.id,\n * })(ctx => async (order: Order) => {\n * await validateOrder(order);\n * await chargePayment(order);\n * await shipOrder(order);\n * });\n * ```\n *\n * @example Saga with compensation\n * ```typescript\n * import { traceWorkflow, traceStep } from 'autotel/workflow';\n *\n * export const orderSaga = traceWorkflow({\n * name: 'OrderSaga',\n * workflowId: () => generateUUID(),\n * })(ctx => async (order: Order) => {\n *\n * const reserveStep = traceStep({\n * name: 'ReserveInventory',\n * compensate: async () => {\n * await releaseInventory(order.items);\n * },\n * })(async () => {\n * await inventoryService.reserve(order.items);\n * });\n * await reserveStep();\n *\n * const paymentStep = traceStep({\n * name: 'ProcessPayment',\n * linkToPrevious: true,\n * compensate: async () => {\n * await refundPayment(order.paymentId);\n * },\n * })(async () => {\n * await paymentService.charge(order);\n * });\n * await paymentStep();\n * });\n * ```\n *\n * @module\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Attributes, Link, SpanContext } from '@opentelemetry/api';\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport { getActiveSpan } from './trace-helpers';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Workflow status\n */\nexport type WorkflowStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'compensating'\n | 'compensated'\n | 'compensation_failed';\n\n/**\n * Step status\n */\nexport type StepStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'skipped'\n | 'compensated';\n\n/**\n * Configuration for workflow tracing\n */\nexport interface WorkflowConfig<TArgs extends unknown[] = unknown[]> {\n /** Workflow name (e.g., 'OrderFulfillment', 'UserOnboarding') */\n name: string;\n\n /**\n * Function to extract or generate workflow ID\n * Can be static string, function of args, or generator\n */\n workflowId: string | ((...args: TArgs) => string);\n\n /** Optional workflow version */\n version?: string;\n\n /** Additional attributes */\n attributes?: Attributes;\n\n /** Callback on workflow completion */\n onComplete?: (ctx: WorkflowContext, result: unknown) => void;\n\n /** Callback on workflow failure */\n onFailed?: (ctx: WorkflowContext, error: Error) => void;\n\n /** Callback on compensation start */\n onCompensating?: (ctx: WorkflowContext) => void;\n}\n\n/**\n * Configuration for workflow step tracing\n */\nexport interface StepConfig {\n /** Step name */\n name: string;\n\n /** Optional step description */\n description?: string;\n\n /** Step index (auto-assigned if not provided) */\n index?: number;\n\n /** Link to previous step span */\n linkToPrevious?: boolean;\n\n /** Link to specific step(s) by name */\n linkTo?: string | string[];\n\n /** Additional attributes */\n attributes?: Attributes;\n\n /** Compensation handler for saga rollback */\n compensate?: (error: Error) => Promise<void> | void;\n\n /** Whether this step is idempotent */\n idempotent?: boolean;\n\n /** Retry configuration */\n retry?: {\n maxAttempts: number;\n backoffMs?: number;\n };\n\n /** Callback on step completion */\n onComplete?: (ctx: StepContext) => void;\n\n /** Callback on step failure */\n onFailed?: (ctx: StepContext, error: Error) => void;\n}\n\n/**\n * Step metadata stored for linking and compensation\n */\ninterface StepMetadata {\n name: string;\n index: number;\n status: StepStatus;\n spanContext?: SpanContext;\n compensate?: (error: Error) => Promise<void> | void;\n startTime: number;\n endTime?: number;\n}\n\n/**\n * Extended trace context for workflows\n */\nexport interface WorkflowContext extends TraceContext {\n /** Get the workflow ID */\n getWorkflowId(): string;\n\n /** Get workflow name */\n getWorkflowName(): string;\n\n /** Get current workflow status */\n getStatus(): WorkflowStatus;\n\n /** Mark step as completed and store for linking */\n completeStep(stepName: string): void;\n\n /** Get previous step's span context for linking */\n getPreviousStep(stepName?: string): SpanContext | null;\n\n /** Get all completed steps */\n getCompletedSteps(): string[];\n\n /** Register a compensation handler */\n registerCompensation(\n stepName: string,\n handler: (error: Error) => Promise<void> | void,\n ): void;\n\n /** Trigger compensation for all registered steps */\n compensate(error: Error): Promise<void>;\n\n /** Record compensation result */\n recordCompensation(stepName: string, success: boolean, error?: Error): void;\n\n /** Set workflow status */\n setWorkflowStatus(status: WorkflowStatus): void;\n}\n\n/**\n * Extended trace context for workflow steps\n */\nexport interface StepContext extends TraceContext {\n /** Get step name */\n getStepName(): string;\n\n /** Get step index */\n getStepIndex(): number;\n\n /** Mark this step as completed */\n complete(): void;\n\n /** Skip this step */\n skip(reason?: string): void;\n\n /** Get workflow context */\n getWorkflowContext(): WorkflowContext | null;\n}\n\n// ============================================================================\n// Storage\n// ============================================================================\n\n// Store workflow state in a WeakMap keyed by span\nconst workflowStates = new WeakMap<\n object,\n {\n workflowId: string;\n workflowName: string;\n status: WorkflowStatus;\n steps: Map<string, StepMetadata>;\n stepCounter: number;\n compensations: Map<string, (error: Error) => Promise<void> | void>;\n }\n>();\n\n/**\n * AsyncLocalStorage for workflow context (async-safe)\n *\n * This replaces the previous module-level variable which was NOT safe for\n * concurrent workflows. AsyncLocalStorage ensures each async execution chain\n * has its own isolated workflow context.\n */\nconst workflowContextStorage = new AsyncLocalStorage<WorkflowContext>();\n\n// ============================================================================\n// Workflow Helper\n// ============================================================================\n\n/**\n * Create a traced workflow function\n *\n * Wraps business logic in a workflow span with automatic step tracking,\n * correlation via workflow ID, and compensation support.\n *\n * @param config - Workflow configuration\n * @returns Factory function that wraps your workflow logic\n *\n * @example Order fulfillment workflow\n * ```typescript\n * export const fulfillOrder = traceWorkflow({\n * name: 'OrderFulfillment',\n * workflowId: (order) => order.id,\n * version: '2.0',\n * })(ctx => async (order: Order) => {\n * ctx.setAttribute('order.total', order.total);\n *\n * await validateOrder(order);\n * await processPayment(order);\n * await fulfillItems(order);\n * await notifyCustomer(order);\n *\n * return { success: true, orderId: order.id };\n * });\n * ```\n */\nexport function traceWorkflow<TArgs extends unknown[], TReturn>(\n config: WorkflowConfig<TArgs>,\n) {\n const spanName = `workflow.${config.name}`;\n\n return (\n fnFactory: (ctx: WorkflowContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>(spanName, (baseCtx) => {\n return async (...args: TArgs) => {\n // Generate or extract workflow ID\n const workflowId =\n typeof config.workflowId === 'function'\n ? config.workflowId(...args)\n : config.workflowId;\n\n // Create workflow context\n const ctx = createWorkflowContext(baseCtx, config.name, workflowId);\n\n // Set workflow attributes\n ctx.setAttribute('workflow.name', config.name);\n ctx.setAttribute('workflow.id', workflowId);\n if (config.version) {\n ctx.setAttribute('workflow.version', config.version);\n }\n ctx.setAttribute('workflow.status', 'running');\n\n // Set custom attributes\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n\n // Run workflow in AsyncLocalStorage context for async-safety\n // This ensures concurrent workflows have isolated contexts\n return workflowContextStorage.run(ctx, async () => {\n try {\n // Execute workflow\n const userFn = fnFactory(ctx);\n const result = await userFn(...args);\n\n // Mark as completed\n ctx.setWorkflowStatus('completed');\n config.onComplete?.(ctx, result);\n\n return result;\n } catch (error) {\n // Mark as failed\n ctx.setWorkflowStatus('failed');\n config.onFailed?.(ctx, error as Error);\n\n // Check if we have compensations to run\n const state = getWorkflowState();\n if (state && state.compensations.size > 0) {\n ctx.setWorkflowStatus('compensating');\n config.onCompensating?.(ctx);\n\n try {\n await ctx.compensate(error as Error);\n ctx.setWorkflowStatus('compensated');\n } catch (compensationError) {\n ctx.setWorkflowStatus('compensation_failed');\n ctx.setAttribute(\n 'workflow.compensation.error',\n String(compensationError),\n );\n }\n }\n\n throw error;\n }\n });\n };\n });\n };\n}\n\n/**\n * Create a traced workflow step\n *\n * Wraps step logic with automatic linking to previous steps,\n * compensation registration, and status tracking.\n *\n * @param config - Step configuration\n * @returns Factory function that wraps your step logic\n *\n * @example Step with compensation\n * ```typescript\n * const chargePayment = traceStep({\n * name: 'ChargePayment',\n * linkToPrevious: true,\n * compensate: async (error) => {\n * await paymentService.refund(paymentId);\n * },\n * })(async (amount: number) => {\n * return await paymentService.charge(amount);\n * });\n * ```\n */\nexport function traceStep<TArgs extends unknown[], TReturn>(\n config: StepConfig,\n) {\n return (\n fn: (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n const spanName = `step.${config.name}`;\n\n return trace<TArgs, TReturn>(spanName, (baseCtx) => {\n return async (...args: TArgs) => {\n // Get workflow context from AsyncLocalStorage (async-safe)\n const workflowCtx = workflowContextStorage.getStore() ?? null;\n\n // Create step context\n const ctx = createStepContext(baseCtx, config, workflowCtx);\n\n // Set step attributes\n ctx.setAttribute('workflow.step.name', config.name);\n ctx.setAttribute('workflow.step.index', ctx.getStepIndex());\n ctx.setAttribute('workflow.step.status', 'running');\n\n if (config.description) {\n ctx.setAttribute('workflow.step.description', config.description);\n }\n\n if (config.idempotent) {\n ctx.setAttribute('workflow.step.idempotent', true);\n }\n\n // Set custom attributes\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n\n // Link to previous steps\n await addStepLinks(ctx, config, workflowCtx);\n\n // Register compensation if provided\n if (config.compensate && workflowCtx) {\n workflowCtx.registerCompensation(config.name, config.compensate);\n }\n\n // Execute with optional retry\n let lastError: Error | undefined;\n const maxAttempts = config.retry?.maxAttempts ?? 1;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n if (attempt > 1) {\n ctx.setAttribute('workflow.step.retry_attempt', attempt);\n ctx.addEvent('step_retry', {\n 'workflow.step.attempt': attempt,\n 'workflow.step.max_attempts': maxAttempts,\n });\n\n // Backoff\n if (config.retry?.backoffMs) {\n await sleep(config.retry.backoffMs * attempt);\n }\n }\n\n const result = await fn(...args);\n\n // Mark as completed\n ctx.setAttribute('workflow.step.status', 'completed');\n ctx.complete();\n config.onComplete?.(ctx);\n\n return result;\n } catch (error) {\n lastError = error as Error;\n\n if (attempt < maxAttempts) {\n ctx.addEvent('step_retry_scheduled', {\n 'workflow.step.error': String(error),\n 'workflow.step.attempt': attempt,\n });\n }\n }\n }\n\n // All attempts failed\n ctx.setAttribute('workflow.step.status', 'failed');\n ctx.setAttribute('workflow.step.error', String(lastError));\n config.onFailed?.(ctx, lastError!);\n\n throw lastError;\n };\n });\n };\n}\n\n// ============================================================================\n// Context Creation\n// ============================================================================\n\n/**\n * Create workflow-extended context\n */\nfunction createWorkflowContext(\n baseCtx: TraceContext,\n workflowName: string,\n workflowId: string,\n): WorkflowContext {\n // Initialize state\n const span = getActiveSpan();\n const state = {\n workflowId,\n workflowName,\n status: 'running' as WorkflowStatus,\n steps: new Map<string, StepMetadata>(),\n stepCounter: 0,\n compensations: new Map<string, (error: Error) => Promise<void> | void>(),\n };\n\n if (span) {\n workflowStates.set(span, state);\n }\n\n return {\n ...baseCtx,\n\n getWorkflowId(): string {\n return workflowId;\n },\n\n getWorkflowName(): string {\n return workflowName;\n },\n\n getStatus(): WorkflowStatus {\n return state.status;\n },\n\n completeStep(stepName: string): void {\n let step = state.steps.get(stepName);\n if (!step) {\n // Auto-create step entry for manually managed steps\n // (when using registerCompensation without traceStep)\n step = {\n name: stepName,\n index: state.stepCounter++,\n status: 'pending',\n startTime: Date.now(),\n };\n state.steps.set(stepName, step);\n }\n step.status = 'completed';\n step.endTime = Date.now();\n\n // Capture span context for linking\n const currentSpan = getActiveSpan();\n if (currentSpan) {\n step.spanContext = currentSpan.spanContext();\n }\n },\n\n getPreviousStep(stepName?: string): SpanContext | null {\n if (stepName) {\n const step = state.steps.get(stepName);\n return step?.spanContext ?? null;\n }\n\n // Get last completed step\n let lastStep: StepMetadata | null = null;\n for (const step of state.steps.values()) {\n if (\n step.status === 'completed' &&\n (!lastStep || step.index > lastStep.index)\n ) {\n lastStep = step;\n }\n }\n\n return lastStep?.spanContext ?? null;\n },\n\n getCompletedSteps(): string[] {\n const completed: string[] = [];\n for (const [name, step] of state.steps) {\n if (step.status === 'completed') {\n completed.push(name);\n }\n }\n return completed.toSorted(\n (a, b) =>\n (state.steps.get(a)?.index ?? 0) - (state.steps.get(b)?.index ?? 0),\n );\n },\n\n registerCompensation(\n stepName: string,\n handler: (error: Error) => Promise<void> | void,\n ): void {\n state.compensations.set(stepName, handler);\n },\n\n async compensate(error: Error): Promise<void> {\n // Execute compensations in reverse order\n const compensationOrder = [...state.compensations.entries()].toReversed();\n\n for (const [stepName, handler] of compensationOrder) {\n const step = state.steps.get(stepName);\n if (step && step.status === 'completed') {\n try {\n baseCtx.addEvent('compensation_started', {\n 'workflow.step.name': stepName,\n });\n\n await Promise.resolve(handler(error));\n\n this.recordCompensation(stepName, true);\n step.status = 'compensated';\n } catch (compensationError) {\n this.recordCompensation(\n stepName,\n false,\n compensationError as Error,\n );\n throw compensationError;\n }\n }\n }\n },\n\n recordCompensation(\n stepName: string,\n success: boolean,\n error?: Error,\n ): void {\n baseCtx.addEvent('compensation_completed', {\n 'workflow.step.name': stepName,\n 'workflow.compensation.success': success,\n ...(error && { 'workflow.compensation.error': String(error) }),\n });\n\n baseCtx.setAttribute(\n `workflow.compensation.${stepName}`,\n success ? 'success' : 'failed',\n );\n },\n\n setWorkflowStatus(status: WorkflowStatus): void {\n state.status = status;\n baseCtx.setAttribute('workflow.status', status);\n\n baseCtx.addEvent('workflow_status_changed', {\n 'workflow.status': status,\n });\n },\n };\n}\n\n/**\n * Create step-extended context\n */\nfunction createStepContext(\n baseCtx: TraceContext,\n config: StepConfig,\n workflowCtx: WorkflowContext | null,\n): StepContext {\n // Determine step index\n let stepIndex = config.index ?? 0;\n if (workflowCtx) {\n const span = getActiveSpan();\n if (span) {\n const state = workflowStates.get(span);\n if (state) {\n stepIndex = config.index ?? state.stepCounter++;\n }\n }\n }\n\n // Register step metadata\n if (workflowCtx) {\n const wfSpan = getActiveSpan();\n if (wfSpan) {\n const state = workflowStates.get(wfSpan);\n if (state) {\n state.steps.set(config.name, {\n name: config.name,\n index: stepIndex,\n status: 'running',\n startTime: Date.now(),\n compensate: config.compensate,\n });\n }\n }\n }\n\n return {\n ...baseCtx,\n\n getStepName(): string {\n return config.name;\n },\n\n getStepIndex(): number {\n return stepIndex;\n },\n\n complete(): void {\n if (workflowCtx) {\n workflowCtx.completeStep(config.name);\n }\n },\n\n skip(reason?: string): void {\n baseCtx.setAttribute('workflow.step.status', 'skipped');\n if (reason) {\n baseCtx.setAttribute('workflow.step.skip_reason', reason);\n }\n baseCtx.addEvent('step_skipped', {\n 'workflow.step.name': config.name,\n ...(reason && { 'workflow.step.skip_reason': reason }),\n });\n },\n\n getWorkflowContext(): WorkflowContext | null {\n return workflowCtx;\n },\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get workflow state from context\n */\nfunction getWorkflowState() {\n const span = getActiveSpan();\n return span ? workflowStates.get(span) : null;\n}\n\n/**\n * Add links to previous steps\n */\nasync function addStepLinks(\n ctx: StepContext,\n config: StepConfig,\n workflowCtx: WorkflowContext | null,\n): Promise<void> {\n if (!workflowCtx) return;\n\n const links: Link[] = [];\n\n // Link to previous step\n if (config.linkToPrevious) {\n const prevSpanContext = workflowCtx.getPreviousStep();\n if (prevSpanContext) {\n links.push({\n context: prevSpanContext,\n attributes: {\n 'workflow.link.type': 'sequence',\n },\n });\n }\n }\n\n // Link to specific steps\n if (config.linkTo) {\n const stepNames = Array.isArray(config.linkTo)\n ? config.linkTo\n : [config.linkTo];\n\n for (const stepName of stepNames) {\n const spanContext = workflowCtx.getPreviousStep(stepName);\n if (spanContext) {\n links.push({\n context: spanContext,\n attributes: {\n 'workflow.link.type': 'dependency',\n 'workflow.link.step': stepName,\n },\n });\n }\n }\n }\n\n // Add all links\n if (links.length > 0) {\n ctx.addLinks(links);\n }\n}\n\n/**\n * Sleep utility for retry backoff\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ============================================================================\n// Convenience Exports\n// ============================================================================\n\n/**\n * Get current workflow context (if inside a workflow)\n *\n * Uses AsyncLocalStorage to ensure async-safety when multiple\n * workflows are running concurrently.\n */\nexport function getCurrentWorkflowContext(): WorkflowContext | null {\n return workflowContextStorage.getStore() ?? null;\n}\n\n/**\n * Check if currently executing inside a workflow\n *\n * Uses AsyncLocalStorage to ensure async-safety when multiple\n * workflows are running concurrently.\n */\nexport function isInWorkflow(): boolean {\n return workflowContextStorage.getStore() !== undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/workflow.ts"],"names":["AsyncLocalStorage","trace","getActiveSpan"],"mappings":"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","file":"chunk-6YGUN7IY.cjs","sourcesContent":["/**\n * Workflow and Saga tracing helpers\n *\n * Provides specialized tracing for multi-step workflows and sagas with\n * automatic step linking, compensation tracking, and workflow correlation.\n *\n * @example Simple workflow\n * ```typescript\n * import { traceWorkflow, traceStep } from 'autotel/workflow';\n *\n * export const processOrder = traceWorkflow({\n * name: 'OrderFulfillment',\n * workflowId: (order) => order.id,\n * })(ctx => async (order: Order) => {\n * await validateOrder(order);\n * await chargePayment(order);\n * await shipOrder(order);\n * });\n * ```\n *\n * @example Saga with compensation\n * ```typescript\n * import { traceWorkflow, traceStep } from 'autotel/workflow';\n *\n * export const orderSaga = traceWorkflow({\n * name: 'OrderSaga',\n * workflowId: () => generateUUID(),\n * })(ctx => async (order: Order) => {\n *\n * const reserveStep = traceStep({\n * name: 'ReserveInventory',\n * compensate: async () => {\n * await releaseInventory(order.items);\n * },\n * })(async () => {\n * await inventoryService.reserve(order.items);\n * });\n * await reserveStep();\n *\n * const paymentStep = traceStep({\n * name: 'ProcessPayment',\n * linkToPrevious: true,\n * compensate: async () => {\n * await refundPayment(order.paymentId);\n * },\n * })(async () => {\n * await paymentService.charge(order);\n * });\n * await paymentStep();\n * });\n * ```\n *\n * @module\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Attributes, Link, SpanContext } from '@opentelemetry/api';\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport { getActiveSpan } from './trace-helpers';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Workflow status\n */\nexport type WorkflowStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'compensating'\n | 'compensated'\n | 'compensation_failed';\n\n/**\n * Step status\n */\nexport type StepStatus =\n | 'pending'\n | 'running'\n | 'completed'\n | 'failed'\n | 'skipped'\n | 'compensated';\n\n/**\n * Configuration for workflow tracing\n */\nexport interface WorkflowConfig<TArgs extends unknown[] = unknown[]> {\n /** Workflow name (e.g., 'OrderFulfillment', 'UserOnboarding') */\n name: string;\n\n /**\n * Function to extract or generate workflow ID\n * Can be static string, function of args, or generator\n */\n workflowId: string | ((...args: TArgs) => string);\n\n /** Optional workflow version */\n version?: string;\n\n /** Additional attributes */\n attributes?: Attributes;\n\n /** Callback on workflow completion */\n onComplete?: (ctx: WorkflowContext, result: unknown) => void;\n\n /** Callback on workflow failure */\n onFailed?: (ctx: WorkflowContext, error: Error) => void;\n\n /** Callback on compensation start */\n onCompensating?: (ctx: WorkflowContext) => void;\n}\n\n/**\n * Configuration for workflow step tracing\n */\nexport interface StepConfig {\n /** Step name */\n name: string;\n\n /** Optional step description */\n description?: string;\n\n /** Step index (auto-assigned if not provided) */\n index?: number;\n\n /** Link to previous step span */\n linkToPrevious?: boolean;\n\n /** Link to specific step(s) by name */\n linkTo?: string | string[];\n\n /** Additional attributes */\n attributes?: Attributes;\n\n /** Compensation handler for saga rollback */\n compensate?: (error: Error) => Promise<void> | void;\n\n /** Whether this step is idempotent */\n idempotent?: boolean;\n\n /** Retry configuration */\n retry?: {\n maxAttempts: number;\n backoffMs?: number;\n };\n\n /** Callback on step completion */\n onComplete?: (ctx: StepContext) => void;\n\n /** Callback on step failure */\n onFailed?: (ctx: StepContext, error: Error) => void;\n}\n\n/**\n * Step metadata stored for linking and compensation\n */\ninterface StepMetadata {\n name: string;\n index: number;\n status: StepStatus;\n spanContext?: SpanContext;\n compensate?: (error: Error) => Promise<void> | void;\n startTime: number;\n endTime?: number;\n}\n\n/**\n * Extended trace context for workflows\n */\nexport interface WorkflowContext extends TraceContext {\n /** Get the workflow ID */\n getWorkflowId(): string;\n\n /** Get workflow name */\n getWorkflowName(): string;\n\n /** Get current workflow status */\n getStatus(): WorkflowStatus;\n\n /** Mark step as completed and store for linking */\n completeStep(stepName: string): void;\n\n /** Get previous step's span context for linking */\n getPreviousStep(stepName?: string): SpanContext | null;\n\n /** Get all completed steps */\n getCompletedSteps(): string[];\n\n /** Register a compensation handler */\n registerCompensation(\n stepName: string,\n handler: (error: Error) => Promise<void> | void,\n ): void;\n\n /** Trigger compensation for all registered steps */\n compensate(error: Error): Promise<void>;\n\n /** Record compensation result */\n recordCompensation(stepName: string, success: boolean, error?: Error): void;\n\n /** Set workflow status */\n setWorkflowStatus(status: WorkflowStatus): void;\n}\n\n/**\n * Extended trace context for workflow steps\n */\nexport interface StepContext extends TraceContext {\n /** Get step name */\n getStepName(): string;\n\n /** Get step index */\n getStepIndex(): number;\n\n /** Mark this step as completed */\n complete(): void;\n\n /** Skip this step */\n skip(reason?: string): void;\n\n /** Get workflow context */\n getWorkflowContext(): WorkflowContext | null;\n}\n\n// ============================================================================\n// Storage\n// ============================================================================\n\n// Store workflow state in a WeakMap keyed by span\nconst workflowStates = new WeakMap<\n object,\n {\n workflowId: string;\n workflowName: string;\n status: WorkflowStatus;\n steps: Map<string, StepMetadata>;\n stepCounter: number;\n compensations: Map<string, (error: Error) => Promise<void> | void>;\n }\n>();\n\n/**\n * AsyncLocalStorage for workflow context (async-safe)\n *\n * This replaces the previous module-level variable which was NOT safe for\n * concurrent workflows. AsyncLocalStorage ensures each async execution chain\n * has its own isolated workflow context.\n */\nconst workflowContextStorage = new AsyncLocalStorage<WorkflowContext>();\n\n// ============================================================================\n// Workflow Helper\n// ============================================================================\n\n/**\n * Create a traced workflow function\n *\n * Wraps business logic in a workflow span with automatic step tracking,\n * correlation via workflow ID, and compensation support.\n *\n * @param config - Workflow configuration\n * @returns Factory function that wraps your workflow logic\n *\n * @example Order fulfillment workflow\n * ```typescript\n * export const fulfillOrder = traceWorkflow({\n * name: 'OrderFulfillment',\n * workflowId: (order) => order.id,\n * version: '2.0',\n * })(ctx => async (order: Order) => {\n * ctx.setAttribute('order.total', order.total);\n *\n * await validateOrder(order);\n * await processPayment(order);\n * await fulfillItems(order);\n * await notifyCustomer(order);\n *\n * return { success: true, orderId: order.id };\n * });\n * ```\n */\nexport function traceWorkflow<TArgs extends unknown[], TReturn>(\n config: WorkflowConfig<TArgs>,\n) {\n const spanName = `workflow.${config.name}`;\n\n return (\n fnFactory: (ctx: WorkflowContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>(spanName, (baseCtx) => {\n return async (...args: TArgs) => {\n // Generate or extract workflow ID\n const workflowId =\n typeof config.workflowId === 'function'\n ? config.workflowId(...args)\n : config.workflowId;\n\n // Create workflow context\n const ctx = createWorkflowContext(baseCtx, config.name, workflowId);\n\n // Set workflow attributes\n ctx.setAttribute('workflow.name', config.name);\n ctx.setAttribute('workflow.id', workflowId);\n if (config.version) {\n ctx.setAttribute('workflow.version', config.version);\n }\n ctx.setAttribute('workflow.status', 'running');\n\n // Set custom attributes\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n\n // Run workflow in AsyncLocalStorage context for async-safety\n // This ensures concurrent workflows have isolated contexts\n return workflowContextStorage.run(ctx, async () => {\n try {\n // Execute workflow\n const userFn = fnFactory(ctx);\n const result = await userFn(...args);\n\n // Mark as completed\n ctx.setWorkflowStatus('completed');\n config.onComplete?.(ctx, result);\n\n return result;\n } catch (error) {\n // Mark as failed\n ctx.setWorkflowStatus('failed');\n config.onFailed?.(ctx, error as Error);\n\n // Check if we have compensations to run\n const state = getWorkflowState();\n if (state && state.compensations.size > 0) {\n ctx.setWorkflowStatus('compensating');\n config.onCompensating?.(ctx);\n\n try {\n await ctx.compensate(error as Error);\n ctx.setWorkflowStatus('compensated');\n } catch (compensationError) {\n ctx.setWorkflowStatus('compensation_failed');\n ctx.setAttribute(\n 'workflow.compensation.error',\n String(compensationError),\n );\n }\n }\n\n throw error;\n }\n });\n };\n });\n };\n}\n\n/**\n * Create a traced workflow step\n *\n * Wraps step logic with automatic linking to previous steps,\n * compensation registration, and status tracking.\n *\n * @param config - Step configuration\n * @returns Factory function that wraps your step logic\n *\n * @example Step with compensation\n * ```typescript\n * const chargePayment = traceStep({\n * name: 'ChargePayment',\n * linkToPrevious: true,\n * compensate: async (error) => {\n * await paymentService.refund(paymentId);\n * },\n * })(async (amount: number) => {\n * return await paymentService.charge(amount);\n * });\n * ```\n */\nexport function traceStep<TArgs extends unknown[], TReturn>(\n config: StepConfig,\n) {\n return (\n fn: (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n const spanName = `step.${config.name}`;\n\n return trace<TArgs, TReturn>(spanName, (baseCtx) => {\n return async (...args: TArgs) => {\n // Get workflow context from AsyncLocalStorage (async-safe)\n const workflowCtx = workflowContextStorage.getStore() ?? null;\n\n // Create step context\n const ctx = createStepContext(baseCtx, config, workflowCtx);\n\n // Set step attributes\n ctx.setAttribute('workflow.step.name', config.name);\n ctx.setAttribute('workflow.step.index', ctx.getStepIndex());\n ctx.setAttribute('workflow.step.status', 'running');\n\n if (config.description) {\n ctx.setAttribute('workflow.step.description', config.description);\n }\n\n if (config.idempotent) {\n ctx.setAttribute('workflow.step.idempotent', true);\n }\n\n // Set custom attributes\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n\n // Link to previous steps\n await addStepLinks(ctx, config, workflowCtx);\n\n // Register compensation if provided\n if (config.compensate && workflowCtx) {\n workflowCtx.registerCompensation(config.name, config.compensate);\n }\n\n // Execute with optional retry\n let lastError: Error | undefined;\n const maxAttempts = config.retry?.maxAttempts ?? 1;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n if (attempt > 1) {\n ctx.setAttribute('workflow.step.retry_attempt', attempt);\n ctx.addEvent('step_retry', {\n 'workflow.step.attempt': attempt,\n 'workflow.step.max_attempts': maxAttempts,\n });\n\n // Backoff\n if (config.retry?.backoffMs) {\n await sleep(config.retry.backoffMs * attempt);\n }\n }\n\n const result = await fn(...args);\n\n // Mark as completed\n ctx.setAttribute('workflow.step.status', 'completed');\n ctx.complete();\n config.onComplete?.(ctx);\n\n return result;\n } catch (error) {\n lastError = error as Error;\n\n if (attempt < maxAttempts) {\n ctx.addEvent('step_retry_scheduled', {\n 'workflow.step.error': String(error),\n 'workflow.step.attempt': attempt,\n });\n }\n }\n }\n\n // All attempts failed\n ctx.setAttribute('workflow.step.status', 'failed');\n ctx.setAttribute('workflow.step.error', String(lastError));\n config.onFailed?.(ctx, lastError!);\n\n throw lastError;\n };\n });\n };\n}\n\n// ============================================================================\n// Context Creation\n// ============================================================================\n\n/**\n * Create workflow-extended context\n */\nfunction createWorkflowContext(\n baseCtx: TraceContext,\n workflowName: string,\n workflowId: string,\n): WorkflowContext {\n // Initialize state\n const span = getActiveSpan();\n const state = {\n workflowId,\n workflowName,\n status: 'running' as WorkflowStatus,\n steps: new Map<string, StepMetadata>(),\n stepCounter: 0,\n compensations: new Map<string, (error: Error) => Promise<void> | void>(),\n };\n\n if (span) {\n workflowStates.set(span, state);\n }\n\n return {\n ...baseCtx,\n\n getWorkflowId(): string {\n return workflowId;\n },\n\n getWorkflowName(): string {\n return workflowName;\n },\n\n getStatus(): WorkflowStatus {\n return state.status;\n },\n\n completeStep(stepName: string): void {\n let step = state.steps.get(stepName);\n if (!step) {\n // Auto-create step entry for manually managed steps\n // (when using registerCompensation without traceStep)\n step = {\n name: stepName,\n index: state.stepCounter++,\n status: 'pending',\n startTime: Date.now(),\n };\n state.steps.set(stepName, step);\n }\n step.status = 'completed';\n step.endTime = Date.now();\n\n // Capture span context for linking\n const currentSpan = getActiveSpan();\n if (currentSpan) {\n step.spanContext = currentSpan.spanContext();\n }\n },\n\n getPreviousStep(stepName?: string): SpanContext | null {\n if (stepName) {\n const step = state.steps.get(stepName);\n return step?.spanContext ?? null;\n }\n\n // Get last completed step\n let lastStep: StepMetadata | null = null;\n for (const step of state.steps.values()) {\n if (\n step.status === 'completed' &&\n (!lastStep || step.index > lastStep.index)\n ) {\n lastStep = step;\n }\n }\n\n return lastStep?.spanContext ?? null;\n },\n\n getCompletedSteps(): string[] {\n const completed: string[] = [];\n for (const [name, step] of state.steps) {\n if (step.status === 'completed') {\n completed.push(name);\n }\n }\n return completed.toSorted(\n (a, b) =>\n (state.steps.get(a)?.index ?? 0) - (state.steps.get(b)?.index ?? 0),\n );\n },\n\n registerCompensation(\n stepName: string,\n handler: (error: Error) => Promise<void> | void,\n ): void {\n state.compensations.set(stepName, handler);\n },\n\n async compensate(error: Error): Promise<void> {\n // Execute compensations in reverse order\n const compensationOrder = [...state.compensations.entries()].toReversed();\n\n for (const [stepName, handler] of compensationOrder) {\n const step = state.steps.get(stepName);\n if (step && step.status === 'completed') {\n try {\n baseCtx.addEvent('compensation_started', {\n 'workflow.step.name': stepName,\n });\n\n await Promise.resolve(handler(error));\n\n this.recordCompensation(stepName, true);\n step.status = 'compensated';\n } catch (compensationError) {\n this.recordCompensation(\n stepName,\n false,\n compensationError as Error,\n );\n throw compensationError;\n }\n }\n }\n },\n\n recordCompensation(\n stepName: string,\n success: boolean,\n error?: Error,\n ): void {\n baseCtx.addEvent('compensation_completed', {\n 'workflow.step.name': stepName,\n 'workflow.compensation.success': success,\n ...(error && { 'workflow.compensation.error': String(error) }),\n });\n\n baseCtx.setAttribute(\n `workflow.compensation.${stepName}`,\n success ? 'success' : 'failed',\n );\n },\n\n setWorkflowStatus(status: WorkflowStatus): void {\n state.status = status;\n baseCtx.setAttribute('workflow.status', status);\n\n baseCtx.addEvent('workflow_status_changed', {\n 'workflow.status': status,\n });\n },\n };\n}\n\n/**\n * Create step-extended context\n */\nfunction createStepContext(\n baseCtx: TraceContext,\n config: StepConfig,\n workflowCtx: WorkflowContext | null,\n): StepContext {\n // Determine step index\n let stepIndex = config.index ?? 0;\n if (workflowCtx) {\n const span = getActiveSpan();\n if (span) {\n const state = workflowStates.get(span);\n if (state) {\n stepIndex = config.index ?? state.stepCounter++;\n }\n }\n }\n\n // Register step metadata\n if (workflowCtx) {\n const wfSpan = getActiveSpan();\n if (wfSpan) {\n const state = workflowStates.get(wfSpan);\n if (state) {\n state.steps.set(config.name, {\n name: config.name,\n index: stepIndex,\n status: 'running',\n startTime: Date.now(),\n compensate: config.compensate,\n });\n }\n }\n }\n\n return {\n ...baseCtx,\n\n getStepName(): string {\n return config.name;\n },\n\n getStepIndex(): number {\n return stepIndex;\n },\n\n complete(): void {\n if (workflowCtx) {\n workflowCtx.completeStep(config.name);\n }\n },\n\n skip(reason?: string): void {\n baseCtx.setAttribute('workflow.step.status', 'skipped');\n if (reason) {\n baseCtx.setAttribute('workflow.step.skip_reason', reason);\n }\n baseCtx.addEvent('step_skipped', {\n 'workflow.step.name': config.name,\n ...(reason && { 'workflow.step.skip_reason': reason }),\n });\n },\n\n getWorkflowContext(): WorkflowContext | null {\n return workflowCtx;\n },\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get workflow state from context\n */\nfunction getWorkflowState() {\n const span = getActiveSpan();\n return span ? workflowStates.get(span) : null;\n}\n\n/**\n * Add links to previous steps\n */\nasync function addStepLinks(\n ctx: StepContext,\n config: StepConfig,\n workflowCtx: WorkflowContext | null,\n): Promise<void> {\n if (!workflowCtx) return;\n\n const links: Link[] = [];\n\n // Link to previous step\n if (config.linkToPrevious) {\n const prevSpanContext = workflowCtx.getPreviousStep();\n if (prevSpanContext) {\n links.push({\n context: prevSpanContext,\n attributes: {\n 'workflow.link.type': 'sequence',\n },\n });\n }\n }\n\n // Link to specific steps\n if (config.linkTo) {\n const stepNames = Array.isArray(config.linkTo)\n ? config.linkTo\n : [config.linkTo];\n\n for (const stepName of stepNames) {\n const spanContext = workflowCtx.getPreviousStep(stepName);\n if (spanContext) {\n links.push({\n context: spanContext,\n attributes: {\n 'workflow.link.type': 'dependency',\n 'workflow.link.step': stepName,\n },\n });\n }\n }\n }\n\n // Add all links\n if (links.length > 0) {\n ctx.addLinks(links);\n }\n}\n\n/**\n * Sleep utility for retry backoff\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ============================================================================\n// Convenience Exports\n// ============================================================================\n\n/**\n * Get current workflow context (if inside a workflow)\n *\n * Uses AsyncLocalStorage to ensure async-safety when multiple\n * workflows are running concurrently.\n */\nexport function getCurrentWorkflowContext(): WorkflowContext | null {\n return workflowContextStorage.getStore() ?? null;\n}\n\n/**\n * Check if currently executing inside a workflow\n *\n * Uses AsyncLocalStorage to ensure async-safety when multiple\n * workflows are running concurrently.\n */\nexport function isInWorkflow(): boolean {\n return workflowContextStorage.getStore() !== undefined;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AUTOTEL_SAMPLING_TAIL_EVALUATED, AUTOTEL_SAMPLING_TAIL_KEEP } from './chunk-
|
|
1
|
+
import { AUTOTEL_SAMPLING_TAIL_EVALUATED, AUTOTEL_SAMPLING_TAIL_KEEP } from './chunk-DPSA4QLA.js';
|
|
2
2
|
|
|
3
3
|
// src/tail-sampling-processor.ts
|
|
4
4
|
var TailSamplingSpanProcessor = class {
|
|
@@ -26,5 +26,5 @@ var TailSamplingSpanProcessor = class {
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export { TailSamplingSpanProcessor };
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-A4E5AQFK.js.map
|
|
30
|
+
//# sourceMappingURL=chunk-A4E5AQFK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tail-sampling-processor.ts"],"names":[],"mappings":";;;AAyBO,IAAM,4BAAN,MAAyD;AAAA,EACtD,gBAAA;AAAA,EAER,YAAY,gBAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,gBAAA,GAAmB,gBAAA;AAAA,EAC1B;AAAA,EAEA,OAAA,CAAQ,MAAY,aAAA,EAA8B;AAChD,IAAA,IAAA,CAAK,gBAAA,CAAiB,OAAA,CAAQ,IAAA,EAAM,aAAa,CAAA;AAAA,EACnD;AAAA,EAEA,MAAM,IAAA,EAA0B;AAC9B,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,UAAA,CAAW,+BAA+B,CAAA;AACrE,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,CAAW,0BAA0B,CAAA;AAE7D,IAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,UAAA,KAAe,KAAA,EAAO;AAClD,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,gBAAA,CAAiB,MAAM,IAAI,CAAA;AAAA,EAClC;AAAA,EAEA,UAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,iBAAiB,UAAA,EAAW;AAAA,EAC1C;AAAA,EAEA,QAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,iBAAiB,QAAA,EAAS;AAAA,EACxC;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/tail-sampling-processor.ts"],"names":[],"mappings":";;;AAyBO,IAAM,4BAAN,MAAyD;AAAA,EACtD,gBAAA;AAAA,EAER,YAAY,gBAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,gBAAA,GAAmB,gBAAA;AAAA,EAC1B;AAAA,EAEA,OAAA,CAAQ,MAAY,aAAA,EAA8B;AAChD,IAAA,IAAA,CAAK,gBAAA,CAAiB,OAAA,CAAQ,IAAA,EAAM,aAAa,CAAA;AAAA,EACnD;AAAA,EAEA,MAAM,IAAA,EAA0B;AAC9B,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,UAAA,CAAW,+BAA+B,CAAA;AACrE,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,CAAW,0BAA0B,CAAA;AAE7D,IAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,UAAA,KAAe,KAAA,EAAO;AAClD,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,gBAAA,CAAiB,MAAM,IAAI,CAAA;AAAA,EAClC;AAAA,EAEA,UAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,iBAAiB,UAAA,EAAW;AAAA,EAC1C;AAAA,EAEA,QAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,iBAAiB,QAAA,EAAS;AAAA,EACxC;AACF","file":"chunk-A4E5AQFK.js","sourcesContent":["/**\n * Tail Sampling Span Processor\n *\n * Filters spans based on the `autotel.sampling.tail.keep` attribute set during execution.\n * This enables adaptive sampling where we decide whether to keep a span AFTER\n * the operation completes, based on criteria like errors, duration, etc.\n *\n * How it works:\n * 1. Decorator creates span optimistically (head sampling returns true)\n * 2. Operation executes and completes\n * 3. Decorator calls shouldKeepTrace() and sets autotel.sampling.tail.keep attribute\n * 4. This processor checks the attribute and drops spans marked as false\n */\n\nimport type {\n SpanProcessor,\n ReadableSpan,\n} from '@opentelemetry/sdk-trace-base';\nimport type { Context } from '@opentelemetry/api';\nimport type { Span } from '@opentelemetry/sdk-trace-base';\nimport {\n AUTOTEL_SAMPLING_TAIL_KEEP,\n AUTOTEL_SAMPLING_TAIL_EVALUATED,\n} from './sampling';\n\nexport class TailSamplingSpanProcessor implements SpanProcessor {\n private wrappedProcessor: SpanProcessor;\n\n constructor(wrappedProcessor: SpanProcessor) {\n this.wrappedProcessor = wrappedProcessor;\n }\n\n onStart(span: Span, parentContext: Context): void {\n this.wrappedProcessor.onStart(span, parentContext);\n }\n\n onEnd(span: ReadableSpan): void {\n const tailEvaluated = span.attributes[AUTOTEL_SAMPLING_TAIL_EVALUATED];\n const shouldKeep = span.attributes[AUTOTEL_SAMPLING_TAIL_KEEP];\n\n if (tailEvaluated === true && shouldKeep === false) {\n return;\n }\n\n this.wrappedProcessor.onEnd(span);\n }\n\n forceFlush(): Promise<void> {\n return this.wrappedProcessor.forceFlush();\n }\n\n shutdown(): Promise<void> {\n return this.wrappedProcessor.shutdown();\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getOperationContext, validateEvent } from './chunk-WD4RP6IV.js';
|
|
2
2
|
import { getOrCreateCorrelationId } from './chunk-S4OFEXLA.js';
|
|
3
|
-
import { getConfig, getEventsConfig, getValidationConfig, getLogger } from './chunk-
|
|
3
|
+
import { getConfig, getEventsConfig, getValidationConfig, getLogger } from './chunk-W35FVJBC.js';
|
|
4
4
|
import { trace, context, propagation } from '@opentelemetry/api';
|
|
5
5
|
|
|
6
6
|
// src/circuit-breaker.ts
|
|
@@ -829,5 +829,5 @@ function resetEvents() {
|
|
|
829
829
|
}
|
|
830
830
|
|
|
831
831
|
export { Event, getEvents, resetEvents };
|
|
832
|
-
//# sourceMappingURL=chunk-
|
|
833
|
-
//# sourceMappingURL=chunk-
|
|
832
|
+
//# sourceMappingURL=chunk-BJ2XPN77.js.map
|
|
833
|
+
//# sourceMappingURL=chunk-BJ2XPN77.js.map
|