Logging
Este skill é auto-contido para uso diário. Referência mais aprofundada (requer o checkout completo do harness): patterns/logging/LOGGING_STANDARDS.md (mandato completo e schema de configuração), patterns/logging/logging.yaml.example (template YAML testado), patterns/logging/config_loader.py (implementação de referência em Python com 99% de cobertura de testes).
Quando se aplica
Logging estruturado completo com configuração YAML, múltiplos backends e rotação é obrigatório no nível Produção. Protótipos: print()/console.log() é aceitável. Ferramentas internas: logging estruturado recomendado, backend único aceitável. Verifique primeiro o nível de rigor do projeto.
Níveis de log — escolha o correto
| Nível | Uso |
|---|---|
TRACE | Detalhes de alta frequência por chamada; desabilitado em produção por padrão |
DEBUG | Informações de diagnóstico para desenvolvedores; desabilitado em produção por padrão |
INFO | Eventos operacionais normais (inicialização, requisição concluída) |
WARNING | Algo inesperado mas recuperável; vale a pena investigar |
ERROR | Uma falha real da qual o sistema não conseguiu se recuperar |
CRITICAL | O processo deve parar ou os dados estão corrompidos |
Regra geral: se você acordaria alguém às 3 da manhã, é ERROR ou CRITICAL.
Logging estruturado: mensagem + campos, nunca interpolação de strings
# ERRADO: não estruturado — não é possível consultar ou filtrar por user_id ou duration
logger.info(f"Requisição concluída para o usuário {user_id} em {duration}ms")
# CERTO: mensagem é um rótulo estático; contexto está em campos estruturados
logger.info("request.completed", user_id=user_id, duration_ms=duration)
// Equivalente Node/pino/winston
logger.info({ userId, durationMs }, 'request.completed');
O que NÃO registrar
Nunca registre: senhas, tokens, chaves de API, números completos de cartão de crédito, SSNs, IDs de sessão ou quaisquer dados sob política de PII/GDPR. Redija ou omita antes de registrar. Se a utilidade do log e o sigilo entrarem em conflito, redija. Não registre o segredo "por completeza."
# ERRADO: registra o token bruto
logger.info("auth.token_issued", token=issued_token)
# CERTO: registre apenas o que é seguro expor
logger.info("auth.token_issued", user_id=user_id, expires_at=exp)
Configuração: template YAML, não feito do zero
Copie patterns/logging/logging.yaml.example como seu ponto de partida:
cp patterns/logging/logging.yaml.example config/logging.yaml
O template suporta interpolação ${VAR:-default}, múltiplos backends de handlers (arquivo, console, OTEL) e rotação. Criar um schema de logging do zero duplica trabalho já testado.
Verificação antes de marcar o trabalho como concluído
- Execute o caminho do código e confirme que as linhas de log realmente são emitidas — não assuma.
- Passe uma linha de log por
jq(ou equivalente) para confirmar que é um JSON válido (ou qualquer formato configurado). - Informe na descrição do PR quais eventos você verificou que emitem corretamente.
Saída local vs. produção
Local/dev: legível por humanos (formato pretty / dev, colorizado).
Produção: JSON interpretável por máquina, sem códigos de cor. Configure isso através de uma variável de ambiente, não de um branch de código:
handlers:
console:
formatter: ${LOG_FORMAT:-json} # sobrescreva para 'pretty' em dev