JavaScript Avançado

Monitoramento de Apps Node.js em Produção: OpenTelemetry e Sentry: Do Básico ao Avançado

7 min de leitura

Monitoramento de Apps Node.js em Produção: OpenTelemetry e Sentry: Do Básico ao Avançado

Introdução: Por que monitorar Node.js em produção? Aplicações Node.js em produção enfrentam desafios reais: latência inesperada, erros silenciosos, picos de memória e degradação de performance. Sem visibilidade adequada, você só descobre problemas quando seus usuários reclamam. OpenTelemetry e Sentry resolvem isso fornecendo observabilidade completa — rastreamento distribuído, métricas em tempo real e captura de exceções. OpenTelemetry é um padrão open-source para instrumentação, enquanto Sentry é uma plataforma de error tracking que complementa perfeitamente. Juntas, essas ferramentas criam uma rede de segurança que identifica problemas antes que se tornem críticos. OpenTelemetry: Instrumentação Completa Instalação e Setup Básico Comece instalando os pacotes essenciais: Crie um arquivo que deve ser importado antes de qualquer outra dependência: No seu ou , importe este arquivo primeira coisa: Métricas e Spans Customizados Além da instrumentação automática, você pode criar spans customizados para lógica de negócio: Sentry: Captura Inteligente de Erros Configuração e Integração Sentry detecta erros não tratados, exceções e problemas de performance. Instale: Configure no

<h2>Introdução: Por que monitorar Node.js em produção?</h2>

<p>Aplicações Node.js em produção enfrentam desafios reais: latência inesperada, erros silenciosos, picos de memória e degradação de performance. Sem visibilidade adequada, você só descobre problemas quando seus usuários reclamam. OpenTelemetry e Sentry resolvem isso fornecendo observabilidade completa — rastreamento distribuído, métricas em tempo real e captura de exceções.</p>

<p>OpenTelemetry é um padrão open-source para instrumentação, enquanto Sentry é uma plataforma de error tracking que complementa perfeitamente. Juntas, essas ferramentas criam uma rede de segurança que identifica problemas antes que se tornem críticos.</p>

<h2>OpenTelemetry: Instrumentação Completa</h2>

<h3>Instalação e Setup Básico</h3>

<p>Comece instalando os pacotes essenciais:</p>

<pre><code class="language-bash">npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto \

@opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-http \

@opentelemetry/resources @opentelemetry/semantic-conventions</code></pre>

<p>Crie um arquivo <code>tracing.js</code> que deve ser importado <strong>antes</strong> de qualquer outra dependência:</p>

