Painéis Dinâmicos e Alertas Inteligentes com Grafana

Painéis Dinâmicos e Alertas Inteligentes com Grafana
“O que não é medido, não pode ser melhorado.” – Peter Drucker
A capacidade de observar o comportamento de aplicações e infraestrutura em tempo real é o que diferencia um ambiente operacional saudável de um que está à beira do colapso. Neste artigo, vamos explorar como o Grafana pode ser usado para transformar dados brutos em painéis dinâmicos, correlacionar logs estruturados e disparar alertas inteligentes que evitam incidentes antes que eles afetem o usuário final.
Sumário
Fundamentos da coleta de métricas e logs
1.1 Métricas como séries temporais
Métricas são valores numéricos que descrevem o estado de um componente ao longo do tempo. Cada ponto de dado possui três partes essenciais:
| Campo | Descrição |
|---|---|
| Timestamp | Momento exato da coleta (UTC) |
| Valor | Medida numérica (ex.: taxa de erro) |
| Rótulos | Chaves de identificação (ex.: service, region) |
A maioria dos coletores de métricas expõe um endpoint HTTP que devolve as séries no formato Prometheus text. Embora não citemos o nome do projeto, o padrão é amplamente suportado por ferramentas de visualização.
Exemplo: Exporter simples em Go
// file: exporter/main.go
package main
import (
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
requests = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "app_requests_total",
Help: "Número total de requisições atendidas",
},
[]string{"service", "status"},
)
latency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "app_request_latency_seconds",
Help: "Latência das requisições em segundos",
Buckets: prometheus.ExponentialBuckets(0.001, 2, 10),
},
[]string{"service"},
)
)
func init() {
prometheus.MustRegister(requests, latency)
}
// Simula tratamento de requisição
func handle(w http.ResponseWriter, r http.Request) {
start := time.Now()
// ... lógica da aplicação ...
time.Sleep(50 time.Millisecond) // delay artificial
requests.WithLabelValues("payment", "200").Inc()
latency.WithLabelValues("payment").Observe(time.Since(start).Seconds())
w.Write([]byte("OK"))
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/", handle)
http.ListenAndServe(":9090", nil)
}
Nota: O código acima cria duas métricas (contador e histograma) e as expõe em
/metrics. Qualquer coletor compatível pode raspá‑las a cada 15 s.
1.2 Logs estruturados
Logs em texto livre são difíceis de analisar em escala. A prática recomendada é gerar JSON contendo campos padronizados (timestamp, nível, mensagem, contexto). Ferramentas como Loki, Elastic ou Splunk podem indexar esses documentos e permitir consultas avançadas.
Exemplo: Log em Go usando zap
// file: logger/main.go
package main
import (
"go.uber.org/zap"
)
func main() {
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("Transação iniciada",
zap.String("service", "payment"),
zap.String("order_id", "12345"),
zap.Float64("amount", 199.90),
)
logger.Error("Falha ao validar cartão",
zap.String("service", "payment"),
zap.String("order_id", "12345"),
zap.String("error_code", "CARD_DECLINED"),
)
}
O output será um JSON pronto para ingestão em um motor de busca de logs.
Construindo dashboards dinâmicos no Grafana
2.1 Conexão de fontes de dados
http://localhost:9090) e teste a conexão.Dica: Defina a opção Scrape interval de acordo com a criticidade dos dados (ex.: 15 s para métricas de SLA).
2.2 Variáveis de painel
Variáveis permitem que o mesmo painel sirva múltiplos serviços, regiões ou ambientes sem duplicação.
# Exemplo de definição de variável no Grafana (JSON)
{
"name": "service",
"type": "query",
"datasource": "Metrics",
"refresh": 1,
"query": "label_values(app_requests_total, service)",
"includeAll": true,
"multi": true,
"default": "payment"
}
Ao selecionar payment, inventory ou auth a consulta subjacente se ajusta automaticamente.
2.3 Painéis recomendados
| Tipo de visualização | Uso típico | Métrica de exemplo |
|---|---|---|
| Time series | Tendência de latência | app_request_latency_seconds |
| Stat | Valor atual de taxa de erro | sum(rate(app_requests_total{status!="200"}[5m])) |
| Bar gauge | Distribuição de status HTTP | sum by (status) (app_requests_total) |
| Table | Listagem de falhas recentes | app_requests_total{status!="200"} |
2.4 Exportando o dashboard como JSON
```json { "dashboard": { "title": "Visão Geral de Serviços", "panels": [ { "type": "timeseries", "title": "Latência média (últimos 5 min)", "targets": [ { "expr": "avg(app_request_latency_seconds{service=~\"$service\"})", "legendFormat": "{{service}}" } ] }, { "type": "stat", "title": "Taxa de Erro", "targets": [ { "expr": "sum(rate(app_requests_total{status!=\"200\",service=~\"$service\"}[5m]))", "legendFormat": "Erro" } ] } ], "templating": { "


