Pular para o conteúdo

Montar um dashboard que alguém usa

Intermediário14 min de leituraobservabilidade

O teste de um bom dashboard: alguém de plantão, às 3h, abre e sabe em dez segundos se o serviço está bem. Se precisa rolar a página, escolher entre vinte painéis ou interpretar um gráfico com quarenta linhas, ele falhou.

Um dashboard por serviço, com um objetivo declarado no topo: “o serviço de pedidos está saudável agora?”. Todo painel que não ajuda a responder isso vai para outro dashboard — de capacidade, de custo, de negócio.

Taxa, erro e duração, lado a lado, ocupando a primeira tela.

# Rate — requisições por segundo, por rota
sum by (route) (rate(http_requests_total{service="$servico"}[$__rate_interval]))
# Errors — proporção, nunca contagem absoluta
sum(rate(http_requests_total{service="$servico", status=~"5.."}[$__rate_interval]))
/ sum(rate(http_requests_total{service="$servico"}[$__rate_interval]))
# Duration — p50, p95 e p99 no mesmo painel
histogram_quantile(0.95, sum by (le) (
rate(http_request_duration_seconds_bucket{service="$servico"}[$__rate_interval])))

Use $__rate_interval em vez de [5m] fixo: o Grafana ajusta a janela ao zoom e você para de ver gráfico vazio ao olhar a última hora.

Percentil, nunca média — a média de latência esconde exatamente quem está sofrendo. E p50 junto do p99 mostra se o problema é geral ou de cauda.

Pergunta Painel
Está pior que há uma hora? Série temporal
Está dentro do aceitável agora? Stat com limiar colorido
Onde está concentrado? Barras ou tabela ordenada
Como se distribui? Heatmap
Quantos estão saudáveis? Stat com valor atual

Evite gráfico de pizza (não mostra tendência), gauge para série temporal, e mais de cinco séries num painel — acima disso vira emaranhado. Para “quem são os piores”, use topk(5, ...) com tabela.

Configure sempre: unidade correta (segundos, requisições/s, porcentagem), limiares de cor alinhados ao SLO, e título em forma de pergunta (“Erros 5xx por rota”), não o nome da métrica.

Abaixo da dobra, em linhas que começam fechadas:

  • Saturação: CPU, memória, pool de conexões, tamanho de fila.
  • Dependências: latência e erro por dependência (banco, cache, gateway).
  • Infraestrutura: réplicas prontas, reinícios, throttling.
  • Links: runbook, logs filtrados por este serviço, traces, repositório.

A linha de links é subestimada e é o que mais economiza tempo em incidente.

5. Use variáveis para não multiplicar dashboards

Seção intitulada “5. Use variáveis para não multiplicar dashboards”
Nome: servico Tipo: Query Consulta: label_values(http_requests_total, service)
Nome: namespace Tipo: Query Consulta: label_values(kube_pod_info, namespace)
Multi-value: sim Include All: sim

Com multi-valor, use =~"$servico" (regex) no seletor. Com =, a consulta quebra assim que alguém escolhe dois valores.

Metade das perguntas de incidente é “mudou alguma coisa?”. Deixe a resposta visível:

Janela do terminal
curl -sX POST http://grafana/api/annotations \
-H "Authorization: Bearer $GRAFANA_TOKEN" -H 'Content-Type: application/json' \
-d '{"tags":["deploy","loja"],"text":"loja 1.8.3","time":'"$(date +%s000)"'}'

Adicione a anotação no fim do job de deploy. Anote também mudanças de feature flag e migrações — são as outras duas causas mais comuns.

Painel editado na interface é mudança sem revisão, que se perde no próximo restore. Exporte o JSON, versione no repositório do serviço e provisione:

apiVersion: 1
providers:
- name: loja
folder: Serviços
type: file
allowUiUpdates: false # exploração continua possível salvando cópia
options: { path: /var/lib/grafana/dashboards }
Sintoma Causa provável
Abrem e vão direto para os logs Os painéis não respondem à pergunta real
“Está tudo verde e o cliente reclama” Falta a métrica de sintoma; você mede infraestrutura
Ninguém sabe interpretar Sem unidade, sem limiar, sem título claro
Cada time tem o seu, todos diferentes Falta um dashboard padrão vindo do golden path
Demora a carregar Consultas caras: pré-calcule com recording rules
  • Uma pergunta declarada para o dashboard.
  • RED na primeira tela, com no máximo cinco a sete painéis.
  • Erro como proporção e latência em percentis.
  • Unidades e limiares configurados.
  • Segunda camada colapsada, com links para runbook e logs.
  • Variáveis no lugar de dashboards duplicados.
  • Deploys anotados na linha do tempo.
  • JSON versionado e provisionado.