Monitoramento avançado de aplicações Go: das métricas aos alertas
No desenvolvimento moderno com Go (Golang), a registração básica e o Health Check não são suficientes. Para sistemas em produção, é necessária uma observabilidade profunda: coleta de métricas personalizadas, exportação para Prometheus, visualização no Grafana e alertas automáticos. Neste artigo, abordaremos o nível avançado de monitoramento de aplicações Go — desde a arquitetura de métricas até a configuração de alertas baseados em lógica de negócios.
Arquitetura de monitoramento: Prometheus + Go
A stack padrão de monitoramento para Go inclui:
- Prometheus — sistema de coleta e armazenamento de métricas (modelo pull).
- Cliente Go do Prometheus (
prometheus/client_golang) — biblioteca para exportação de métricas. - Grafana — visualização de dashboards.
- Alertmanager — gerenciamento de alertas (email, Slack, Telegram).
A aplicação Go deve fornecer um endpoint HTTP (geralmente /metrics) do qual o Prometheus coleta os dados. Vamos ver a configuração básica.
package main
import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { // Registro de métricas padrão do Go (runtime, GC, goroutines) prometheus.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) prometheus.MustRegister(prometheus.NewGoCollector())
http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}Ao iniciar a aplicação, você obterá métricas padrão: go_goroutines, process_cpu_seconds_total, go_memstats_alloc_bytes e outras. Mas para monitoramento avançado, isso não é suficiente — são necessárias métricas personalizadas.
Criação de métricas personalizadas: Gauge, Counter, Histogram
O Prometheus suporta quatro tipos principais de métricas. Vamos vê-los com exemplos de uma aplicação Go que processa requisições HTTP.
Counter (contador) — número de eventos
Usado para contar requisições, erros, execuções de tarefas.
var requestCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Número total de requisições HTTP", }, []string{"method", "endpoint", "status"},)
func init() { prometheus.MustRegister(requestCounter)}
func handler(w http.ResponseWriter, r *http.Request) { // Processamento da requisição requestCounter.WithLabelValues(r.Method, r.URL.Path, "200").Inc()}Gauge (medidor) — valores atuais
Ideal para monitorar filas, pools de conexão, temperatura.
var queueSize = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "task_queue_size", Help: "Tamanho atual da fila de tarefas", },)
func addToQueue() { queueSize.Inc()}
func processFromQueue() { queueSize.Dec()}Histogram (histograma) — distribuição de valores
Usado para medir tempo de resposta ou tamanho de dados.
var requestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Histograma do tempo de processamento de requisições", Buckets: prometheus.DefBuckets, // 0.005, 0.01, 0.025, 0.05, ... }, []string{"endpoint"},)
func measureRequest(endpoint string, duration float64) { requestDuration.WithLabelValues(endpoint).Observe(duration)}Summary (sumário) — quantis
Semelhante ao histograma, mas calcula quantis exatos (p50, p95, p99).
var requestLatency = prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "http_request_latency_seconds", Help: "Latência de requisições (quantis)",