M02·06Observabilidade

CAPÍTULO 06

Observabilidade

Logs estruturados com slog, métricas RED com Prometheus e o mínimo que todo backend precisa expor.

Por Thiago Souza7 min de leituraAtualizado em 2026-05

Analogia da caixa-preta de avião: quando um avião cai, ninguém acha o piloto e pergunta "o que aconteceu". Ele tá morto. Vão na caixa-preta — que registrou tudo. Logs, métricas e traces são a caixa-preta do seu backend.

Observabilidade tem 3 pilares:

  1. Logs — diário do que aconteceu.
  2. Métricas — números agregados (req/s, latência, erro %).
  3. Traces — caminho de uma request por todo o sistema.

Para começar, foco em logs estruturados e métricas básicas.

Logs estruturados

Por que estruturado? Porque fmt.Println("usuário 123 fez login") é inútil em escala. Como você busca? Como filtra? Logs estruturados são JSON, com campos. Aí sim ferramentas como Datadog, Loki, Elasticsearch fazem mágica.

Go 1.21+ trouxe log/slog na biblioteca padrão. É o padrão moderno:

go
package main
 
import (
    "log/slog"
    "os"
)
 
func main() {
    // Logger que escreve JSON no stdout.
    logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
        Level: slog.LevelInfo,
    }))
    slog.SetDefault(logger)
 
    slog.Info("servidor iniciado",
        "porta", 8080,
        "env", "production",
    )
 
    // Saída:
    // {"time":"2025-...","level":"INFO","msg":"servidor iniciado","porta":8080,"env":"production"}
}

Boas práticas de log:

  • Use níveis corretos (Debug, Info, Warn, Error). Não logue tudo como Info.
  • Nunca logue dados sensíveis — senha, token, CPF, cartão. Nunca. Mesmo. Em ambiente nenhum.
  • Inclua um request_id em cada log de request — isso permite rastrear a jornada inteira.
  • Loga onde a decisão acontece, não em todo lugar. Excesso de log polui mais do que ajuda.
  • Erros com contexto: slog.Error("falha ao salvar pedido", "order_id", id, "err", err).

Métricas simples

Métricas mínimas que todo backend deveria ter:

  • RED: Rate (req/s), Errors (% erros), Duration (latência p50, p95, p99).
  • Saúde de dependências: banco está respondendo? Redis está respondendo?
  • Filas: quantos itens pendentes? Quanto tempo o item mais antigo está esperando?

A ferramenta mais comum em Go é Prometheus (cliente: prometheus/client_golang):

go
import "github.com/prometheus/client_golang/prometheus"
 
var (
    httpRequests = prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total de requests HTTP por método e status",
        },
        []string{"method", "path", "status"},
    )
 
    httpDuration = prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "http_request_duration_seconds",
            Help:    "Duração de requests HTTP",
            Buckets: prometheus.DefBuckets,
        },
        []string{"method", "path"},
    )
)
 
func init() {
    prometheus.MustRegister(httpRequests, httpDuration)
}
 
// middleware que mede tudo
func metricsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        rw := &statusRecorder{ResponseWriter: w, status: 200}
 
        next.ServeHTTP(rw, r)
 
        dur := time.Since(start).Seconds()
        httpRequests.WithLabelValues(r.Method, r.URL.Path,
            strconv.Itoa(rw.status)).Inc()
        httpDuration.WithLabelValues(r.Method, r.URL.Path).Observe(dur)
    })
}

Depois é só expor o endpoint /metrics e apontar o Prometheus para ele.

Este capítulo cobre o essencial de observabilidade para um backend Go. O Módulo 06 aprofunda os temas: Quatro Sinais Dourados, SLOs, error budget, alertas acionáveis e o stack Prometheus + Grafana completo.