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
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.