What is OpenTelemetry?
OpenTelemetry (OTel) is the industry standard for observability. It provides a single set of APIs, SDKs, and tools to collect traces, metrics, and logs from your applications.
The JavaScript SDK is completely free and open source — and it works with every major observability platform: Jaeger, Grafana, Datadog, New Relic, Honeycomb, and more.
Quick Setup
npm install @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-http
Auto-Instrument Everything
// tracing.js — run BEFORE your app
const { NodeSDK } = require("@opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: "http://localhost:4318/v1/traces",
}),
instrumentations: [getNodeAutoInstrumentations()],
serviceName: "my-api",
});
sdk.start();
Run your app:
node --require ./tracing.js app.js
That's it. OpenTelemetry automatically instruments:
- HTTP requests (incoming & outgoing)
- Express/Fastify routes
- Database queries (PostgreSQL, MySQL, MongoDB, Redis)
- gRPC calls
- File system operations
Custom Spans
const { trace } = require("@opentelemetry/api");
const tracer = trace.getTracer("my-service");
async function processOrder(orderId) {
return tracer.startActiveSpan("process-order", async (span) => {
span.setAttribute("order.id", orderId);
try {
const items = await fetchItems(orderId);
span.setAttribute("order.items_count", items.length);
const total = await calculateTotal(items);
span.setAttribute("order.total", total);
await chargeCustomer(total);
span.setStatus({ code: 1 }); // OK
} catch (error) {
span.setStatus({ code: 2, message: error.message }); // ERROR
span.recordException(error);
throw error;
} finally {
span.end();
}
});
}
Custom Metrics
const { metrics } = require("@opentelemetry/api");
const meter = metrics.getMeter("my-service");
const requestCounter = meter.createCounter("http_requests_total", {
description: "Total HTTP requests",
});
const responseTime = meter.createHistogram("http_response_time_ms", {
description: "HTTP response time in milliseconds",
});
// In your middleware:
app.use((req, res, next) => {
const start = Date.now();
res.on("finish", () => {
requestCounter.add(1, { method: req.method, status: res.statusCode });
responseTime.record(Date.now() - start, { route: req.route?.path });
});
next();
});
Send to Jaeger (Free, Local)
# Run Jaeger locally
docker run -d --name jaeger \
-p 16686:16686 \
-p 4318:4318 \
jaegertracing/jaeger:latest
Open http://localhost:16686 to see your traces — full request waterfall, spans, errors, latency.
Express Integration
const express = require("express");
const { trace, SpanStatusCode } = require("@opentelemetry/api");
const app = express();
const tracer = trace.getTracer("express-app");
app.get("/api/users/:id", async (req, res) => {
const span = trace.getActiveSpan();
span?.setAttribute("user.id", req.params.id);
const user = await db.users.findById(req.params.id);
// The DB query is auto-instrumented!
res.json(user);
});
Why OpenTelemetry?
- Vendor-neutral: Switch from Datadog to Grafana without changing code
- Auto-instrumentation: Works out of the box with 30+ libraries
- Free: No licensing fees, no usage limits
- Standard: CNCF graduated project, backed by every major vendor
Need help setting up observability or building monitoring tools?
📧 spinov001@gmail.com
🔧 My developer tools on Apify Store
What observability stack do you use? Share in the comments!
Top comments (0)