Logs: o que registar, e o que nunca
Os registos servem para responder a uma pergunta que se faz sempre tarde: o que é que aconteceu às 3 da manhã? Um registo que não responde a isso é papel; um que responde de mais é um problema legal.
1. Níveis, e o que cabe em cada um
error — falhou e alguém tem de saber. Uma exceção, uma gravação recusada.
warn — não falhou, mas não está bem. Uma tentativa recusada, um limite atingido.
info — acontecimentos que interessam depois: arranque, deploy, uma encomenda criada.
debug — o detalhe para caçar um problema. Desligado em produção.
Se tudo for error, nada é: o alerta que dispara cem vezes por dia é um alerta que ninguém lê.
2. Estruturados, não frases
// Bonito para uma pessoa, inútil para procurar
console.log(`Utilizador ${id} falhou a entrar às ${new Date()}`);
// Feio de ler, e pesquisável
logger.warn({ evento: 'entrada_falhada', utilizadorId: id, ip });Com objetos, responder a "quantas tentativas falhadas por IP na última hora" é uma consulta. Com frases, é um grep e alguma esperança.
3. O que nunca entra num registo
Passwords. Nem em erros, nem "só desta vez para ver o que se passa".
Tokens, chaves e cookies de sessão. Um registo com um token é uma sessão utilizável por quem o ler.
Dados pessoais a mais. Moradas, números de identificação, o corpo de mensagens privadas. Os registos vão para sítios com outras regras de acesso — e o RGPD aplica-se lá como aqui.
O corpo inteiro dos pedidos. É o caminho mais rápido para os três pontos anteriores.
const OCULTAR = new Set(['password', 'token', 'authorization', 'cookie']);
const seguro = Object.fromEntries(
Object.entries(dados).map(([chave, valor]) => [
chave,
OCULTAR.has(chave.toLowerCase()) ? '[oculto]' : valor,
])
);4. O identificador que junta as pontas
Um pedido que atravessa três serviços deixa três registos sem relação aparente. Um identificador gerado à entrada e passado adiante transforma isso numa história legível:
const pedidoId = crypto.randomUUID();
logger.info({ pedidoId, rota: '/api/encomendas', ms: 42 });E rotação, sempre. Registos sem limite enchem o disco — e um disco cheio derruba a aplicação que os escrevia.