What's OpenTelemetry
OpenTelemetry is a free, open standard for the traces, logs, and metrics your software produces. Instrument once, send the data to any tool.
OpenTelemetry, or OTel, is built and maintained in the open by a broad group of companies, in order to give telemetry one shared standard that no single vendor owns.
Why it exists
Before OpenTelemetry, every monitoring tool shipped its own agent, its own data format, and its own names for the same things. Sending your data somewhere new, or to two tools at once, meant re-instrumenting your code. Your telemetry was tied to whichever tool you set up first.
OpenTelemetry fixes that with one standard everyone agrees on:
- Instrument once. Add it to your code a single time, then point the data at any tool that supports it.
- No lock-in. Move between tools, or run several at once, without touching your instrumentation.
- Everything lines up. Because the format and the names are shared, your traces, logs, and metrics connect to each other on their own.
The three kinds of signal
OpenTelemetry describes three kinds of signal.
Traces are the story of one request as it moves through your system. A trace is a tree of spans, and each span is a single step: a name, when it started, how long it took, whether it succeeded, and some attributes. Each span points at its parent, and that link travels from one service to the next (in an HTTP header, say), so the steps join into a single trace.
GET /checkout 142ms (root span: the whole trace)
├─ authorize 12ms
├─ SELECT cart_items 38ms
└─ POST /payments 86ms (another service; the trace continues here)
└─ charge card 71msEach row is a span, carrying its name, duration, status, and attributes such as http.response.status_code.
Logs are timestamped notes your code writes: a time, a severity, a message, and attributes. When a log happens inside a request it carries that request's trace_id and span_id, which is what ties a log line to the exact step that produced it.
log severity=ERROR body="payment declined"
trace_id=a1b2… span_id=9f… attributes: { user.id: u_42 }Metrics are numbers measured over time, like how many requests came in or how long they took. Attributes split one metric into separate series (per route, per method). The common shapes are counts that only go up, values sampled right now, and distributions for things like latency.
metric name=http.server.request.duration histogram unit=s
record(0.142) attributes: { http.request.method: GET, http.route: /checkout }Why the names matter
The signals only line up across tools because everyone agrees on the attribute names. service.name, http.response.status_code, and db.system mean the same thing whatever emitted them, so a query written for one service works for the next. These agreed names are called semantic conventions.
service.name http.request.method db.system
service.version http.response.status_code db.query.textGetting it out of your code
OTLP is the shared format the standard uses to send traces, logs, and metrics over the network. The Collector is a small middleman that receives that data and forwards it on, so you can change where telemetry goes, or add another destination, in one place instead of editing every service.
Learn more
The full standard, SDKs, and language guides live at opentelemetry.io.