Frontend Labs
⋯

Part IV — Observability

28. Observability strategy

28.1 Signals and what each one answers

Signal Answers Strength Cost driver
Metrics "Is something wrong? How much? Since when?" cheap aggregates, alerting, trends cardinality (unique label combinations)
Logs "What exactly happened in this event?" detail, context, audit volume (bytes ingested)
Traces "Where did the time go across services for this request?" causality across hops volume (sample!)
Profiles "Which line of code burns CPU/allocates memory?" continuous pprof (Pyroscope, Parca) low
K8s events "What did the platform do?" (OOMKill, eviction, scaling) explains restarts low, but they expire after 1 h

The workflow they enable: an alert fires on a metric → a dashboard narrows it to a service and time → an exemplar or trace shows the slow hop → that span's logs (same trace_id) show the error. Correlation by shared resource attributes (service.name, k8s.pod.name) and trace_id is what turns three data stores into one investigation.

28.2 What to measure: Golden Signals, RED, USE

  • RED (for every service): Rate, Errors, Duration.
  • USE (for every resource: CPU, memory, disk, connection pools, queues): Utilization, Saturation, Errors.
  • Four Golden Signals (Google SRE book): latency, traffic, errors, saturation, which is RED + saturation.

For Orbit:

Component Signals
catalog, orders RED per route; DB pool in-use/wait; cache hit ratio
worker messages processed/s, processing duration, failures, stream lag (saturation)
Postgres connections vs max, replication lag, TPS, slow queries, disk
Redis memory vs maxmemory, ops/s, stream length
Kubernetes restarts, OOMKills, not-ready pods, HPA at max, pending pods, node pressure, PVC usage

28.3 Why OpenTelemetry

OpenTelemetry (OTel) is the CNCF standard for generating and shipping telemetry: one SDK per language, one wire protocol (OTLP), one Collector. The backend becomes a swappable detail: Prometheus/Loki/Tempo today, Datadog/Honeycomb/New Relic/Grafana Cloud tomorrow, by changing Collector config, not application code.

 app (OTel SDK) ──OTLP──► Collector AGENT (DaemonSet, per node) ──OTLP──► Collector GATEWAY (Deployment)
 app stdout logs ──files──►   │  + k8s metadata, batching                  │ tail sampling, routing, redaction
                              │                                            ├──► Prometheus (metrics, OTLP receiver)
                              │                                            ├──► Loki       (logs, OTLP)
                              │                                            └──► Tempo      (traces, OTLP)
 kube-state-metrics, node-exporter, kubelet/cAdvisor ◄──scrape── Prometheus

Best practice: apps send to a local agent, never directly to a SaaS endpoint. The agent buffers through backend outages, adds K8s metadata, and lets you change backends, sampling and redaction without redeploying 200 services.


Generated from real-life-k8s-guide.md · 8 Oct 2026 16:36