Noções Básicas de Logging
8 exemplos para você começar com Logging para backends Node.js - 6 básicos e 2 intermediários.
Busque em todas as páginas da documentação
8 exemplos para você começar com Logging para backends Node.js - 6 básicos e 2 intermediários.
npm install pino
npm install -D pino-pretty typescript@5.6 tsxServiços de produção no Node 24.18.0 devem emitir JSON estruturado para stdout - agregadores (Datadog, Loki, CloudWatch) analisam um objeto por linha.
Máquinas analisam campos; humanos buscam level e requestId.
import pino from "pino";
const logger = pino({ level: "info" });
logger.info({ userId: "u_123", action: "login_success" }, "usuário logado");
// {"level":30,"userId":"u_123","action":"login_success","msg":"usuário logado",...}`Usuário ${id} logado` perdem campos pesquisáveis.level 30 é info no mapeamento numérico do Pino.Relacionado: pino - loggers filhos e redação
Escolha o nível que corresponde à resposta do operador, não ao humor do desenvolvedor.
logger.fatal({ err }, "banco de dados inacessível na inicialização");
logger.error({ err, orderId }, "falha na captura de pagamento");
logger.warn({ retryCount: 3 }, "timeout downstream, tentando novamente");
logger.info({ requestId }, "requisição concluída");
logger.debug({ query }, "sql executado");error - precisa de investigação ou impacto no usuário.warn - degradado, mas se recuperando (tentativas, fallbacks).info - eventos normais de negócios e ciclo de vida da requisição.debug - apenas para desenvolvimento ou amostrado em produção.Relacionado: Melhores Práticas de Logging - política de nível de log de produção
errO serializador padrão do Pino captura rastros de pilha.
try {
await chargeCard(orderId);
} catch (err) {
logger.error({ err, orderId }, "falha no carregamento");
}{ err } aciona pino.stdSerializers.err - pilha e tipo preservados.logger.error(err) sem o wrapper de objeto perde a estrutura do campo.Relacionado: Padrões de Resposta de Erro - detalhe do cliente vs log
console.log no Código da AplicaçãoLinhas não estruturadas quebram pipelines de log apenas em JSON.
// eslint no-console: error
import pino from "pino";
const log = pino();
log.info({ event: "worker_started" });console.log ignora filtros de nível e redação.no-console em src/ com exceção para scripts CLI.pino.destination({ sync: true }) para captura.Relacionado: Logging com Pino no Fastify - integração com framework
Método, caminho, status e duração alimentam dashboards SLO.
logger.info({
event: "request_complete",
method: "GET",
path: "/users",
statusCode: 200,
durationMs: 42,
requestId: "req_abc",
});requestId, não reqId em um app e rid em outro).reply.elapsedTime (Fastify) ou temporização de middleware (Express).Relacionado: IDs de Correlação de Requisição -
x-request-id
Crie no escopo do módulo; evite pino() por requisição.
// src/logger.ts
import pino from "pino";
export const logger = pino({
level: process.env.LOG_LEVEL ?? "info",
base: { service: "orders-api", version: process.env.APP_VERSION },
});base aparecem em todas as linhas - nome do serviço para índices de log multi-tenant.logger para workers via importação, não mutação global.Relacionado: pino - opções de configuração
Associe requestId uma vez; todos os logs downstream o herdam.
const child = logger.child({ requestId: "req_abc", tenantId: "t_1" });
child.info({ action: "fetch_order" });
child.info({ action: "send_receipt" });
// ambas as linhas incluem requestId e tenantIdonRequest do Fastify.req.log = req.log.child({ userId: user.id }).Relacionado: AsyncLocalStorage para Contexto - workers não-HTTP
Mantenha senhas e tokens fora do armazenamento de logs.
const logger = pino({
redact: {
paths: ["req.headers.authorization", "req.body.password", "email"],
censor: "[REDACTED]",
},
});Relacionado: Redação de PII e Conformidade - políticas de retenção
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026