Logging Estruturado
Formatos, níveis, centralização e boas práticas para logging em sistemas distribuídos.
Por que logging estruturado?
Em um sistema monolítico, ler logs em texto puro pode ser suficiente. Mas em uma arquitetura distribuída com dezenas de serviços, os logs não estruturados se tornam impossíveis de gerenciar. O logging estruturado — em que cada entrada é um objeto com campos bem definidos — é a base para conseguir buscar, filtrar e correlacionar eventos em escala.
Formatos de log
JSON como padrão
O formato mais adotado para logs estruturados é o JSON. Cada linha de log é um objeto com campos consistentes:
{
"timestamp": "2024-01-15T10:30:00.123Z",
"level": "INFO",
"service": "order-service",
"traceId": "abc123def456",
"message": "Orden creada exitosamente",
"orderId": "ORD-789",
"userId": "USR-456",
"duration_ms": 145
}
Campos essenciais
Todo log estruturado deveria incluir, no mínimo:
- timestamp: Momento exato no formato ISO 8601 com fuso horário UTC.
- level: Severidade do evento (DEBUG, INFO, WARN, ERROR, FATAL).
- service: Nome do serviço que emite o log.
- traceId / correlationId: Identificador para correlacionar logs entre serviços.
- message: Descrição legível do evento.
Níveis de log
Os níveis de log permitem filtrar por severidade e controlar o volume de informação:
| Nível | Uso | Exemplo |
|---|---|---|
| DEBUG | Detalhe interno para desenvolvimento | ”Query executada em 12ms” |
| INFO | Eventos normais do negócio | ”Ordem ORD-789 criada” |
| WARN | Situações anômalas não críticas | ”Retry #2 ao serviço de pagamentos” |
| ERROR | Falhas que exigem atenção | ”Timeout ao conectar com o DB” |
| FATAL | O serviço não pode continuar | ”Não foi possível iniciar o pool de conexões” |
Boas práticas com níveis
- Use INFO para eventos de negócio significativos, não para cada linha de código.
- Reserve ERROR para situações que realmente precisam de intervenção humana.
- Configure níveis dinamicamente por serviço — poder subir para DEBUG em produção sem redeploy é algo inestimável.
- Evite logar dados sensíveis (senhas, tokens, PII) em qualquer nível.
Centralização de logs
O problema dos logs distribuídos
Quando você tem 20 microsserviços rodando em múltiplas instâncias, os logs ficam espalhados por dezenas de containers. Sem centralização, diagnosticar um problema exige conectar-se manualmente a cada instância.
Stack de centralização
O padrão mais comum é o stack ELK (Elasticsearch, Logstash, Kibana) ou sua variante EFK (Elasticsearch, Fluentd, Kibana):
- Coleta: Cada serviço escreve logs em stdout/stderr. Um agente (Fluentd, Filebeat, Fluent Bit) os coleta.
- Processamento: Os logs são parseados, enriquecidos e transformados antes de serem armazenados.
- Armazenamento: O Elasticsearch indexa os logs para busca rápida.
- Visualização: O Kibana permite buscar, filtrar e criar dashboards sobre os logs.
Alternativas modernas
- Loki (Grafana): Armazena logs indexando apenas as labels, não o conteúdo completo. Mais econômico que o Elasticsearch para volumes altos.
- CloudWatch Logs (AWS): Solução gerenciada para ambientes AWS.
- Datadog Logs: Plataforma SaaS com correlação automática entre logs, métricas e traces.
Boas práticas
Contexto, não ruído
Cada linha de log deve trazer contexto útil. Pergunte-se: “Se um alerta me acordar às 3 da manhã, esse log me ajuda a entender o que aconteceu?”
Correlation IDs
Propague um traceId ou correlationId em cada request que percorra múltiplos serviços. Isso permite reconstruir o fluxo completo de uma operação filtrando por um único ID.
Sampling em produção
Para serviços de alto tráfego, logar cada request pode ser custoso. Implemente sampling: logue 100% dos erros, mas apenas uma porcentagem dos requests bem-sucedidos.
Retenção e rotação
Defina políticas claras de retenção:
- Logs de ERROR/FATAL: 90 dias no mínimo.
- Logs de INFO: 30 dias.
- Logs de DEBUG: Apenas em ambientes de desenvolvimento ou habilitados temporariamente.
Não logar dados sensíveis
Nunca inclua nos logs: senhas, tokens de acesso, números de cartão, dados pessoais identificáveis (PII). Use masking ou redação automática se necessário.
Logging na prática
Padrão: Request logging middleware
Um middleware que loga automaticamente cada request de entrada e sua resposta:
→ REQUEST | method=POST path=/api/orders traceId=abc123 userId=USR-456
← RESPONSE | method=POST path=/api/orders traceId=abc123 status=201 duration=145ms
Padrão: Error logging com contexto
Quando ocorre um erro, inclua todo o contexto necessário para diagnosticá-lo sem precisar reproduzi-lo:
ERROR | service=payment-service traceId=abc123 orderId=ORD-789
message="Pago rechazado por el proveedor"
provider=stripe errorCode=card_declined
retryCount=0 userId=USR-456
Resumo
O logging estruturado é o primeiro pilar da observabilidade. Logs bem formatados, centralizados e com contexto adequado permitem diagnosticar problemas rapidamente, entender o comportamento do sistema e cumprir requisitos de auditoria. O investimento em uma boa estratégia de logging se paga com folga na primeira vez que você precisar investigar um incidente em produção.