Observabilidade com OpenTelemetry em Node.js: Guia Prático

Observabilidade com OpenTelemetry em Node.js: Guia Prático

# Observabilidade com OpenTelemetry em Node.js: Guia Prático...

5 min de leitura
🔒 Faça login para curtir

Autor

Luis Henrique Cuba

Luis Henrique Cuba

Autor no blog LHCX.

Gostou do conteúdo?

🔒 Faça login para curtir

Sua curtida nos ajuda a melhorar

Observabilidade com OpenTelemetry em Node.js: Guia Prático

Tecnologia e Inovação

Introdução

A observabilidade se tornou um requisito indispensável para aplicações modernas, sobretudo em ambientes de microserviços e cloud‑native. Ela permite que equipes de desenvolvimento e operação entendam o comportamento interno de um sistema, detectem anomalias e melhorem a experiência do usuário.

Neste post vamos implementar observabilidade completa (traces, métricas e logs) em uma aplicação Node.js usando OpenTelemetry, exportando dados para Jaeger e Prometheus. Você aprenderá a configurar o SDK, instrumentar código e visualizar resultados em ferramentas populares.


1. Por que Observabilidade é essencial?

  • Detecção precoce de falhas antes que impactem usuários.
  • Diagnóstico rápido: correlacione métricas, logs e traces.
  • Otimização de performance: identifique gargalos de latência.
  • Conformidade: auditorias e compliance são facilitadas com dados estruturados.

2. Conceitos básicos do OpenTelemetry

ConceitoDescrição
TracerCria spans que representam unidades de trabalho (ex.: requisição HTTP).
MeterColeta métricas (counters, gauges, histograms).
ExporterEnvia dados para back‑ends como Jaeger, Zipkin ou Prometheus.
Instrumentation LibraryPacotes que já vêm com instrumentação pronta (ex.: @opentelemetry/instrumentation-express).

3. Configurando o ambiente

3.1 Requisitos

  • Node.js >= 14
  • Docker (para Jaeger e Prometheus)
  • npm ou yarn

3.2 Instalando dependências

bash npm init -y npm install express @opentelemetry/api @opentelemetry/sdk-node
@opentelemetry/auto-instrumentations-node @opentelemetry/exporter-jaeger
@opentelemetry/exporter-prometheus

3.3 Subindo Jaeger e Prometheus com Docker Compose

Crie um arquivo docker-compose.yml: yaml version: "3" services: jaeger: image: jaegertracing/all-in-one:1.53 ports: - "16686:16686" # UI - "6831:6831/udp" # UDP for Thrift prometheus: image: prom/prometheus:latest volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml ports: - "9090:9090"

E um prometheus.yml mínimo: yaml global: scrape_interval: 15s scrape_configs:

  • job_name: 'nodejs' static_configs:
    • targets: ['host.docker.internal:9464']

Inicie os containers: bash docker-compose up -d

Desenvolvimento e Código

4. Instrumentando a aplicação Node.js

4.1 Estrutura do projeto

my-app/ ├─ src/ │ └─ server.js ├─ otel-setup.js ├─ package.json └─ docker-compose.yml

4.2 Configuração do OpenTelemetry (otel-setup.js)

javascript // otel-setup.js const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { JaegerExporter } = require('@opentelemetry/exporter-jaeger'); const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express'); const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');

// ---------- Tracing ---------- const tracerProvider = new NodeTracerProvider(); const jaegerExporter = new JaegerExporter({ endpoint: 'http://localhost:14268/api/traces', // Jaeger HTTP collector }); tracerProvider.addSpanProcessor(new SimpleSpanProcessor(jaegerExporter)); tracerProvider.register();

// ---------- Metrics ---------- const prometheusExporter = new PrometheusExporter({ port: 9464, endpoint: '/metrics', }); const metricReader = new PeriodicExportingMetricReader({ exporter: prometheusExporter, exportIntervalMillis: 5000, }); const meterProvider = new MeterProvider(); meterProvider.addMetricReader(metricReader); meterProvider.register();

// ---------- Auto‑instrumentation ---------- registerInstrumentations({ instrumentations: [ new HttpInstrumentation(), new ExpressInstrumentation(), ], });

console.log('OpenTelemetry configurado: Jaeger (traces) e Prometheus (metrics)');

4.3 Servidor Express (src/server.js)

javascript // src/server.js require('../otel-setup'); // Must be imported before any other module const express = require('express'); const { Counter } = require('@opentelemetry/api').metrics;

const app = express(); const port = process.env.PORT || 3000;

// Métrica customizada: contagem de requisições HTTP const meter = require('@opentelemetry/api').metrics.getMeter('my-app-meter'); const requestCounter = meter.createCounter('http_requests_total', { description: 'Contagem total de requisições HTTP', });

app.use(express.json());

app.get('/health', (req, res) => { requestCounter.add(1, { route: '/health', method: 'GET' }); res.json({ status: 'ok' }); });

app.get('/compute/:n', (req, res) => { const n = parseInt(req.params.n, 10); requestCounter.add(1, { route: '/compute/:n', method: 'GET' }); const fib = fibonacci(n); res.json({ n, fib }); });

function fibonacci(num) { if (num <= 1) return num; return fibonacci(num - 1) + fibonacci(num - 2); }

app.listen(port, () => { console.log(Servidor rodando na porta ${port}); });

Importante: otel-setup.js deve ser carregado antes de qualquer outro módulo para garantir que a instrumentação automática capture todas as chamadas.

5. Exportando e visualizando dados

5.1 Jaeger (Traces)

Acesse a UI do Jaeger em http://localhost:16686. Procure pelo serviço my-app e explore os spans gerados pelas rotas /health e /compute/:n. Você verá a hierarquia de chamadas, tempos de execução e atributos customizados.

5.2 Prometheus (Métricas)

A UI do Prometheus fica em http://localhost:9090. Use a query:

http_requests_total{route="/compute/:n"}

para observar o contador de requisições. O exporter do OpenTelemetry já expõe a métrica em http://localhost:9464/metrics.

Tecnologia e Programação

6. Boas práticas e próximos passos

  • Context Propagation: assegure que contextos de trace sejam propagados em chamadas assíncronas (promises, callbacks).
  • Sampling: ajuste políticas de sampling para evitar sobrecarga em produção.
  • Custom Attributes: adicione atributos relevantes (userId, tenantId) aos spans para enriquecer a análise.
  • Alertas: configure alertas no Prometheus (ou Grafana) para métricas críticas como latência > 500 ms.
  • Exporters adicionais: OpenTelemetry suporta Zipkin, OTLP, Elastic APM, entre outros.

Conclusão

Implementar observabilidade com OpenTelemetry em Node.js não requer esforço excessivo e traz ganhos imediatos de visibilidade. Ao combinar traces (Jaeger) e métricas (Prometheus) você obtém um panorama completo do comportamento da aplicação, facilitando diagnóstico, otimização e escalabilidade.

Próximos passos recomendados:

  1. Integrar logs estruturados com OpenTelemetry Logging.
  2. Automatizar a coleta de métricas de recursos (CPU, memória) usando o collector oficial.
  3. Avaliar estratégias de sampling avançado para ambientes de alta taxa de requisição.

Com esses fundamentos, sua equipe está pronta para adotar práticas de observabilidade que sustentam sistemas resilientes e de alto desempenho.

Carregando comentários...