Observability: os 3 pilares (logs, métricas, traces) e por que não basta
Toda empresa acha que tem "monitoring". Poucas têm observability. A diferença aparece no pior momento: 3 da manhã, alerta disparado, dashboard verde, mas os usuários falam que algo está quebrado. Monitoring te diz "o que foi quebrou?" somente se você pensou antes em medir essa coisa. Observability te deixa fazer perguntas novas sobre o sistema em tempo real.
Este módulo abre a trilha de observabilidade com os conceitos-chave: os 3 pilaresclássicos (logs, métricas, traces), por que essa separação está mudando, o conceito de cardinalidade (e por que ela é cara), events como 4º pilar, e continuous profiling como 5º. Sem hype — o que efetivamente você deve ter no seu stack em 2026.
Monitoring vs Observability: a mudança conceitual
Monitoring é velho — vem dos anos 90, de sistemas monolíticos onde o operador sabia exatamente o que podia dar errado (disk cheio, CPU em 100%, serviço caiu). Você configurava alertas pra esses N cenários e pronto.
Observability (conceito da teoria de controle, Kalman 1960) começou a ser importada pra software em ~2017 (Honeycomb, Charity Majors). A tese: sistemas distribuídos modernos têm muito mais estados possíveis do que qualquer engenheiro consegue antecipar. Em vez de alertar sobre N coisas conhecidas, você instrumenta tudo o suficiente pra descobrir o que deu errado.
| Dimensão | Monitoring | Observability |
|---|---|---|
| Perguntas | As que você previu | Qualquer pergunta ad-hoc |
| Dashboards | Fixos, por dashboard | Exploratórios, drill-down livre |
| Cardinalidade | Baixa (agregada) | Alta (contexto preservado) |
| Alertas | Baseados em thresholds absolutos | Baseados em SLO burn rates |
| Debugging | Grep em logs | Decompor evento por dimensão |
| Ferramentas típicas | Nagios, Zabbix, Prom | Honeycomb, Datadog, Tempo |
Os 3 pilares clássicos
OBSERVABILITY ├─ LOGS ──── "o que aconteceu" (evento textual/JSON por linha) ├─ METRICS ──── "quanto" (números agregados no tempo: rate, latência, count) └─ TRACES ──── "como" (path de uma request atravessando N serviços)
| Pilar | Granularidade | Uso típico | Custo |
|---|---|---|---|
| Metrics | Agregado (contadores, histogramas) | Dashboards, alertas, SLOs | Barato — timeseries compactas |
| Logs | Por evento (texto/JSON) | Debugging detalhado, audit, forensics | Alto — volume cresce com tráfego |
| Traces | Por request (span tree) | Entender latência distribuída, root cause em microserviços | Médio — com sampling |
Exemplo: mesmo incidente visto pelos 3 pilares.
Problema: usuário reporta que checkout tá lento
MÉTRICAS (Prometheus):
http_request_duration_seconds{path="/checkout"} p99 = 4.2s
(era 200ms ontem — anomalia clara)
→ mas por quê? métricas não sabem.
LOGS (JSON):
{"level":"warn","msg":"slow query","query":"SELECT * FROM carts...","dur_ms":3800}
{"level":"info","msg":"checkout completed","user":"u42","dur_ms":4100}
→ hipótese: query lenta. Mas qual cart? Quantos usuários afetados?
TRACES (Jaeger):
span: POST /checkout (4.1s)
├─ span: CartService.getCart (3.8s) ← gargalo!
│ └─ span: db.query (3.7s, query_type="cart_items_join")
├─ span: PaymentService.charge (150ms)
└─ span: ShippingService.schedule (40ms)
→ conclusão: join no cart_items explodiu. Correlacionar com deploy de hoje.Os 3 pilares são complementares. Sozinhos, cada um é limitado. Juntos, permitem ir do "algo está lento" pro "essa query específica, nesse código, nesse deploy" em minutos.
Cardinalidade: o imposto oculto
Cardinalidade de uma métrica = número de combinações únicas de labels. Em Prometheus e similares, cada combinação é uma série temporal separada — com seu próprio buffer, índice e retenção.
# baixa cardinalidade — ok
http_requests_total{method="GET", status="200"} 12345
http_requests_total{method="POST", status="500"} 42
# ~ 6 métodos × 10 status = 60 séries, ok
# alta cardinalidade — PERIGO
http_requests_total{method, status, path, user_id} 1
# 5 métodos × 10 status × 500 paths × 1_000_000 user_ids = 25 bilhões de séries
# Prometheus capota. Latência de query em minutos.Regras práticas pra labels de métricas:
- Nunca use: user_id, email, session_id, trace_id, uuid, timestamp, URL completa com query params
- OK: enum-like (method, status, region), low-cardinality features (tier: free/pro/ent, os: ios/android)
- Máximo: 10-50k séries únicas por métrica em Prometheus
- Se precisa alta cardinalidade: use events/traces (não métricas) ou TSDB moderno (VictoriaMetrics, Mimir, Cortex)
request_id numa métrica ("seria legal ver por request"), deploy vai, 3h depois Prometheus OOMs. Investigue queries pesadas comtopk(10, count by (__name__) ({__name__=~".+"})).Events: o 4º pilar (wide events, high cardinality)
Metrics são lossy (agregadas). Logs são textuais (difíceis de consultar estruturado). Traces são hierárquicos (bom pra latência). Wide events ficam no meio: cada request gera um evento JSON com 30-100 fields — user, tenant, version, region, cache hit, status, latency, feature flags, db stats, etc.
// um wide event por request (exemplo Honeycomb-style)
{
"timestamp": "2026-04-16T14:23:45.123Z",
"service": "checkout-api",
"version": "v2.3.1-a4f8",
"env": "production",
"region": "us-east-1",
"endpoint": "POST /checkout",
"status": 200,
"duration_ms": 423,
"user_id": "u_42",
"user_tier": "pro",
"tenant_id": "acme-corp",
"feature_flag.new_payment_flow": true,
"feature_flag.cdn_enabled": false,
"cart_items_count": 12,
"cart_total_cents": 15000,
"db.query_count": 5,
"db.cache_hit_ratio": 0.8,
"trace_id": "abc123...",
"request_id": "req_xyz"
}Com wide events, em 1 minuto no dashboard você pode: "mostre latência p99 por region E feature_flag.new_payment_flow E user_tier". Sem pré-agregação, sem dashboards pré-configurados. Honeycomb e Datadog (Continuous Profiler + RUM) são lideres; ferramentas open-source crescendo (Grafana Tempo aceita span events, ClickHouse + Vector é stack DIY popular).
Continuous profiling: o 5º pilar
Profiling tradicional: você liga em ambiente de staging, roda carga, analisa offline. Problema: bugs de performance em produção raramente reproduzem fora dela. Continuous profiling roda em produçãocom overhead <3% (via eBPF, instrumentação em runtime), gerando flamegraphs sempre disponíveis.
CPU flamegraph do momento do incidente: |████████████████████████████████| 100% CPU (root) |████████████████████████| 65% checkout_handler |████████████| 42% getCartItems |█████| 28% db.query (N+1 detectado!) |██| 8% json.serialize |███| 13% paymentClient.charge |██████| 25% rateLimiter.check
| Ferramenta | Tech | Uso |
|---|---|---|
| Pyroscope (Grafana) | eBPF + agents | Open-source, multi-lang, integrado com Grafana |
| Parca | eBPF puro | Open-source, foco em infra estilo K8s |
| Datadog Continuous Profiler | Agent proprietário | Enterprise, deep integration com APM |
| Google Cloud Profiler | SDK por language | Low-overhead, GCP native |
| Polar Signals | Parca commercial | Empresa por trás do Parca |
O que montar em 2026: stack mínimo
| Pilar | Open-source | Managed |
|---|---|---|
| Metrics | Prometheus + Grafana | Datadog, New Relic, Honeycomb, Chronosphere, Grafana Cloud |
| Logs | Loki, ELK stack, Vector + ClickHouse | Datadog Logs, Elastic Cloud, Grafana Cloud Logs |
| Traces | Tempo, Jaeger, Zipkin (legacy) | Honeycomb, Datadog APM, Lightstep |
| Events | ClickHouse + Vector + Grafana | Honeycomb (pioneer), Datadog CI, Axiom |
| Profiling | Pyroscope, Parca | Datadog, Polar Signals, GCP |
| Instrumentação | OpenTelemetry SDK + Collector | (mesma, padrão do mercado) |
- Grafana LGTM stack (Loki + Grafana + Tempo + Mimir) — open-source, self-host ou Grafana Cloud
- Datadog — plug-and-play, caro mas completo
- Honeycomb — aposta forte em events/cardinalidade, menos dashboards tradicionais
Custo: observability é cara (atente-se)
O maior trauma operacional pós-K8s é a fatura do Datadog. Alguns padrões pra não quebrar:
- Sampling em traces: 1-10% em produção, 100% em staging. Rejeite spans de health checks.
- Log levels apropriados: DEBUG nunca em prod. INFO moderado. Truncar fields gigantes.
- Retention tiered: hot 7d, warm 30d, cold S3 90d+. Datadog permite; self-host precisa configurar.
- Cardinalidade cap: Prometheus
label_limit, Grafana Mimir limits per tenant. - Drop filtering: OTel Collector processor pra dropar spans/logs irrelevantes antes do backend.
- Derived metrics: extrair métricas de logs (se é a mesma info, não duplique).
Decisões reais
📋 Empresa small/mid começando do zero, equipe de 5-20 devs
OTel te dá portabilidade — pode trocar backend sem recódigo. Grafana Cloud free tier é generoso (10k active series, 50GB logs/mês) pra começar. Quando escalar, upgrade ou self-host LGTM.
Alt: Datadog — Menor curva mas cara fácil: 5k/mês sobe rápido.
Alt: Honeycomb — Ótima se foco em events/debugging distribuído.
📋 Enterprise com compliance pesado, workloads sensíveis
Data sensível não sai da nuvem. LGTM (ou ELK legacy) dá controle total. Custo operacional é alto — precisa de time dedicado. Mas é o único caminho pra workloads regulados (banking, health, defesa).
Alt: Datadog com private cloud — Existe mas caro e ainda compartilhado.
📋 App tem bottlenecks que só aparecem em produção com carga real
Traces mostram 'db.query took 3s' mas não qual função chamou. Profiler mostra o stack completo com flamegraph. <3% overhead é negligível comparado ao tempo de debug economizado.
Alt: pprof manual — Funciona mas é evento pontual, não contínuo.
Perguntas típicas (Q&A)
Preciso dos 3 pilares desde o dia 1?
Sim, mas na ordem: métricas pra SLOs e alertas (sem isso não sabe se app tá viva), logs estruturados desde sempre (JSON com correlation id), traces quando tiver mais de 2 serviços. Profiling quando problemas ficam sutis.
OpenTelemetry é mandatório?
Se começa novo em 2026: sim, é o padrão da CNCF. Auto-instrumentação pra maioria das libs existe. Permite trocar backend sem tocar código. Legado: considere migração gradual via OTel Collector que aceita formatos antigos.
High cardinality sempre é problema?
Em métricas tradicionais (Prometheus), sim. Em eventos/traces, é o que dá poder — você quer contexto rico. A distinção é crucial: não meta user_id em Prometheus metric, mas meta sim em todo span/evento.
Logs ainda importam ou só eventos?
Logs estruturados são eventos. A distinção antiga (logs = text file) virou histórica. JSON logs com os fields certos = events. A indústria tá convergindo — OTel Logs é basicamente "wide event" padronizado.
Como testar observability em pre-prod?
Injete falhas intencionalmente (Chaos Engineering: Gremlin, Litmus). Se você simula disco cheio, DB lento, pod mort — todas as dimensões do dashboard devem acender. Se algo passa despercebido, falta instrumentação ou alerta.
- Observability > Monitoring: não só "alertas conhecidos", mas capacidade de responder perguntas novas.
- Os 3 pilares (logs, metrics, traces) são complementares — nenhum sozinho basta.
- Cardinalidade é o pecado oculto: meta rica em eventos/traces, parcimoniosa em métricas clássicas.
- Wide events (4º pilar): logs estruturados com 30-100 fields permitem drill-down sem pré-agregar.
- Continuous profiling (5º): CPU/heap em produção, baixo overhead, explica "onde o tempo vai".
- Stack 2026: OpenTelemetry SDK + Collector + backend (Grafana LGTM / Datadog / Honeycomb).
- Observability é cara — monitor a fatura. Sampling, tiered retention, cardinality limits.
Próximo módulo: os frameworks que te dizem o que medir — RED e USE.
Quiz rápido
4 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito