Estratégias de logging: o que e como registrar
1. Fundamentos do Logging Eficaz
Em sistemas distribuídos modernos, o log é frequentemente a única fonte de verdade quando algo dá errado. Diferente de métricas (que mostram agregados) ou tracing (que mostra o caminho de uma requisição), o logging fornece o contexto narrativo do que realmente aconteceu em cada ponto da execução.
Existem três categorias principais de logging:
- Logging operacional: usado para monitorar a saúde do sistema (startups, shutdowns, heartbeats)
- Logging de auditoria: registro imutável de ações críticas para compliance (quem fez o quê e quando)
- Logging de depuração: detalhes granulares usados durante desenvolvimento e troubleshooting
O princípio fundamental é: registrar informação suficiente para diagnosticar problemas, mas não tanta a ponto de gerar ruído ou custo excessivo de armazenamento e processamento.
2. O que registrar: categorias essenciais de eventos
Nem todo evento merece um log. As categorias que sempre devem ser registradas são:
Eventos de entrada e saída — toda requisição recebida e sua respectiva resposta devem ser logadas com um identificador de correlação único:
2025-01-15T10:30:00.123Z INFO [user-service] Request iniciada | trace_id=abc123 | method=POST | path=/api/users | body_size=2048
2025-01-15T10:30:00.456Z INFO [user-service] Request concluída | trace_id=abc123 | status=201 | duration_ms=333
Mudanças de estado críticas — transições de estado, falhas de conexão, timeouts, abertura de circuit breakers:
2025-01-15T10:30:01.789Z WARN [payment-service] Circuit breaker aberto | serviço=gateway-pagamento | timeout_ms=5000 | tentativas=3
Dados de contexto — ID de usuário, ID de transação, serviço de origem, versão do deploy. Esses campos permitem filtrar e correlacionar logs entre serviços:
2025-01-15T10:30:02.000Z ERROR [order-service] Falha ao processar pedido | user_id=u789 | transaction_id=txn456 | service_version=2.1.0 | erro=estoque_insuficiente
3. O que NÃO registrar: riscos e armadilhas comuns
Dados sensíveis — senhas, tokens de autenticação, números de cartão de crédito, PII (informações pessoais identificáveis). Se precisar registrar algo sensível, use mascaramento:
# ERRADO
2025-01-15T10:30:03.000Z INFO Login realizado | email=joao@email.com | senha=minhaSenha123
# CORRETO
2025-01-15T10:30:03.000Z INFO Login realizado | email=j***@email.com | senha=***
Logs excessivos em hot paths — loops que executam milhares de vezes por segundo não devem logar cada iteração. Isso gera overhead de I/O e degrada performance. Use contadores ou amostragem.
Informações redundantes — se você já tem métricas para latência (p99, p50) e tracing para o caminho completo da requisição, não precisa logar cada etapa intermediária. Log só o que métricas e tracing não capturam.
4. Níveis de severidade e quando usar cada um
| Nível | Uso | Exemplo |
|---|---|---|
DEBUG |
Desenvolvimento e troubleshooting local. Desligado em produção. | DEBUG Parâmetros da query: {filtros} |
INFO |
Fluxo normal de operação. Startup, shutdown, requests bem-sucedidos. | INFO Serviço iniciado na porta 8080 |
WARN |
Situações anômalas que não quebram o sistema. Retry, degradação leve. | WARN Timeout na primeira tentativa, iniciando retry |
ERROR |
Falhas que exigem intervenção. Exceções não tratadas, dependências offline. | ERROR Banco de dados indisponível após 3 tentativas |
FATAL |
Estado irrecuperável que encerra o processo. | FATAL Falha na inicialização do pool de conexões |
Regra prática: em produção, configure o nível mínimo como INFO ou WARN. Ative DEBUG apenas sob demanda para troubleshooting específico.
5. Estrutura e formato do registro
Logging estruturado em JSON é o padrão da indústria. Ele permite consultas eficientes em sistemas centralizados como Elasticsearch, Splunk ou Loki:
{
"timestamp": "2025-01-15T10:30:04.000Z",
"level": "ERROR",
"service": "api-gateway",
"message": "Falha ao rotear requisição",
"trace_id": "abc123",
"span_id": "def456",
"environment": "production",
"host": "web-01",
"method": "GET",
"path": "/api/users/789",
"status_code": 502,
"duration_ms": 15000,
"error": "upstream_connection_timeout"
}
Campos obrigatórios em todo log:
- timestamp — formato ISO 8601 com timezone
- level — DEBUG, INFO, WARN, ERROR, FATAL
- service — nome do serviço que gerou o log
- message — mensagem legível do evento
- trace_id — ID de correlação entre serviços
6. Estratégias de contexto e correlação
Em sistemas distribuídos, um único trace_id deve ser propagado entre todos os serviços envolvidos em uma requisição. Isso permite reconstruir o fluxo completo.
Propagação síncrona — o trace_id viaja no header HTTP (X-Trace-Id) e é extraído no middleware de cada serviço:
# Serviço A recebe requisição sem trace_id, gera um novo
trace_id = gerar_uuid()
# Serviço A chama Serviço B, passa trace_id no header
GET /api/orders HTTP/1.1
X-Trace-Id: abc123
# Serviço B extrai trace_id do header e usa em todos os logs
2025-01-15T10:30:05.000Z INFO [order-service] Processando pedido | trace_id=abc123
Propagação assíncrona — em filas ou mensageria, o trace_id deve ser incluído no payload ou nos headers da mensagem.
MDC (Mapped Diagnostic Context) — em Java, .NET e outras linguagens, use MDC para anexar automaticamente o contexto (trace_id, user_id) a todos os logs gerados durante a execução de uma thread ou request scope:
// Configuração do MDC no middleware
MDC.put("trace_id", request.getHeader("X-Trace-Id"));
MDC.put("user_id", usuario.getId());
// Todos os logs subsequentes incluirão esses campos automaticamente
logger.info("Pedido criado com sucesso");
// Saída: 2025-01-15T10:30:06.000Z INFO trace_id=abc123 user_id=u789 Pedido criado com sucesso
7. Gerenciamento de volume e rotação
Logs sem controle viram custo e ruído. Políticas recomendadas:
- Retenção: logs de
INFOeWARN— 30 dias. Logs deERROReFATAL— 90 dias (ou conforme compliance). Logs de auditoria — 1 ano ou mais. - Amostragem seletiva: para logs de alta frequência (ex: health checks a cada 5 segundos), registre apenas 1 a cada 10 ocorrências ou apenas quando falharem.
- Buffers e envio assíncrono: nunca bloqueie a thread da aplicação esperando o log ser escrito em disco ou enviado para a rede. Use bibliotecas que operam em background (ex: Logback AsyncAppender, Serilog sink assíncrono).
8. Monitoramento e alertas baseados em logs
Dashboards e alertas transformam logs de repositório morto em ferramenta proativa:
Dashboards essenciais:
- Taxa de erros por serviço e endpoint (quantidade de ERROR por minuto)
- Distribuição de níveis de severidade ao longo do tempo
- Top 5 mensagens de erro mais frequentes
- Latência média e p99 extraída de logs de resposta
Alertas críticos:
- Pico de ERROR (ex: > 10 erros/minuto em qualquer serviço)
- Ausência de heartbeat (nenhum log de INFO de um serviço por > 5 minutos)
- Padrões anômalos (ex: aumento súbito de WARN de timeouts)
Revisão periódica: a cada sprint, revise os logs registrados. Ajuste níveis que estão muito verbosos e remova logs que se provaram inúteis. Logging é um produto que precisa de manutenção contínua.
Referências
- 12 Factor App — Logs — Documentação do método Twelve-Factor App sobre tratamento de logs como fluxo de eventos, sem armazenamento local.
- The Log: What Every Software Engineer Should Know About Real-Time Data — Artigo seminal de Jay Kreps (LinkedIn) sobre logs como abstração unificadora em sistemas distribuídos.
- Structured Logging in .NET — Documentação oficial da Microsoft sobre logging estruturado, níveis de severidade e provedores de log.
- Logging Best Practices — Google SRE Book — Capítulo do Site Reliability Engineering do Google sobre monitoramento e logging em sistemas distribuídos.
- Elastic Common Schema (ECS) — Logging Reference — Documentação do Elastic Common Schema, padrão de campos para logs estruturados, amplamente usado em stack ELK.
- OWASP Logging Cheat Sheet — Guia de segurança da OWASP sobre o que registrar e o que evitar para não expor dados sensíveis.