@ogcio/o11y-sdk-node
Version:
Opentelemetry standard instrumentation SDK for NodeJS based project
91 lines (90 loc) • 3.54 kB
JavaScript
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;
}
}