UNPKG

@ogcio/o11y-sdk-node

Version:

Opentelemetry standard instrumentation SDK for NodeJS based project

126 lines (109 loc) 3.53 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 type { Exporters } from "./exporter/index.js"; import type { NodeSDKConfig } from "./index.js"; import { _shutdownHook } from "./internals/hooks.js"; import { ObservabilityResourceDetector } from "./resource.js"; import { UrlSampler } from "./url-sampler.js"; export default async function buildNodeInstrumentation( config?: NodeSDKConfig, ): Promise<NodeSDK | undefined> { 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: Exporters; 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: string): boolean { try { new URL(url); return true; } catch (_) { return false; } }