Trace Events registram eventos detalhados do Node.js e do V8 em um formato que pode ser analisado por visualizadores de timeline. Eles ajudam a investigar garbage collection, atividade assíncrona, bootstrap, chamadas nativas, duração de operações e períodos de bloqueio que são difíceis de entender apenas com métricas agregadas.
O resultado costuma ser um arquivo JSON compatível com ferramentas baseadas no formato de tracing do Chromium. A captura pode gerar muito dado e adicionar overhead, portanto deve ser curta, direcionada e protegida.
Ativando trace events
node --trace-events-enabled dist/server.jsO Node.js cria um arquivo de trace no diretório atual. Para evitar misturar execuções, configure padrão de nome e diretório.
Selecionando categorias
node \
--trace-events-enabled \
--trace-event-categories node,v8 \
dist/server.jsCategorias controlam quais eventos são coletados. Ativar tudo aumenta volume e pode esconder o sinal. Comece com a pergunta que deseja responder.
Padrão do nome do arquivo
node \
--trace-events-enabled \
--trace-event-file-pattern='diagnostics/node-trace-${pid}-${rotation}.json' \
dist/server.jsO suporte a marcadores e rotação depende das opções da versão utilizada. Teste o comando antes de adotar em produção.
Gerando carga representativa
O trace precisa conter o problema. Um fluxo básico:
- inicie a aplicação;
- aguarde readiness e aquecimento;
- comece a captura;
- gere carga estável;
- reproduza o sintoma;
- encerre o processo de forma controlada;
- salve métricas do mesmo intervalo.
Se a captura inclui minutos ociosos, inicialização e várias rotas, a análise fica mais difícil.
Abrindo o arquivo
Visualizadores de tracing permitem importar o JSON e navegar pela timeline. Ferramentas do ecossistema Chromium e analisadores compatíveis mostram faixas por thread, eventos e duração.
Não envie o arquivo para um serviço público sem revisar dados. Nomes de funções, caminhos e argumentos podem revelar arquitetura interna.
O que procurar
- longos períodos contínuos na thread principal;
- eventos de garbage collection frequentes;
- pausas grandes;
- operações síncronas;
- atividade intensa durante bootstrap;
- tarefas repetidas;
- lacunas entre início e conclusão assíncrona;
- desequilíbrio entre Worker Threads;
- eventos próximos a picos de p99.
Trace e CPU profile
Trace Events mostra uma linha do tempo; CPU profile mostra onde amostras de CPU se concentram. Use trace para localizar a janela problemática e profiling para identificar funções dominantes.
Uma timeline pode mostrar bloqueio de 400 ms, mas não necessariamente todos os detalhes da pilha. Um flamegraph complementa essa visão.
Trace e event loop delay
Métricas de delay indicam que callbacks atrasaram. O trace ajuda a visualizar o que ocorreu no mesmo período. Correlacione timestamps, levando em conta relógios e unidades diferentes.
Garbage collection
Categorias do V8 podem mostrar eventos de GC. Procure frequência, duração e relação com aumento de memória. Muitos GCs curtos podem indicar alta taxa de alocação; pausas longas podem surgir com heap grande ou pressão intensa.
Combine com process.memoryUsage(), heap profiler e snapshots. O trace sozinho não identifica quais objetos estão retidos.
Async Hooks e trace
Eventos assíncronos ajudam a relacionar criação e execução de recursos. Entretanto, capturas detalhadas podem ficar enormes em aplicações com muitas promises. Filtre categorias e reduza duração.
Worker Threads
A timeline pode exibir atividade em threads diferentes. Confirme IDs e nomes para distinguir thread principal, workers e threads internas do runtime. Um worker saturado pode não aparecer nas métricas agregadas da forma esperada.
Eventos personalizados
O módulo node:trace_events permite habilitar categorias em código:
import { createTracing } from 'node:trace_events';
const tracing = createTracing({
categories: ['node.perf', 'node.async_hooks'],
});
tracing.enable();
// executar cenário
tracing.disable();As categorias devem existir e fazer sentido para a versão usada. A API controla categorias, mas não substitui um sistema de spans de aplicação.
Verificando categorias habilitadas
import { getEnabledCategories } from 'node:trace_events';
console.log(getEnabledCategories());Essa informação ajuda a validar configurações, especialmente quando opções são fornecidas por NODE_OPTIONS.
Captura sob demanda
Uma aplicação interna pode habilitar tracing por uma janela curta:
const tracing = createTracing({ categories: ['node', 'v8'] });
async function captureScenario(operation) {
tracing.enable();
try {
return await operation();
} finally {
tracing.disable();
}
}Como a coleta e o arquivo são controlados pelo runtime, valide exatamente quando eventos começam e terminam. Evite capturas concorrentes descoordenadas.
Sinal administrativo
Você pode associar uma captura a um sinal ou endpoint interno, mas aplique autenticação, auditoria e cooldown. Uma pessoa mal-intencionada não deve conseguir gerar arquivos ilimitados.
Correlação com request ID
Trace Events de runtime não substitui tracing distribuído. Para relacionar uma requisição específica, use OpenTelemetry e logs com request ID. Depois alinhe a janela temporal com o trace do processo.
Formato e tamanho
Arquivos podem crescer rapidamente. Defina:
- duração máxima;
- categorias mínimas;
- diretório dedicado;
- limite de disco;
- retenção;
- compressão após fechamento;
- coleta segura;
- identificação de versão e PID.
Containers
Grave em volume que possa ser coletado antes da remoção do container. Um trace em filesystem efêmero desaparece com o pod. Monitore espaço para evitar evictions.
Kubernetes
Capture uma única réplica para reduzir custo e volume. Marque o pod fora do balanceamento se o overhead puder afetar usuários. Registre limites de CPU, throttling e nó.
Produção
Em produção:
- use janela curta;
- ative somente categorias necessárias;
- monitore impacto;
- não capture todas as réplicas;
- proteja arquivos;
- remova após análise;
- registre quem iniciou;
- tenha procedimento de rollback.
Comparação antes e depois
Repita o mesmo cenário com:
- mesma versão do Node.js;
- mesmo hardware e limites;
- mesma carga;
- mesmo conjunto de dados;
- mesmo aquecimento;
- mesmas categorias;
- duração semelhante.
Compare trace junto com p95, p99, throughput, CPU, memória e erros.
Exemplo de bloqueio
function parseLargePayload(text) {
const data = JSON.parse(text);
return data.items.sort((a, b) => a.score - b.score);
}Com payload grande, parsing e ordenação podem formar um bloco longo na thread principal. O trace localiza a janela; CPU profile aponta as funções; a correção pode usar limites, paginação, worker ou processamento prévio.
Exemplo de alocação
function duplicate(items) {
return items.map((item) => ({
...item,
values: [...item.values],
}));
}Chamadas repetidas criam muitos objetos temporários. A timeline pode mostrar mais eventos de GC. Heap profiler ajuda a quantificar as fontes de alocação.
Automação de diagnóstico
Crie um script que registra commit, cenário e parâmetros:
mkdir -p diagnostics/${GIT_SHA:-local}
node \
--trace-events-enabled \
--trace-event-categories node,v8 \
--trace-event-file-pattern="diagnostics/${GIT_SHA:-local}/trace-${PID}.json" \
dist/server.jsUse nomes suportados pela opção real; variáveis do shell e marcadores do Node não são a mesma coisa.
Erros comuns
- ativar todas as categorias por muito tempo;
- capturar sem reproduzir o problema;
- analisar sem métricas do mesmo intervalo;
- confundir trace com tracing distribuído;
- publicar arquivo sensível;
- deixar trace em disco efêmero;
- comparar ambientes diferentes;
- ignorar overhead;
- não registrar versão e PID.
Fluxo recomendado
- defina a hipótese;
- selecione categorias mínimas;
- aqueça a aplicação;
- capture durante carga representativa;
- correlacione com métricas;
- localize a janela;
- aprofunde com CPU ou heap profiler;
- faça uma alteração;
- repita a medição.
Combine Trace Events com CPU Profiling, Flamegraphs, Event Loop Utilization, Process Reports e Heap Snapshots.
Consulte a documentação oficial de Trace Events e a referência oficial das opções de tracing.



