🧠FFVAcademy
🔍

Observability: os 3 pilares (logs, métricas, traces) e por que não basta

15 min de leitura·+75 XP

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ãoMonitoringObservability
PerguntasAs que você previuQualquer pergunta ad-hoc
DashboardsFixos, por dashboardExploratórios, drill-down livre
CardinalidadeBaixa (agregada)Alta (contexto preservado)
AlertasBaseados em thresholds absolutosBaseados em SLO burn rates
DebuggingGrep em logsDecompor evento por dimensão
Ferramentas típicasNagios, Zabbix, PromHoneycomb, Datadog, Tempo
💡
Frase canônica: "Monitoring is for known unknowns; observability is for unknown unknowns." — Charity Majors. Sistemas distribuídos modernos falham de formas que ninguém previu no dia do deploy.

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)
PilarGranularidadeUso típicoCusto
MetricsAgregado (contadores, histogramas)Dashboards, alertas, SLOsBarato — timeseries compactas
LogsPor evento (texto/JSON)Debugging detalhado, audit, forensicsAlto — volume cresce com tráfego
TracesPor request (span tree)Entender latência distribuída, root cause em microserviçosMé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.

text
# 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)
🚨
"Cardinality explosion" é o bug mais comum de observability. Dev adiciona label 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.

json
// 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).

💡
"Wide events are all you need": artigo polêmico da Charity Majors (2024) argumenta que com wide events + ferramenta de query decente, você pode derivar métricas, replicar traces, e substitui 80% dos dashboards tradicionais. Extremo, mas reflete o movimento: cardinalidade alta + query flexível > N sistemas separados.

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
FerramentaTechUso
Pyroscope (Grafana)eBPF + agentsOpen-source, multi-lang, integrado com Grafana
ParcaeBPF puroOpen-source, foco em infra estilo K8s
Datadog Continuous ProfilerAgent proprietárioEnterprise, deep integration com APM
Google Cloud ProfilerSDK por languageLow-overhead, GCP native
Polar SignalsParca commercialEmpresa por trás do Parca
⚠️
Quando vale a pena: sua app tem bottlenecks intermitentes que não reproduzem em dev/staging. Traces mostram "db.query took 3s" mas você não sabe qual query. Com profiler, você vê o stack completo naquele momento.

O que montar em 2026: stack mínimo

PilarOpen-sourceManaged
MetricsPrometheus + GrafanaDatadog, New Relic, Honeycomb, Chronosphere, Grafana Cloud
LogsLoki, ELK stack, Vector + ClickHouseDatadog Logs, Elastic Cloud, Grafana Cloud Logs
TracesTempo, Jaeger, Zipkin (legacy)Honeycomb, Datadog APM, Lightstep
EventsClickHouse + Vector + GrafanaHoneycomb (pioneer), Datadog CI, Axiom
ProfilingPyroscope, ParcaDatadog, Polar Signals, GCP
InstrumentaçãoOpenTelemetry SDK + Collector(mesma, padrão do mercado)
💡
Escolha de 2026: se você está começando, OpenTelemetry pra instrumentar (SDK unificado, export pra qualquer backend) + um dos "3 caminhos":
  1. Grafana LGTM stack (Loki + Grafana + Tempo + Mimir) — open-source, self-host ou Grafana Cloud
  2. Datadog — plug-and-play, caro mas completo
  3. 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).
🚨
Regra prática: monitore o custo do monitoring. Dashboard com fatura mensal por pilar, alerta se passar do budget. Já teve startup que gastou mais em Datadog que em AWS compute.

Decisões reais

📋 Empresa small/mid começando do zero, equipe de 5-20 devs

OpenTelemetry SDK + Grafana Cloud (LGTM) free tier

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: DatadogMenor 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

Self-host LGTM ou ELK + Jaeger, com access control granular

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 cloudExiste mas caro e ainda compartilhado.

📋 App tem bottlenecks que só aparecem em produção com carga real

Continuous profiling (Pyroscope ou Datadog Profiler)

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

Take-aways:
  • 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

Continue lendo