<pre><code class="language-javascript">const { NodeSDK } = require(&#039;@opentelemetry/sdk-node&#039;);

const { getNodeAutoInstrumentations } = require(&#039;@opentelemetry/auto-instrumentations-node&#039;);

const { OTLPTraceExporter } = require(&#039;@opentelemetry/exporter-trace-otlp-http&#039;);

const { Resource } = require(&#039;@opentelemetry/resources&#039;);

const { SemanticResourceAttributes } = require(&#039;@opentelemetry/semantic-conventions&#039;);

const traceExporter = new OTLPTraceExporter({

url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || &#039;http://localhost:4318/v1/traces&#039;,

});

const sdk = new NodeSDK({

resource: new Resource({

[SemanticResourceAttributes.SERVICE_NAME]: &#039;meu-app-nodejs&#039;,

[SemanticResourceAttributes.SERVICE_VERSION]: &#039;1.0.0&#039;,

}),

traceExporter,

instrumentations: [getNodeAutoInstrumentations()],

});

sdk.start();

console.log(&#039;OpenTelemetry iniciado&#039;);

process.on(&#039;SIGTERM&#039;, () =&gt; {

sdk.shutdown()

.then(() =&gt; console.log(&#039;Tracing finalizado&#039;))

.catch((log) =&gt; console.log(&#039;Erro ao finalizar tracing&#039;, log))

.finally(() =&gt; process.exit(0));

});</code></pre>

<p>No seu <code>index.js</code> ou <code>app.js</code>, importe este arquivo <strong>primeira coisa</strong>:</p>

<pre><code class="language-javascript">require(&#039;./tracing&#039;);

const express = require(&#039;express&#039;);

const app = express();

app.get(&#039;/api/users/:id&#039;, (req, res) =&gt; {

const userId = req.params.id;

// Simulando busca em BD

res.json({ id: userId, name: &#039;João&#039; });

});

app.listen(3000, () =&gt; console.log(&#039;Servidor rodando na porta 3000&#039;));</code></pre>

<h3>Métricas e Spans Customizados</h3>

<p>Além da instrumentação automática, você pode criar spans customizados para lógica de negócio:</p>

<pre><code class="language-javascript">const { trace } = require(&#039;@opentelemetry/api&#039;);

const tracer = trace.getTracer(&#039;meu-app-tracer&#039;, &#039;1.0.0&#039;);

async function processarPagamento(pedidoId) {

const span = tracer.startSpan(&#039;processarPagamento&#039;);

try {

span.setAttribute(&#039;pedido.id&#039;, pedidoId);

// Span filho para validação

const validSpan = tracer.startSpan(&#039;validarPagamento&#039;, { parent: span });

await validarPagamento(pedidoId);

validSpan.end();

// Span filho para processamento

const procSpan = tracer.startSpan(&#039;enviarGateway&#039;, { parent: span });

const resultado = await enviarParaGateway(pedidoId);

procSpan.setAttribute(&#039;resultado.status&#039;, resultado.status);

procSpan.end();

span.setStatus({ code: 0 }); // OK

return resultado;

} catch (erro) {

span.recordException(erro);

span.setStatus({ code: 2 }); // ERROR

throw erro;

} finally {

span.end();

}

}</code></pre>

<h2>Sentry: Captura Inteligente de Erros</h2>

<h3>Configuração e Integração</h3>

<p>Sentry detecta erros não tratados, exceções e problemas de performance. Instale:</p>

<pre><code class="language-bash">npm install @sentry/node @sentry/tracing</code></pre>

<p>Configure no início da sua aplicação (depois do OpenTelemetry):</p>

<pre><code class="language-javascript">require(&#039;./tracing&#039;); // OpenTelemetry primeiro

const Sentry = require(&#039;@sentry/node&#039;);

const { nodeProfilingIntegration } = require(&#039;@sentry/profiling-node&#039;);

const express = require(&#039;express&#039;);

const app = express();

Sentry.init({

dsn: process.env.SENTRY_DSN,

environment: process.env.NODE_ENV || &#039;development&#039;,

tracesSampleRate: 1.0,

profilesSampleRate: 0.1, // 10% para profiling

integrations: [

new Sentry.Integrations.Http({ tracing: true }),

new Sentry.Integrations.Express({ app }),

nodeProfilingIntegration(),

],

});

// Middleware ANTES das rotas

app.use(Sentry.Handlers.requestHandler());

app.use(Sentry.Handlers.tracingHandler());

// Suas rotas aqui

app.get(&#039;/api/dados&#039;, (req, res) =&gt; {

res.json({ ok: true });

});

// Middleware de erro DEPOIS das rotas

app.use(Sentry.Handlers.errorHandler());

app.listen(3000);</code></pre>

<h3>Captura Manual e Contexto</h3>

<p>Para eventos específicos, capture manualmente com contexto:</p>

<pre><code class="language-javascript">app.post(&#039;/api/transferencia&#039;, async (req, res) =&gt; {

const { origem, destino, valor } = req.body;

Sentry.setContext(&#039;transferencia&#039;, {

origem,

destino,

valor,

timestamp: new Date().toISOString(),

});

try {

const resultado = await executarTransferencia(origem, destino, valor);

res.json(resultado);

} catch (erro) {

// Capture com level apropriado

Sentry.captureException(erro, {

level: &#039;error&#039;,

tags: {

operacao: &#039;transferencia&#039;,

severidade: valor &gt; 10000 ? &#039;alto&#039; : &#039;normal&#039;,

},

});

res.status(500).json({ erro: &#039;Falha na transferência&#039; });

}

});</code></pre>

<h2>Integração OpenTelemetry + Sentry</h2>

<p>OpenTelemetry e Sentry trabalham juntos. Adicione o Sentry como exportador de traces:</p>

<pre><code class="language-bash">npm install @sentry/opentelemetry-node</code></pre>

<pre><code class="language-javascript">require(&#039;./tracing&#039;);

const Sentry = require(&#039;@sentry/node&#039;);

const { SentryPropagator, SentrySpanProcessor } = require(&#039;@sentry/opentelemetry-node&#039;);

Sentry.init({

dsn: process.env.SENTRY_DSN,

integrations: [

new Sentry.Integrations.Http({ tracing: true }),

new SentrySpanProcessor(), // Sincroniza spans com Sentry

],

});</code></pre>

<p>Agora todos os spans do OpenTelemetry aparecem como transactions no Sentry, criando uma visão unificada de performance e erros.</p>

<h2>Boas Práticas e Alerts</h2>

<p>Configure alertas no Sentry para problemas críticos: aumente de taxa de erro acima de 5%, latência P95 acima de 1 segundo, ou memory usage crescente. Use tags e contexto consistentemente para facilitar investigação.</p>

<p>No código, sempre adicione informação do usuário aos erros: <code>Sentry.setUser({ id, email })</code>. Isso ajuda a correlacionar problemas com experiências reais.</p>

<p>Exporte métricas do OpenTelemetry para Grafana ou Datadog para visualizar tendências. Configure sampling inteligente: 100% para erros, 10-20% para traces normais, reduzindo custos sem perder visibilidade.</p>

<h2>Conclusão</h2>

<p>Monitorar Node.js em produção não é opcional — é essencial. <strong>OpenTelemetry fornece observabilidade estruturada</strong> com traces distribuídos que rastreiam requisições através de múltiplos serviços. <strong>Sentry complementa com captura de erros inteligente, análise de performance e alertas proativos</strong>. Juntas, essas ferramentas transformam você de reativo (esperando reclamações) para proativo (identificando problemas antes do impacto). Comece instrumentando sua app hoje: seu futuro eu agradecerá quando rastrear um bug complexo em 5 minutos em vez de 5 horas.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://opentelemetry.io/docs/instrumentation/js/" target="_blank" rel="noopener noreferrer">OpenTelemetry Official Documentation</a></li>

<li><a href="https://docs.sentry.io/platforms/javascript/guides/node/" target="_blank" rel="noopener noreferrer">Sentry Node.js SDK</a></li>

<li><a href="https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/auto-instrumentations-node" target="_blank" rel="noopener noreferrer">OpenTelemetry Node Auto-Instrumentation</a></li>

<li><a href="https://docs.sentry.io/product/integrations/opentelemetry/" target="_blank" rel="noopener noreferrer">Sentry OpenTelemetry Integration</a></li>

<li><a href="https://www.cncf.io/blog/2021/05/18/distributed-tracing-overview/" target="_blank" rel="noopener noreferrer">Distributed Tracing Best Practices - Cloud Native Computing Foundation</a></li>

</ul>

Comentários

Mais em JavaScript Avançado

NestJS com TypeScript: Arquitetura Modular, DI e Guards na Prática
NestJS com TypeScript: Arquitetura Modular, DI e Guards na Prática

Arquitetura Modular no NestJS O NestJS foi construído com a modularidade como...

Design Patterns em JavaScript: Strategy, Decorator e Composite: Do Básico ao Avançado
Design Patterns em JavaScript: Strategy, Decorator e Composite: Do Básico ao Avançado

Strategy Pattern: Flexibilidade no Comportamento O Strategy Pattern encapsula...

Metaprogramação Avançada: Symbols, Well-Known Symbols e Iteração Customizada: Do Básico ao Avançado
Metaprogramação Avançada: Symbols, Well-Known Symbols e Iteração Customizada: Do Básico ao Avançado

Symbols em JavaScript: A Base da Metaprogramação Symbols são um tipo primitiv...