Produção em Go: Logs, Métricas, Traces e Sinais
Executar um serviço Go em produção significa que você pode responder o que aconteceu, com que frequência e quanto tempo levou - sem precisar fazer SSH em um pod para ler stdout não estruturado.
Busque em todas as páginas da documentação
Executar um serviço Go em produção significa que você pode responder o que aconteceu, com que frequência e quanto tempo levou - sem precisar fazer SSH em um pod para ler stdout não estruturado.
Noções Básicas de Observabilidade coleta trechos executáveis; artigos irmãos cobrem slog, Prometheus, OpenTelemetry, sondas, desligamento e configuração.
A observabilidade repousa sobre três pilares que se complementam.
Logs registram eventos individuais: um manipulador iniciou, um pagamento falhou, uma tentativa se esgotou.
Logs estruturados (campos chave-valor) permitem filtrar user_id=… ou trace_id=… em Loki ou CloudWatch sem arqueologia de regex.
O pacote log/slog do Go (stdlib desde Go 1.21) é a escolha padrão para novos serviços.
Métricas comprimem o comportamento em números ao longo do tempo: taxa de requisições, proporção de erros, percentis de duração.
Prometheus coleta contadores e histogramas de endpoints /metrics; Grafana plota RED (Rate, Errors, Duration) por rota ou dependência.
Traces unem spans entre serviços para que você veja que uma chamada de API de 2 s gastou 1.8 s no PostgreSQL e 150 ms em uma chamada HTTP downstream.
SDKs OpenTelemetry emitem spans para Jaeger, Tempo ou backends de fornecedores.
Além dos três pilares, serviços Go em produção expõem sinais operacionais: /healthz e /readyz para orquestradores, tratamento de SIGTERM para deploys rolling e configuração orientada por ambiente para que o mesmo binário rode em staging e prod.
Requisição
|
v
middleware -----> span de trace (OTel)
| |
v v
manipulador -----> campos slog (trace_id, rota)
|
v
métricas <----- contador/histograma (status, latência)
A instrumentação se anexa em limites estáveis.
Middleware HTTP envolve http.Handler para iniciar spans, incrementar métricas e anexar um ID de requisição ao context.Context.
Esse contexto flui para chamadas de banco de dados e RPC para que logs e spans filhos compartilhem a mesma chave de correlação.
| Sinal | Pergunta que responde | Ferramentas Go Típicas | Risco de Cardinalidade |
|---|---|---|---|
| Logs | O que aconteceu nesta requisição? | log/slog, zap (opcional) | Alto se você logar IDs únicos por linha |
| Métricas | Quantos? Quão rápido? Qual taxa de erro? | prometheus/client_golang | Alto se rótulos incluem IDs de usuário ilimitados |
| Traces | Onde o tempo foi gasto entre serviços? | OpenTelemetry Go SDK | Médio; amostragem mitiga |
| Sondas | O processo está vivo? Pode servir tráfego? | Manipuladores net/http | Baixo |
| Desligamento | Deploys podem drenar com segurança? | signal.Notify, server.Shutdown | N/A |
Logs e traces se conectam através de campos trace_id compartilhados.
Métricas permanecem agregadas: nunca coloque endereços de e-mail brutos em rótulos Prometheus.
A configuração é carregada uma vez na inicialização (flags + env) ou observa arquivos para hot reload; endpoints de observabilidade devem refletir erros de configuração na prontidão, não na vivacidade.
Cardinalidade é o assassino silencioso das pilhas de métricas.
Prefira rótulos de template http_route="/users/{id}" em vez de rótulos por usuário.
Os buckets de histograma devem corresponder aos limites do SLO (por exemplo, 50 ms, 200 ms, 1 s).
Amostragem mantém o volume de traces gerenciável: amostragem baseada em cabeça na borda ou amostragem baseada em cauda apenas para erros.
Sempre registre erros e spans de alta latência, mesmo quando o tráfego de base for amostrado para baixo.
O volume de logs cresce com QPS.
Defina níveis por ambiente (INFO em prod, DEBUG em dev), censure segredos no manipulador e evite logar corpos de requisição completos por padrão.
O slog do Go suporta LogValuer para campos caros preguiçosos.
Kubernetes distingue liveness (reiniciar se morto) de readiness (remover do balanceador de carga se as dependências falharem).
Uma falha no banco de dados deve falhar a prontidão, não a vivacidade, ou você reinicia pods que não conseguem resolver o problema.
O desligamento gracioso combina SIGTERM com um context.Context limitado passado para http.Server.Shutdown e drenagem de workers em segundo plano.
| Abordagem | Força | Fraqueza | Melhor Ajuste |
|---|---|---|---|
| Apenas slog | Zero dependências, stdlib | Sem ecossistema de appenders | Novos microsserviços |
| zap | Muito rápido, rico ecossistema | Dependência extra | Logging de QPS alto |
| Pull do Prometheus | Modelo de scrape simples | Disciplina de cardinalidade necessária | Serviços Kubernetes |
| OpenTelemetry | Traces neutros em relação ao fornecedor | Sobrecarga de configuração do SDK | Malhas multi-serviço |
| Apenas config por env | Simples 12-factor | Sem padrões baseados em arquivo | Contêineres, serverless |
Logs estruturados com ID de requisição, um endpoint /metrics com histograma de duração de requisição, /healthz e /readyz, e desligamento SIGTERM cobrem o básico.
Adicione tracing quando tiver mais de uma dependência downstream ou serviço.
Comece com log/slog na biblioteca padrão.
Alcance zap quando profiling mostrar alocações de logging no caminho quente ou você precisar de recursos que o slog ainda não oferece.
Injete trace_id e span_id do span OpenTelemetry ativo nos atributos slog em cada requisição.
Backends de log podem se vincular a UIs de trace quando os IDs corresponderem.
Rate (requisições por segundo), Errors (requisições falhas), Duration (distribuição de latência).
Instrumente na camada de middleware com rótulos de template de rota, não caminhos brutos com IDs.
Falhe na prontidão quando dependências críticas (banco de dados, cache, API upstream necessária) estiverem inacessíveis.
Mantenha a vivacidade barata para que o Kubernetes não reinicie processos saudáveis durante falhas de dependência.
Métricas bem projetadas e traces amostrados adicionam uma sobrecarga de baixa porcentagem de um dígito.
Logging de depuração ilimitado e rótulos de alta cardinalidade prejudicam mais do que atualizações de histograma.
Monte /metrics em um listener separado ou caminho de mux, restrinja o acesso à rede e faça scrape com Prometheus ou um agente compatível.
Configuração incorreta causa interrupções que parecem bugs de código.
Logs de inicialização estruturados, verificações de prontidão para variáveis de ambiente necessárias e padrões documentados reduzem o tempo médio de recuperação.
Eles ainda usam manipuladores net/http.
Envolva o roteador com o mesmo middleware para logging, métricas e tracing, independentemente do framework.
Logue o tipo de erro, operação, IDs de correlação e contexto seguro.
Evite senhas, tokens e números completos de cartão de crédito, mesmo em caminhos de erro.
Workers se beneficiam de spans em torno do processamento de jobs e chamadas externas.
Vincule o ID do job nos logs, mesmo quando os IDs de requisição HTTP não existirem.
Use httptest para atingir manipuladores e afirmar incrementos de métricas ou saída de log com manipuladores de teste slog.
Verifique se os endpoints de sonda retornam os códigos de status esperados sob falhas de dependência simuladas.
Versões da Pilha: Esta página foi escrita para Go 1.26.x (padrão GC Green Tea, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026