Observability with OpenTelemetry›Modules · Cheat sheet & self-check
Learning Hub / Observability & Reliability / Observability with OpenTelemetry

Modules · wrap-up

Cheat sheet & self-check

Every command from this section on one page.

01 · Observability fundamentals

Signals

MetricsCheap numbers over time: rates, errors, latency percentiles, saturation
LogsDetailed events: what exactly happened, with context
TracesOne request's path across services, with timing per step (spans)

Methods & standards

RED: Rate, Errors, DurationFor request-driven services
USE: Utilization, Saturation, ErrorsFor resources (CPU, disk, queues)
OTLP: gRPC :4317, HTTP :4318OpenTelemetry's wire protocol
service.name, k8s.namespace.name, k8s.pod.nameResource attributes that tie signals together

02 · OpenTelemetry Collector deep dive

Config building blocks

receivers: otlp, prometheus, filelog, hostmetrics, kubeletstatsHow data gets in
processors: memory_limiter → k8sattributes → … → batchWhat happens to it (order matters)
exporters: otlp, otlphttp, prometheusremotewrite, debugWhere it goes
connectors: spanmetrics, countTurn one pipeline's output into another's input
service.pipelines.{traces,metrics,logs}Wire it together per signal

Operate

otelcol-contrib validate --config config.yamlCheck a config before deploying
exporters: debug: { verbosity: detailed }Print what flows through (temporarily)
:8888/metrics (service.telemetry)The Collector's own metrics
kubectl get opentelemetrycollectors,instrumentations -AOperator-managed resources

03 · Distributed tracing

Instrumentation

OTEL_SERVICE_NAME=cartName the service (the most important attribute)
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-agent:4318Where to send telemetry
OTEL_TRACES_SAMPLER=parentbased_traceidratio OTEL_TRACES_SAMPLER_ARG=0.1Head sampling at 10%, respecting the parent's decision
opentelemetry-instrument python app.pyPython auto-instrumentation (opentelemetry-distro)
java -javaagent:opentelemetry-javaagent.jar -jar app.jarJava auto-instrumentation

Querying

traceparent: 00-<trace-id 32 hex>-<span-id 16 hex>-01W3C propagation header
{ resource.service.name = "cart" && status = error }TraceQL: failed spans in cart
{ span.http.route = "/checkout" && duration > 2s }TraceQL: slow checkout spans

04 · Structured logging & Loki

LogQL

{namespace="shop", app="cart"}Stream selector (labels only)
{namespace="shop"} |= "timeout" != "healthz"Line filters (contains / not contains)
{app="cart"} | json | status >= 500Parse JSON, filter on a field
{app="cart"} | logfmt | line_format "{{.level}} {{.msg}}"Parse logfmt, reformat
sum by (app) (rate({namespace="shop"} |= "error" [5m]))Error lines per second, per app

Label rules

Good labels: cluster, namespace, app, container, levelFew values, used to select streams
Bad labels: user_id, trace_id, request_id, pod IPUnbounded → too many streams
Structured metadata (Loki 3)High-cardinality fields attached without being labels

05 · Signal correlation

Links to set up

Exemplars on histograms (Prometheus: --enable-feature=exemplar-storage)Metric spike → example trace
Tempo data source: trace to logs (Loki)Span → that pod's logs around that time
Tempo data source: trace to metricsSpan → the service's RED metrics
Loki data source: derived field on trace_idLog line → trace

Prerequisites

Same service.name / namespace / pod names across signalsThe join keys
trace_id + span_id in every log lineVia OTel log bridges or logging instrumentation
Synchronized clocks (NTP/chrony)Time-window jumps line up

06 · SLOs, SLIs & burn-rate alerting

Definitions

SLI = good events / valid eventse.g. requests < 300 ms and not 5xx, divided by all requests
SLO = target for an SLI over a windowe.g. 99.9% over 30 days
Error budget = 1 − SLO0.1% → 43.2 minutes of total outage per 30 days
Burn rate = error ratio / (1 − SLO)1 = using the budget exactly over the window

Standard alert pairs (30-day SLO)

14.4× over 1h AND 5m → page2% of budget in 1 hour
6× over 6h AND 30m → page5% of budget in 6 hours
1× over 3d AND 6h → ticket10% of budget in 3 days

07 · Production observability patterns

Cost levers

Traces: tail sampling (errors + slow + small %)Keep what matters
Metrics: drop unused series/labels (relabeling, filter processor)Cardinality is cost
Logs: drop noise at the source; shorter retention for debug dataLargest volume
Retention tiers per signal and tenantPay for history only where it's used

Platform

X-Scope-OrgID: <tenant>Tenant header for Loki, Tempo and Mimir
transform / attributes / redaction processorsRemove PII and secrets before storage
otelcol_exporter_send_failed_*, otelcol_processor_refused_* (names vary by version)Collector health signals