import type { Tracer } from '@opentelemetry/api' import { trace } from '@opentelemetry/api' import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks' import { W3CTraceContextPropagator } from '@opentelemetry/core' import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http' import type { SpanProcessor } from '@opentelemetry/sdk-trace-base' import { BatchSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base' import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node' import type { TraceConfig } from '../trace-core/types/config' import { defaultConfig } from '../trace-core/types/config' export class NodeTracer { private static provider: NodeTracerProvider private static defaultTracer: Tracer private static spanProcessor: SpanProcessor static init(config?: TraceConfig, spanProcessor?: SpanProcessor) { if (config) { defaultConfig.serviceName = config.serviceName || defaultConfig.serviceName defaultConfig.endpoint = config.endpoint || defaultConfig.endpoint defaultConfig.headers = config.headers || defaultConfig.headers defaultConfig.defaultTracerName = config.defaultTracerName || defaultConfig.defaultTracerName } this.spanProcessor = spanProcessor || new BatchSpanProcessor(this.getExporter()) this.provider = new NodeTracerProvider({ spanProcessors: [this.spanProcessor] }) this.provider.register({ propagator: new W3CTraceContextPropagator(), contextManager: new AsyncLocalStorageContextManager() }) this.defaultTracer = trace.getTracer(config?.defaultTracerName || 'default') } private static getExporter(config?: TraceConfig) { if (config && config.endpoint) { return new OTLPTraceExporter({ url: `${config.endpoint}/v1/traces`, headers: config.headers || undefined }) } return new ConsoleSpanExporter() } public static getTracer() { return this.defaultTracer } }