OpenTelemetry
CNCF vendor-neutral standard for generating and exporting telemetry. Instrument once, route anywhere.
Three Signals
- Traces — a request’s path across services as a tree of spans (timing, attributes, status).
- Metrics — counters, gauges, histograms.
- Logs — correlated to traces via trace/span IDs.
Architecture
flowchart LR A[App + OTel SDK] -->|OTLP| C[OTel Collector] C --> J[Tracing backend: Jaeger / X-Ray / Tempo] C --> P[Metrics: Prometheus] C --> L[Logs backend]
- API + SDK — API is stable; SDK does sampling, batching, export.
- Instrumentation — auto (HTTP, DB, frameworks) vs manual (custom spans for business logic).
- Collector — receive → process (batch, filter, enrich) → export. Swap vendors without re-instrumenting.
- OTLP — the wire protocol. Exporters: Jaeger, Prometheus, AWS X-Ray (via ADOT), Datadog, …
- Context propagation — W3C
traceparentheader stitches spans across process boundaries. - Semantic conventions — standard attribute names (
http.request.method,db.system).
Node.js zero-code instrumentation
npm i @opentelemetry/api @opentelemetry/auto-instrumentations-node
# Local check: print spans to stdout
OTEL_SERVICE_NAME=my-svc OTEL_TRACES_EXPORTER=console \
OTEL_METRICS_EXPORTER=none OTEL_LOGS_EXPORTER=none \
node --require @opentelemetry/auto-instrumentations-node/register app.js
# Real backend: OTLP to a collector
OTEL_SERVICE_NAME=my-svc OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
node --require @opentelemetry/auto-instrumentations-node/register app.jsInbound http and outbound fetch/undici calls appear as spans with no code changes. Exporter batches flush on a timer (OTEL_BSP_SCHEDULE_DELAY, default 5000 ms) and on SIGTERM; process.exit() skips the flush.
Pairs with Prometheus for metrics; feeds the four golden signals in the Production Readiness Checklist.