Node.js
This guide covers adding OpenTelemetry instrumentation to Node.js applications. The Node.js OTel SDK supports auto-instrumentation for Express, Fastify, HTTP, gRPC, database clients, and many other libraries.
Prerequisites
Section titled “Prerequisites”- Node.js 16+
- OTel Collector running at
localhost:4317(gRPC) orlocalhost:4318(HTTP) - npm, yarn, or pnpm for package management
Install dependencies
Section titled “Install dependencies”Install the core SDK and OTLP exporter:
npm install @opentelemetry/sdk-node \ @opentelemetry/api \ @opentelemetry/exporter-trace-otlp-grpc \ @opentelemetry/exporter-metrics-otlp-grpc \ @opentelemetry/exporter-logs-otlp-grpc \ @opentelemetry/resources \ @opentelemetry/semantic-conventionsFor auto-instrumentation of common libraries:
npm install @opentelemetry/auto-instrumentations-nodeSDK setup
Section titled “SDK setup”Create a tracing.js (or tracing.ts) file that initializes the SDK:
const { NodeSDK } = require("@opentelemetry/sdk-node");const { OTLPTraceExporter,} = require("@opentelemetry/exporter-trace-otlp-grpc");const { OTLPMetricExporter,} = require("@opentelemetry/exporter-metrics-otlp-grpc");const { OTLPLogExporter,} = require("@opentelemetry/exporter-logs-otlp-grpc");const { PeriodicExportingMetricReader,} = require("@opentelemetry/sdk-metrics");const { Resource } = require("@opentelemetry/resources");const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION,} = require("@opentelemetry/semantic-conventions");const { getNodeAutoInstrumentations,} = require("@opentelemetry/auto-instrumentations-node");
const resource = new Resource({ [ATTR_SERVICE_NAME]: "my-node-service", [ATTR_SERVICE_VERSION]: "1.0.0", "deployment.environment": "development",});
const sdk = new NodeSDK({ resource, traceExporter: new OTLPTraceExporter({ url: "grpc://localhost:4317", }), metricReader: new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter({ url: "grpc://localhost:4317", }), exportIntervalMillis: 2000, }), logRecordExporter: new OTLPLogExporter({ url: "grpc://localhost:4317", }), instrumentations: [getNodeAutoInstrumentations()],});
sdk.start();
process.on("SIGTERM", () => { sdk.shutdown().then(() => process.exit(0));});Auto-instrumentation
Section titled “Auto-instrumentation”The simplest approach uses --require to load the tracing setup before your application:
node --require ./tracing.js app.jsThe @opentelemetry/auto-instrumentations-node package automatically instruments:
- HTTP/HTTPS clients and servers
- Express, Fastify, Koa, Hapi
- gRPC clients and servers
- MySQL, PostgreSQL, MongoDB, Redis
- AWS SDK, GraphQL, and more
To disable specific instrumentations:
const { getNodeAutoInstrumentations } = require( "@opentelemetry/auto-instrumentations-node");
const instrumentations = getNodeAutoInstrumentations({ "@opentelemetry/instrumentation-fs": { enabled: false }, "@opentelemetry/instrumentation-dns": { enabled: false },});Manual instrumentation
Section titled “Manual instrumentation”Creating spans
Section titled “Creating spans”const { trace } = require("@opentelemetry/api");
const tracer = trace.getTracer("my-module");
async function processOrder(orderId) { return tracer.startActiveSpan("process_order", async (span) => { try { span.setAttribute("order.id", orderId);
// Child span await tracer.startActiveSpan("validate_payment", async (child) => { await validatePayment(orderId); child.end(); });
span.addEvent("order_processed", { "order.id": orderId }); } catch (err) { span.recordException(err); span.setStatus({ code: 2, message: err.message }); // ERROR throw err; } finally { span.end(); } });}Recording metrics
Section titled “Recording metrics”const { metrics } = require("@opentelemetry/api");
const meter = metrics.getMeter("my-module");
const requestCounter = meter.createCounter("http.server.request_count", { description: "Number of HTTP requests", unit: "1",});
const requestDuration = meter.createHistogram("http.server.duration", { description: "HTTP request duration", unit: "ms",});
function handleRequest(req, res) { requestCounter.add(1, { "http.method": req.method, "http.route": req.path }); const start = Date.now(); // ... handle request requestDuration.record(Date.now() - start, { "http.method": req.method, "http.route": req.path, });}Framework integration
Section titled “Framework integration”Express
Section titled “Express”const express = require("express");const { ExpressInstrumentation,} = require("@opentelemetry/instrumentation-express");const { HttpInstrumentation,} = require("@opentelemetry/instrumentation-http");
// If using NodeSDK, add these to the instrumentations array:const sdk = new NodeSDK({ instrumentations: [new HttpInstrumentation(), new ExpressInstrumentation()], // ... other config});
const app = express();
app.get("/orders/:id", (req, res) => { res.json({ orderId: req.params.id });});
app.listen(3000);Fastify
Section titled “Fastify”const { FastifyInstrumentation,} = require("@opentelemetry/instrumentation-fastify");
const sdk = new NodeSDK({ instrumentations: [new FastifyInstrumentation()], // ... other config});Next.js
Section titled “Next.js”For Next.js applications, initialize the SDK in an instrumentation.ts file:
export async function register() { if (process.env.NEXT_RUNTIME === "nodejs") { await import("./tracing"); }}Environment variables
Section titled “Environment variables”| Variable | Description | Example |
|---|---|---|
OTEL_SERVICE_NAME | Service name | my-node-service |
OTEL_EXPORTER_OTLP_ENDPOINT | Collector endpoint | http://localhost:4317 |
OTEL_EXPORTER_OTLP_PROTOCOL | Export protocol | grpc |
OTEL_TRACES_SAMPLER | Sampler type | parentbased_traceidratio |
OTEL_TRACES_SAMPLER_ARG | Sampler argument | 0.1 |
OTEL_NODE_ENABLED_INSTRUMENTATIONS | Comma-separated list of instrumentations to enable | http,express |
OTEL_NODE_DISABLED_INSTRUMENTATIONS | Comma-separated list of instrumentations to disable | fs,dns |
NODE_OPTIONS | Load tracing at startup | --require ./tracing.js |
Related links
Section titled “Related links”- Applications overview
- Auto-instrumentation
- Manual instrumentation
- OpenTelemetry JavaScript documentation — Official OTel JS/Node.js SDK reference
- Node.js instrumentation libraries — Available auto-instrumentation packages