UNPKG

@ogcio/o11y-sdk-node

Version:

Opentelemetry standard instrumentation SDK for NodeJS based project

91 lines (90 loc) 3.54 kB
import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api"; import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node"; import { W3CTraceContextPropagator } from "@opentelemetry/core"; import { NodeSDK } from "@opentelemetry/sdk-node"; import { AlwaysOffSampler, ParentBasedSampler, TraceIdRatioBasedSampler, } from "@opentelemetry/sdk-trace-base"; import { setNodeSdkConfig } from "./config-manager.js"; import buildConsoleExporters from "./exporter/console.js"; import buildGrpcExporters from "./exporter/grpc.js"; import buildHttpExporters from "./exporter/http.js"; import { _shutdownHook } from "./internals/hooks.js"; import { ObservabilityResourceDetector } from "./resource.js"; import { UrlSampler } from "./url-sampler.js"; export default async function buildNodeInstrumentation(config) { if (!config) { console.warn("observability config not set. Skipping NodeJS OpenTelemetry instrumentation."); return; } if (!config.collectorUrl) { console.warn("collectorUrl not set. Skipping NodeJS OpenTelemetry instrumentation."); return; } if (!isUrl(config.collectorUrl)) { console.error("collectorUrl does not use a valid format. Skipping NodeJS OpenTelemetry instrumentation."); return; } if (!config.detection) { config.detection = { email: true, }; } if (config.detection.email === undefined) { config.detection.email = true; } // Init configManager to make it available to all o11y utils. setNodeSdkConfig(config); const urlSampler = new UrlSampler(config.ignoreUrls, new TraceIdRatioBasedSampler(config.traceRatio ?? 1)); const mainSampler = new ParentBasedSampler({ root: urlSampler, remoteParentSampled: urlSampler, remoteParentNotSampled: new AlwaysOffSampler(), localParentSampled: urlSampler, localParentNotSampled: new AlwaysOffSampler(), }); diag.setLogger(new DiagConsoleLogger(), config.diagLogLevel ? DiagLogLevel[config.diagLogLevel] : DiagLogLevel.INFO); try { const nodeSdkInstrumentation = getNodeAutoInstrumentations({ "@opentelemetry/instrumentation-fs": { enabled: config.enableFS ?? false, }, }); let exporter; if (config.protocol === "http") { exporter = buildHttpExporters(config); } else if (config.protocol === "console") { exporter = buildConsoleExporters(config); } else { exporter = await buildGrpcExporters(config); } const sdk = new NodeSDK({ resourceDetectors: [ new ObservabilityResourceDetector(config.resourceAttributes), ], spanProcessors: exporter.spans, serviceName: config.serviceName, metricReader: exporter.metrics, logRecordProcessors: exporter.logs, sampler: mainSampler, textMapPropagator: new W3CTraceContextPropagator(), instrumentations: [nodeSdkInstrumentation], }); sdk.start(); console.log("NodeJS OpenTelemetry instrumentation started successfully."); _shutdownHook(sdk); return sdk; } catch (error) { console.error("Error starting NodeJS OpenTelemetry instrumentation:", error); } } function isUrl(url) { try { new URL(url); return true; } catch (_) { return false; } }