How to Instrument an Application with OpenTelemetry

OpenTelemetry is the current industry-standard framework for generating metrics, logs, and traces from your application code — vendor-neutral, meaning the same instrumentation works with many different backend observability tools.

Why OpenTelemetry Specifically

Before OpenTelemetry, instrumenting applications for observability often meant vendor-specific SDKs, locking you into a particular tool. OpenTelemetry provides one standard instrumentation approach that can export to Jaeger, Prometheus, or many other compatible backends.

Prerequisites

  • A running application in your language of choice (examples below use Node.js)

Step 1 — Install OpenTelemetry Packages

npm install @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http

Step 2 — Create an Instrumentation Setup File

nano tracing.js
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://YOUR_JAEGER_SERVER_IP:4318/v1/traces',
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start();

Step 3 — Load Instrumentation Before Your Application Code

node -r ./tracing.js app.js

The tracing setup must load before your application's own modules to correctly auto-instrument common libraries (HTTP, database clients, and more).

Step 4 — Verify Traces Are Being Sent

Make a few requests to your application, then check your Jaeger UI (see How to Implement Distributed Tracing with Jaeger) to confirm traces are appearing for your service.

Adding Custom Spans for Specific Business Logic

const { trace } = require('@opentelemetry/api');
const tracer = trace.getTracer('my-app');

async function processOrder(orderId) {
  return tracer.startActiveSpan('process-order', async (span) => {
    span.setAttribute('order.id', orderId);
    try {
      // ... business logic ...
    } finally {
      span.end();
    }
  });
}

Auto-instrumentation covers common libraries automatically; custom spans let you add visibility into your own application-specific logic.

Adding Metrics Instrumentation

const { metrics } = require('@opentelemetry/api');
const meter = metrics.getMeter('my-app');
const requestCounter = meter.createCounter('requests_total');

requestCounter.add(1, { route: '/api/orders' });

Instrumenting Other Languages

OpenTelemetry provides SDKs for most major languages (Python, Java, Go, .NET, and others) following the same general pattern — consult the official OpenTelemetry documentation for language-specific setup, since exact API syntax differs.

Exporting to Multiple Backends Simultaneously

OpenTelemetry supports exporting the same instrumentation data to multiple destinations at once (e.g. traces to Jaeger, metrics to Prometheus) — useful if you're using specialized tools for different observability pillars rather than one unified platform.

Common Errors

Auto-instrumentation doesn't capture expected spans — verify the tracing setup file is loaded before your application code (via -r flag or equivalent), not imported after other modules are already loaded.

High overhead from tracing — consider sampling (tracing only a percentage of requests) for high-traffic production services rather than tracing every single request.

Continue Reading

Browse more articles in Advanced Observability & Incident Management.

  • opentelemetry, application instrumentation, opentelemetry nodejs, otel tracing
  • 0 Users Found This Useful
Was this answer helpful?

Related Articles

What Is Observability? Metrics, Logs, and Traces Explained

Observability goes beyond basic monitoring — it's the ability to understand what's...

How to Set Up Centralized Logging with the ELK Stack (Elasticsearch, Logstash, Kibana)

The ELK Stack (Elasticsearch, Logstash, Kibana) is a mature, powerful centralized logging...

How to Set Up Centralized Logging with Grafana Loki (Lightweight Alternative)

Grafana Loki is a lighter-weight alternative to the ELK Stack, designed to index only log...

How to Implement Distributed Tracing with Jaeger

Distributed tracing tracks a single request as it flows through multiple services —...

How to Define and Track SLOs and Error Budgets

Service Level Objectives (SLOs) and error budgets bring a structured, quantitative approach to...