Dashboards customizados no Grafana

Importar dashboards prontos é o começo, mas as métricas mais valiosas são as da sua aplicação, e para essas você precisa criar painéis customizados. Grafana tem um editor visual poderoso para PromQL, templates dinâmicos com variáveis e suporte a annotations para correlacionar eventos (deploys, incidentes) com métricas.

Anatomia de um dashboard Grafana

Entenda a estrutura antes de criar:

bash
# Hierarquia do Grafana:
# Organization → Folder → Dashboard → Row → Panel

# Dashboard: conjunto de painéis com timerange compartilhado
# Row: agrupador visual (colapsável)
# Panel: visualização individual (gráfico, tabela, stat, gauge, etc.)

# Tipos de painel mais usados:
# Time series: gráfico de linha/área — bom para métricas ao longo do tempo
# Stat: valor único grande — uptime, total de usuários, latência atual
# Gauge: medidor semicircular — CPU%, uso de memória
# Bar chart: comparação entre categorias — requests por endpoint
# Table: dados tabulares — lista de containers com métricas
# Heatmap: distribuição ao longo do tempo — histograma de latência
# Logs: painel de logs Loki — correlacionado com métricas

# Criação: Dashboards → New → New Dashboard → Add visualization

Variáveis de template para dashboards dinâmicos

Variáveis permitem filtrar o dashboard por instância, serviço ou ambiente sem duplicar painéis:

promql
# Dashboard Settings → Variables → Add variable

# Variável de tipo "Query" — lista instâncias disponíveis no Prometheus:
# Name: instance
# Type: Query
# Datasource: Prometheus
# Query: label_values(node_uname_info, instance)
# Multi-value: true (selecionar múltiplas)
# Include All option: true

# Uso nos painéis (filtra pela instância selecionada):
node_memory_MemAvailable_bytes{instance="$instance"}
# Com multi-value: {instance=~"$instance"}

# Outros tipos úteis:
# Interval: variável de intervalo de tempo ($__interval)
# Custom: lista fixa (prod, staging, dev)
# Textbox: input livre

Criar painel de latência percentil

Dashboard de latência com P50, P95 e P99, o mais importante para APIs:

promql
# Panel: Latência de Requisições HTTP
# Tipo: Time series
# Queries:

# A: P50 (mediana)
histogram_quantile(0.50,
  sum(rate(http_request_duration_seconds_bucket{instance="$instance"}[$__rate_interval]))
  by (le, route)
)

# B: P95
histogram_quantile(0.95,
  sum(rate(http_request_duration_seconds_bucket{instance="$instance"}[$__rate_interval]))
  by (le, route)
)

# C: P99
histogram_quantile(0.99,
  sum(rate(http_request_duration_seconds_bucket{instance="$instance"}[$__rate_interval]))
  by (le, route)
)

# Configurações do painel:
# Unit: seconds (s)
# Min: 0
# Thresholds: 0.2s = verde, 0.5s = amarelo, 1s = vermelho
# Legend: {{route}} P{{ ... }}

Annotations: marcar eventos no dashboard

Annotations adicionam marcações verticais no gráfico para correlacionar deploys e incidentes com métricas:

bash
# Tipo 1: Annotation manual via UI
# Dashboard → Annotation marks → Add annotation
# Clique no gráfico → Add annotation

# Tipo 2: Annotation via API (ideal para deploys automatizados)
# No script de deploy:
curl -X POST http://localhost:3000/api/annotations \
  -H "Content-Type: application/json" \
  -u admin:senha \
  -d "{
    \"dashboardId\": 1,
    \"time\": $(date +%s)000,
    \"tags\": [\"deploy\", \"v2.1.0\"],
    \"text\": \"Deploy v2.1.0 — $(git log -1 --pretty=%s)\"
  }"

# Tipo 3: Annotation baseada em alerta
# Dashboard Settings → Annotations → Add annotation query:
# Datasource: Prometheus
# Expr: ALERTS{alertname="HighCPU", alertstate="firing"}
# Isso mostra quando o alerta ficou ativo no gráfico

Exportar dashboard como JSON (versionamento)

Versione dashboards no git como código, evita perda de configuração:

bash
# Exportar dashboard via API
DASHBOARD_UID="meu_dashboard_uid"
curl http://localhost:3000/api/dashboards/uid/$DASHBOARD_UID \
  -u admin:senha | python3 -m json.tool > dashboards/minha-api.json

# Script para exportar todos os dashboards:
for uid in $(curl -s http://localhost:3000/api/search -u admin:senha | python3 -c "import sys,json; [print(d['uid']) for d in json.load(sys.stdin)]"); do
  curl -s http://localhost:3000/api/dashboards/uid/$uid -u admin:senha > dashboards/$uid.json
done

# Importar dashboard do arquivo (restore ou novo ambiente):
curl -X POST http://localhost:3000/api/dashboards/import \
  -H "Content-Type: application/json" \
  -u admin:senha \
  -d @dashboards/minha-api.json

# Provisioning automático: monte /etc/grafana/provisioning/dashboards/
# e configure dashboard.yaml para carregar JSONs automaticamente

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

$__rate_interval é uma variável especial do Grafana, ajusta automaticamente o intervalo baseado no timerange do dashboard e no scrape_interval do Prometheus. Use sempre $__rate_interval em vez de valores fixos como [5m]: evita erros com timeranges muito curtos ou muito longos e garante resultados corretos.

Use offset em PromQL: http_request_duration_seconds_sum offset 1w / http_request_duration_seconds_count offset 1w, mostra a latência média de uma semana atrás. Adicione como série separada no painel com nome "Semana passada" para comparação visual com o período atual.

Causas comuns: (1) timerange muito curto vs scrape_interval; (2) labels incorretos na query; (3) $__rate_interval muito pequeno; (4) datasource errado selecionado no painel; (5) métricas com nome diferente do esperado, valide a query direto no Prometheus UI (localhost:9090) antes de criar o painel.

Use painéis Stat com valores únicos grandes: total de usuários, receita do dia, taxa de uptime. Combine com Gauge para mostrar metas. Adicione painéis de tendência (Time series) para os últimos 30 dias. Use variáveis de período (Last 24h, Last 7d, Last 30d). O foco é em métricas de negócio, não de infraestrutura.

Grafana OSS: não tem reports nativos. Grafana Enterprise/Cloud: tem. Alternativa open source: grafana-reporter (gera PDF) ou scripts que fazem screenshot via Grafana API e enviam por e-mail. Para relatórios simples: exporte os dados via API e gere um CSV/HTML com Python.