De console.log a logs estruturados
Em desenvolvimento console.log("usuário logado", id) é cômodo. Em produção
os logs são lidos por uma máquina (um agregador como Datadog, Loki ou CloudWatch),
não uma pessoa olhando o terminal. Por isso os logs devem ser estruturados:
cada linha é um objeto JSON com campos consistentes.
// Mal: texto livre, impossível de filtrar ou agregar.
console.log("Erro ao salvar o pedido 42 do usuário 7");
// Bem: JSON com campos. Dá para filtrar por nível, buscar por usuarioId...
console.log(JSON.stringify({
nivel: "error",
mensagem: "Erro ao salvar o pedido",
pedidoId: 42,
usuarioId: 7,
ts: "2026-06-22T10:00:00Z",
}));
Níveis de log
Cada entrada leva um nível de severidade, para poder filtrar:
info: eventos normais ("servidor iniciado", "requisição recebida").warn: algo inesperado mas recuperável ("repetindo conexão").error: uma falha que requer atenção (exceção, requisição falhada).
Em produção costuma-se baixar o "ruído" mostrando apenas warn e error, enquanto
em desenvolvimento se vê tudo. Bibliotecas como pino ou winston dão isso pronto.
function criarLog(nivel, mensagem) {
return { nivel, mensagem, ts: new Date().toISOString() };
}
Métricas
Os logs contam o que aconteceu; as métricas medem quanto e quão rápido: requisições por segundo, latência (p95, p99), uso de memória e CPU, taxa de erros. São expostas (p. ex. em formato Prometheus) e plotadas em painéis (Grafana) com alertas quando algo sai do intervalo.
Health checks
Um health check é um endpoint simples, normalmente GET /health, que
responde 200 e um corpo como { status: "ok" } se o serviço está vivo.
Não é um humano que o chama: ele é consultado pelo balanceador de carga, pelo orquestrador
(Kubernetes) ou pelo process manager para decidir se a instância deve receber
tráfego ou ser reiniciada.
function health(req, res) {
res.status(200).json({ status: "ok" });
}
Às vezes se distingue liveness (o processo está vivo?) de readiness (está pronto para receber tráfego, p. ex. com o BD conectado?).
Rastreabilidade
Quando uma requisição atravessa vários serviços, associa-se a ela um identificador de correlação (request id / trace id) que se propaga e é incluído em todos os logs dessa requisição. Assim você pode reconstruir o percurso completo de uma única requisição através de todo o sistema. É a base do distributed tracing (OpenTelemetry).
Exemplos
Logger estruturado com níveis, emitido como JSON
function criarLog(nivel, mensagem, extra) {
return Object.assign({ nivel, mensagem, ts: new Date().toISOString() }, extra || {});
}
console.log(JSON.stringify(criarLog("info", "Servidor iniciado", { porta: 3000 })));
console.log(JSON.stringify(criarLog("error", "Conexão perdida")));