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ívelUsoExemplo
DEBUGDetalhe interno para desenvolvimento”Query executada em 12ms”
INFOEventos normais do negócio”Ordem ORD-789 criada”
WARNSituações anômalas não críticas”Retry #2 ao serviço de pagamentos”
ERRORFalhas que exigem atenção”Timeout ao conectar com o DB”
FATALO 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):

  1. Coleta: Cada serviço escreve logs em stdout/stderr. Um agente (Fluentd, Filebeat, Fluent Bit) os coleta.
  2. Processamento: Os logs são parseados, enriquecidos e transformados antes de serem armazenados.
  3. Armazenamento: O Elasticsearch indexa os logs para busca rápida.
  4. 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.