API Observability: Logs, Traces, Metrics with OpenTelemetry

Observability isn't just about logs anymore.

In 2025, understanding how your API behaves under load, in production, across services is critical.

That’s where OpenTelemetry shines.

  • Unified logs, traces, and metrics

  • Framework-agnostic setup

  • Vendor-neutral exporting (Prometheus, Jaeger, Datadog...)

Why Observability Matters

Your API might return a 200 OK. But is it slow? Is it retrying upstream services? Did something silently fail inside a nested call? Observability helps answer these questions.

Unlike simple logging or error tracking, observability enables a holistic understanding of your system's behavior, across multiple dimensions:

  • Logs: Human-readable event history

  • Traces: Distributed timing across systems

  • Metrics: Numeric signals to track system health

Introducing OpenTelemetry

OpenTelemetry is an open standard for collecting telemetry data (logs, traces, metrics) from your application, and exporting them to any backend (e.g. Jaeger, Prometheus, New Relic, AWS X-Ray).

It’s supported across all major languages, and backed by CNCF.

Core Concepts

  • Tracer: Creates spans (units of work) with timing context

  • Span: A single operation with a start & end time, metadata, and optional parent span

  • Context Propagation: Tracks request across services

  • Exporter: Sends data to backends

Setup OpenTelemetry in Node.js

1. Install Required Packages

npm install @opentelemetry/api \
  @opentelemetry/sdk-node \
  @opentelemetry/instrumentation-http \
  @opentelemetry/instrumentation-express \
  @opentelemetry/exporter-trace-otlp-http

2. Configure SDK

// tracing.js
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'http://localhost:4318/v1/traces',
  }),
  instrumentations: [new HttpInstrumentation(), new ExpressInstrumentation()],
});

sdk.start();

3. Start Tracing Early

// index.js
require('./tracing');

const express = require('express');
const app = express();

app.get('/hello', (req, res) => {
  res.send('Hello, observability!');
});

app.listen(3000);

Visualizing Traces

graph TD
A[Client Request] --> B[Express Route Handler]
B --> C[Middleware Span]
C --> D[External HTTP Request Span]
D --> E[Database Query Span]

Each span can include custom metadata (e.g. user.id, status, retryCount).

Exporting to a Backend

  • Use Jaeger or Tempo for tracing

  • Prometheus + Grafana for metrics

  • Combine logs via OTel Log API or sidecars

You can also stream all to observability platforms like:

  • Grafana Cloud

  • Honeycomb

  • Datadog

  • AWS X-Ray / CloudWatch

Pro Tips

  • Sample aggressively in dev, reduce volume in prod

  • Use semantic conventions (http.route, db.statement, etc.)

  • Avoid sensitive data in span attributes

  • Always isolate observability config (e.g. tracing.js)

  • Propagate context in HTTP headers for distributed systems

Conclusion

OpenTelemetry gives you the power to see into your API's behavior without vendor lock-in. Whether you're debugging latency or investigating failed requests, logs alone aren't enough.

Start with tracing, and evolve into full observability.

1
Subscribe to my newsletter

Read articles from Faiz Ahmed Farooqui directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Faiz Ahmed Farooqui
Faiz Ahmed Farooqui

Principal Technical Consultant at GeekyAnts. Bootstrapping our own Data Centre services. I lead the development and management of innovative software products and frameworks at GeekyAnts, leveraging a wide range of technologies including OpenStack, Postgres, MySQL, GraphQL, Docker, Redis, API Gateway, Dapr, NodeJS, NextJS, and Laravel (PHP). With over 9 years of hands-on experience, I specialize in agile software development, CI/CD implementation, security, scaling, design, architecture, and cloud infrastructure. My expertise extends to Metal as a Service (MaaS), Unattended OS Installation, OpenStack Cloud, Data Centre Automation & Management, and proficiency in utilizing tools like OpenNebula, Firecracker, FirecrackerContainerD, Qemu, and OpenVSwitch. I guide and mentor a team of engineers, ensuring we meet our goals while fostering strong relationships with internal and external stakeholders. I contribute to various open-source projects on GitHub and share industry and technology insights on my blog at blog.faizahmed.in. I hold an Engineer's Degree in Computer Science and Engineering from Raj Kumar Goel Engineering College and have multiple relevant certifications showcased on my LinkedIn skill badges.