Span & Signal

Chapter 2 · OpenTelemetry

Instrument once. Send it anywhere.

OpenTelemetry is the CNCF's open standard for generating and moving telemetry. It is not a backend — it is the plumbing that gets traces, metrics and logs out of your code in one consistent shape, so the place you store them becomes a choice rather than a lock-in.

Apps + SDKs

  • checkout · Node.js
  • payments · Go
  • search · Python
  • legacy · Java agent

OpenTelemetry Collector

1. receivers

otlp · prometheus · filelog

2. processors

memory_limiter · batch · tail_sampling

3. exporters

otlp · otlphttp · debug

Backends

  • Traces store
  • Metrics store
  • Logs store
Data flows over OTLP. Swap a backend by changing an exporter — not your application code.

01The moving parts

01 · what you code against

API

Stable, vendor-neutral interfaces for creating spans, recording metrics and emitting logs. Libraries depend only on the API, so instrumentation does nothing until an application installs an SDK.

02 · what makes it real

SDK

The implementation behind the API: sampling, batching, resource detection and exporters. Configured once at startup, usually through OTEL_* environment variables.

03 · what saves you time

Instrumentation

Ready-made instrumentation for HTTP servers, database drivers, queues and frameworks. Zero-code agents for Java, Python, .NET, Node.js and others attach it without touching source.

04 · how data travels

OTLP

The OpenTelemetry Protocol — a single wire format for every signal over gRPC (port 4317) or HTTP (port 4318). Most backends now accept it directly.

05 · where data gets shaped

Collector

A standalone service that receives, processes and exports telemetry. It batches, filters, redacts, samples and fans data out to one or many backends — decoupling your code from your vendor.

06 · why it all lines up

Semantic conventions

Agreed names for common attributes — http.request.method, db.system.name, service.name. Consistent names are what let any backend build useful views without custom mapping.

02In practice

A few lines to your first trace.

Start with auto-instrumentation to get HTTP and database spans for free, then add manual spans around the business logic that matters. Point the exporter at a Collector and let it decide where data goes.

Most settings can be driven by environment variables such as OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_SERVICE_NAME, so the same build runs anywhere.

// instrumentation.mjs — load with: node --import ./instrumentation.mjs app.mjs
import { NodeSDK } from '@opentelemetry/sdk-node'
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'

const sdk = new NodeSDK({
  serviceName: 'checkout',
  traceExporter: new OTLPTraceExporter(), // defaults to http://localhost:4318
  instrumentations: [getNodeAutoInstrumentations()],
})

sdk.start()

03Glossary

Resource
Attributes describing the thing producing telemetry — service.name, host, cloud region, k8s pod.
Context propagation
Passing trace context between services, usually in the W3C traceparent HTTP header.
Head sampling
Deciding at the start of a trace whether to keep it. Cheap, but blind to what happens later.
Tail sampling
Deciding after a trace completes, so you can keep every error and slow request. Runs in the Collector.
Exemplar
A sample trace ID attached to a metric data point, linking a latency spike to a real request.
Baggage
Key-value pairs propagated alongside trace context, readable by every downstream service.
Next: choosing where your data lives →