OpenTelemetry in Node.js: Traces Without Changing Your Code
OpenTelemetry's auto-instrumentation patches popular libraries (http, Express, pg, Redis, fetch and many more) so you get traces with almost no code changes.
Zero-code setup
npm install @opentelemetry/api @opentelemetry/auto-instrumentations-node
export OTEL_SERVICE_NAME=shop-api
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
node --require @opentelemetry/auto-instrumentations-node/register src/server.js
Every incoming request now creates a trace, with child spans for database queries and outgoing HTTP calls.
Programmatic setup
// instrumentation.js - load before anything else
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
const sdk = new NodeSDK({
serviceName: 'shop-api',
traceExporter: new OTLPTraceExporter(), // uses OTEL_EXPORTER_OTLP_ENDPOINT
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-fs': { enabled: false }, // very noisy
}),
],
});
sdk.start();
process.on('SIGTERM', () => sdk.shutdown()); // flush spans on exit
node --import ./instrumentation.js src/server.js
Custom spans for business logic
import { trace, SpanStatusCode } from '@opentelemetry/api';
const tracer = trace.getTracer('checkout');
export async function placeOrder(cart, user) {
return tracer.startActiveSpan('placeOrder', async (span) => {
span.setAttributes({ 'cart.items': cart.items.length, 'user.plan': user.plan });
try {
const order = await createOrder(cart, user);
span.setAttribute('order.id', order.id);
return order;
} catch (err) {
span.recordException(err);
span.setStatus({ code: SpanStatusCode.ERROR });
throw err;
} finally {
span.end();
}
});
}
See it locally
docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one
# open http://localhost:16686
In production, send OTLP to an OpenTelemetry Collector or straight to your vendor. Don't put personal data like emails or card numbers in span attributes.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.