autotel
Version:
Write Once, Observe Anywhere
1 lines • 93.8 kB
Source Map (JSON)
{"version":3,"sources":["../src/baggage-span-processor.ts","../src/redact-values.ts","../src/posthog-logs.ts","../src/env-config.ts","../src/init.ts"],"names":["propagation","otelContext","requireModule","config","REDACTOR_PRESETS","safeRequire","OTLPTraceExporterHTTP","OTLPMetricExporterHTTP","loadYamlConfig","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","TailSamplingSpanProcessor","BatchSpanProcessor","SimpleSpanProcessor","PrettyConsoleExporter","ConsoleSpanExporter","CanonicalLogLineProcessor","AttributeRedactingProcessor","SpanNameNormalizingProcessor","FilteringSpanProcessor","PeriodicExportingMetricReader","NodeSDK"],"mappings":"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","file":"chunk-GIND746I.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\nclass 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 */\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}\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}\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 return env;\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 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","/**\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} from '@opentelemetry/sdk-trace-base';\nimport type { SpanExporter } 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 } from './sampling';\nimport { AdaptiveSampler } from './sampling';\nimport type { EventSubscriber } from './event-subscriber';\nimport type { Logger } from './logger';\nimport type { Attributes } 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 type { PushMetricExporter } from '@opentelemetry/sdk-metrics';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { buildPostHogLogProcessors } 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 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';\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// 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;\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: 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',\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 /** 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 /** Sampling strategy (default: AdaptiveSampler with 10% baseline) */\n sampler?: Sampler;\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// Internal state\nlet initialized = 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;\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 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 // 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 ...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 // Set logger (use provided or default to silent - no spam)\n logger = mergedConfig.logger || silentLogger;\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 const endpoint = mergedConfig.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\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 // 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 sdkOptions: Partial<NodeSDKConfiguration> = {\n resource,\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 (\n config?.sampler ||\n new AdaptiveSampler({\n baselineSampleRate: 0.1,\n alwaysSampleErrors: true,\n alwaysSampleSlow: true,\n })\n );\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 * Get SDK instance (for shutdown)\n */\nexport function getSdk(): NodeSDK | null {\n return sdk;\n}\n"]}