DEV Community

Alex Spinov
Alex Spinov

Posted on

OpenTelemetry JS Has a Free API: Here's How to Instrument Your Node.js Apps

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
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

Run your app:

node --require ./tracing.js app.js
Enter fullscreen mode Exit fullscreen mode

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();
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

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();
});
Enter fullscreen mode Exit fullscreen mode

Send to Jaeger (Free, Local)

# Run Jaeger locally
docker run -d --name jaeger \
  -p 16686:16686 \
  -p 4318:4318 \
  jaegertracing/jaeger:latest
Enter fullscreen mode Exit fullscreen mode

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);
});
Enter fullscreen mode Exit fullscreen mode

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)