UNPKG

@mwcp/otel

Version:
138 lines (111 loc) 4.25 kB
import type { TextMapPropagator } from '@opentelemetry/api' import { CompositePropagator, W3CTraceContextPropagator } from '@opentelemetry/core' import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc' import { JaegerPropagator } from '@opentelemetry/propagator-jaeger' import { node, resources } from '@opentelemetry/sdk-node' import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions' import { PropagatorList, SpanExporterList } from '##/lib/types.js' import type { InitTraceOptions } from '##/lib/types.js' import { detectorResources } from './resource.detector.js' interface InitTraceReturnType { provider: node.NodeTracerProvider processors: node.SpanProcessor[] } export function initTrace(options: InitTraceOptions): InitTraceReturnType { const { otelConfig } = options const resource = new resources.Resource({ [ATTR_SERVICE_NAME]: otelConfig.serviceName, [ATTR_SERVICE_VERSION]: otelConfig.serviceVersion, }) const resourceDefault = resources.Resource.default() const resourceFull = resourceDefault.merge(resource).merge(detectorResources) const processors: node.SpanProcessor[] = [] otelConfig.exporters.forEach((exporter) => { const processor = genExporterInstrumentation(options, exporter, options.isDevelopmentEnvironment) processors.push(processor) }) const provider = new node.NodeTracerProvider({ resource: resourceFull, spanLimits: { linkCountLimit: 127, }, spanProcessors: processors, }) const propagators = genPropagators(otelConfig.propagators) provider.register({ propagator: new CompositePropagator({ propagators }), }); ['SIGINT', 'SIGTERM'].forEach((signal) => { process.on(signal, () => { provider.shutdown().catch(console.error) }) }) // const globalProvider = trace.getTracerProvider() // console.info({ globalProvider }) // const spanProcessor = provider.activeSpanProcessor // const spanProcessor2 = provider.getActiveSpanProcessor() // void spanProcessor // void spanProcessor2 const ret = { provider, processors } return ret } function genPropagators(list: PropagatorList[]): TextMapPropagator[] { const propagators: TextMapPropagator[] = [] list.forEach((propagator) => { switch (propagator) { /* c8 ignore next 4 */ case PropagatorList.jaeger: { propagators.push(new JaegerPropagator()) break } case PropagatorList.w3cTraceContext: { propagators.push(new W3CTraceContextPropagator()) break } /* c8 ignore next 4 */ default: { // eslint-disable-next-line @typescript-eslint/restrict-template-expressions throw new Error(`Propagator ${propagator} not implemented. Use registerInstrumentations() manually.`) } } }) return propagators } function genExporterInstrumentation( options: InitTraceOptions, exporterName: SpanExporterList, isDevelopmentEnvironment: boolean, ): node.SpanProcessor { switch (exporterName) { /* c8 ignore start :local test */ case SpanExporterList.console: { const exporter: node.SpanExporter = new node.ConsoleSpanExporter() // const processor = isDevelopmentEnvironment // ? new node.SimpleSpanProcessor(exporter) // : new node.BatchSpanProcessor(exporter) const processor = new node.BatchSpanProcessor(exporter) return processor } /* c8 ignore stop */ // case SpanExporterList.jaeger: { // const exporter: SpanExporter = new JaegerExporter(options.jaegerExporterConfig) // const processor = new BatchSpanProcessor(exporter) // provider.addSpanProcessor(processor) // return processor // } case SpanExporterList.otlpGrpc: { const exporter: node.SpanExporter = new OTLPTraceExporter(options.otlpGrpcExporterConfig) const processor = isDevelopmentEnvironment ? new node.SimpleSpanProcessor(exporter) : new node.BatchSpanProcessor(exporter) return processor } /* c8 ignore next 3 */ default: // eslint-disable-next-line @typescript-eslint/restrict-template-expressions throw new TypeError(`Exporter ${exporterName} not implemented`) } }