Busca en todas las páginas de la documentación
Instrument Node.js 24 services with the OpenTelemetry Node SDK - auto-instrument HTTP and database drivers, export OTLP traces, and add manual spans for business logic.
Quick-reference recipe card - copy-paste ready.
// src/instrumentation.ts
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { Resource } from "@opentelemetry/resources";
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
const sdk = new NodeSDK({
resource: new Resource({ [ATTR_SERVICE_NAME]: "orders-api" }),
traceExporter: new OTLPTraceExporter(),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();// src/main.ts
import "./instrumentation.js";
import { startServer } from "./server.js";
startServer();When to reach for this:
console.time timing in production.// instrumentation.ts
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
// server.ts
import express from "express";
import { trace } from "@opentelemetry/api";
const app = express();
const tracer = trace.getTracer("orders");
app.get("/orders/:id",
What this demonstrates:
sdk.shutdown() on SIGTERM flushes pending spans.@opentelemetry/api.http, https, fetch, pg, ioredis, etc. at require time.traceparent header propagates context to downstream HTTP calls.| Variable | Purpose |
|---|---|
OTEL_SERVICE_NAME | service.name resource attribute |
OTEL_EXPORTER_OTLP_ENDPOINT | Base OTLP URL |
OTEL_TRACES_SAMPLER | parentbased_traceidratio etc. |
OTEL_NODE_RESOURCE_DETECTORS | cloud, container, host |
// CORRECT
import "./instrumentation";
import express from "express";
// WRONG - missed HTTP spans
import express from "express";
import "./instrumentation";import "./instrumentation" first line in main.ts.node --import ./src/instrumentation.ts src/main.ts.OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1userId on every span explodes cost. Fix: low-cardinality attrs only.readFile spans. Fix: disable @opentelemetry/instrumentation-fs.sdk.shutdown() in termination handler.OTEL_TRACES_EXPORTER=none locally or run Jaeger docker.| Alternative | Use When | Don't Use When |
|---|---|---|
| OTel Node SDK | Vendor-neutral, multi-signal | Zero config single-vendor agent suffices |
| Datadog dd-trace | All-in on Datadog APM | Want OTLP portability |
| New Relic agent | NR-only stack | Multi-backend OTLP |
| Manual logs only | Tiny internal tool | Production SLA APIs |
@opentelemetry/sdk-node, @opentelemetry/auto-instrumentations-node, OTLP exporters, @opentelemetry/api for manual spans.
Yes. HTTP auto-instrumentation covers Fastify's underlying server. Load instrumentation before Fastify import.
OTel logs SDK is evolving. Most teams use Pino stdout + trace_id injection for log-trace correlation.
Community instrumentation or manual spans around queries. Enable @opentelemetry/instrumentation-pg for raw SQL drivers.
Run collector with OTLP receiver on 4318. Point OTEL_EXPORTER_OTLP_ENDPOINT there.
opentelemetry-instrumentation-nestjs-core or manual spans in interceptors. Still load SDK first in main.ts.
Typically low single-digit % with sampling. Profile with and without on staging at peak RPS.
Separate service.name (e.g. orders-worker). Start SDK in worker entry same as HTTP.
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.