Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Métricas Prometheus no Node.js

Atualizado em: 23 de agosto de 2026

Rack de servidores processando fluxos de dados no Node.js

Implementar métricas Prometheus no Node.js permite acompanhar volume, erros, latência, memória, event loop e comportamento de dependências. Diferentemente de logs, métricas agregam eventos em séries temporais e ajudam a identificar tendências, comparar versões e criar alertas.

O Prometheus normalmente coleta dados por pull em um endpoint HTTP. A aplicação expõe métricas no formato de texto, e o servidor Prometheus consulta esse endpoint periodicamente. O desenho das métricas é tão importante quanto a instrumentação: nomes, tipos e labels incorretos podem gerar cardinalidade alta e custo excessivo.

Neste guia, você aprenderá a usar Counter, Gauge, Histogram e Summary, expor o endpoint, medir HTTP, event loop e dependências, controlar labels, integrar com Kubernetes, criar alertas e testar.

O que é Prometheus?

Prometheus é um sistema de monitoramento e banco de séries temporais. A documentação oficial do Prometheus explica arquitetura e modelo de dados. A documentação de boas práticas para nomes apresenta convenções.

Para traces distribuídos, consulte OpenTelemetry no Node.js. Para medições internas, veja Performance Hooks no Node.js.

Biblioteca prom-client

npm install prom-client

O pacote prom-client fornece tipos de métrica e serialização compatível.

Registry

const client = require('prom-client');

const registry = new client.Registry();

registry.setDefaultLabels({
  service: 'orders-api',
  environment: process.env.NODE_ENV || 'development'
});

Default labels devem ter poucos valores possíveis. Não inclua hostname se o Prometheus já adiciona instância no scrape.

Métricas padrão

client.collectDefaultMetrics({
  register: registry,
  prefix: 'my_api_'
});

As métricas padrão podem incluir processo, heap, garbage collection e event loop, dependendo da versão.

Endpoint /metrics

app.get('/metrics', async (req, res) => {
  res.setHeader('content-type', registry.contentType);
  res.end(await registry.metrics());
});

O endpoint deve ser acessível ao coletor, mas não necessariamente à internet.

Protegendo o endpoint

Use rede privada, NetworkPolicy, autenticação no proxy ou ServiceMonitor restrito. Métricas podem revelar nomes de rotas, versões, filas e volume de negócio.

Counter

Counter só aumenta, exceto quando o processo reinicia:

const ordersCreated = new client.Counter({
  name: 'orders_created_total',
  help: 'Total de pedidos criados',
  labelNames: ['channel'],
  registers: [registry]
});

ordersCreated.inc({ channel: 'web' });

Use sufixo _total para contadores.

Taxa de Counter

No PromQL:

rate(orders_created_total[5m])

O cálculo considera resets do processo.

Gauge

Gauge aumenta e diminui:

const queueSize = new client.Gauge({
  name: 'jobs_queue_size',
  help: 'Quantidade atual de jobs na fila',
  registers: [registry]
});

queueSize.set(42);

É adequado para conexões, fila, uso momentâneo e estado atual.

Gauge com collect

const activeSessions = new client.Gauge({
  name: 'active_sessions',
  help: 'Sessões ativas',
  registers: [registry],
  async collect() {
    this.set(await repository.countActiveSessions());
  }
});

O método executa durante scrape. Não faça consultas caras ou sem timeout, pois atrasará o endpoint inteiro.

Histogram

const httpDuration = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duração das requisições HTTP',
  labelNames: ['method', 'route', 'status_code'],
  buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2, 5],
  registers: [registry]
});

Histogram mantém contagem por buckets, soma e total.

Medindo duração

const end = httpDuration.startTimer({
  method: req.method
});

res.on('finish', () => {
  end({
    route: req.route?.path || 'unknown',
    status_code: String(res.statusCode)
  });
});

Use rota normalizada, não URL com IDs.

Percentis com Histogram

histogram_quantile(
  0.95,
  sum by (le, route) (
    rate(http_request_duration_seconds_bucket[5m])
  )
)

Percentis são estimados a partir dos buckets.

Escolhendo buckets

Buckets precisam representar SLO e distribuição real. Para API com objetivo de 300 ms, inclua limites próximos a 0.1, 0.25, 0.3, 0.5 e 1 segundo.

Summary

const operationDuration = new client.Summary({
  name: 'operation_duration_seconds',
  help: 'Duração de operações',
  percentiles: [0.5, 0.9, 0.99],
  registers: [registry]
});

Summary calcula quantis no processo, mas não agrega bem entre instâncias. Histogram costuma ser melhor para serviços distribuídos.

Unidades

Use unidades base nos nomes:

  • _seconds para tempo;
  • _bytes para tamanho;
  • _total para contadores;
  • razão entre 0 e 1 para percentuais quando adequado.

Cardinalidade

Cada combinação de labels cria uma série. Nunca use:

  • requestId;
  • userId;
  • orderId;
  • URL completa;
  • mensagem de erro;
  • timestamp;
  • token.

Milhões de valores tornam Prometheus caro ou instável.

Rota normalizada

Use:

/api/users/:id

Não use:

/api/users/48291

Status code

Status possui cardinalidade limitada. Algumas equipes preferem classe:

status_class="2xx"

Manter código exato ainda costuma ser aceitável.

Erros

const errors = new client.Counter({
  name: 'application_errors_total',
  help: 'Erros da aplicação',
  labelNames: ['type', 'operation'],
  registers: [registry]
});

type deve ser uma categoria controlada, não error.message.

Métricas RED

Para serviços, monitore:

  • Rate: requisições por segundo;
  • Errors: taxa de falha;
  • Duration: latência.

Métricas USE

Para recursos:

  • Utilization;
  • Saturation;
  • Errors.

CPU, event loop e pool de conexões podem seguir essa análise.

Event loop delay

Métricas padrão podem expor atraso. Também é possível usar monitorEventLoopDelay(). Consulte Event Loop no Node.js.

Event loop utilization

Uma Gauge pode registrar utilização calculada em intervalo. Não confunda utilização alta com erro; correlacione com latência e CPU.

Memória

Observe RSS, heap usado, heap total e memória externa. Um heap estável com RSS crescente pode indicar buffers ou addon nativo.

Garbage collection

Duração e quantidade de GC ajudam a explicar pausas. Consulte Módulo V8 no Node.js.

Pool PostgreSQL

const poolTotal = new client.Gauge({
  name: 'postgres_pool_total_connections',
  help: 'Conexões totais do pool',
  registers: [registry]
});

const poolIdle = new client.Gauge({
  name: 'postgres_pool_idle_connections',
  help: 'Conexões ociosas',
  registers: [registry]
});

Atualize com propriedades do driver. Consulte Pool PostgreSQL no Node.js.

Fila

Monitore tamanho atual, idade do job mais antigo, taxa de processamento, falhas e retries. A idade costuma ser mais útil que apenas quantidade.

Dependências HTTP

Use histogram de duração e counter por serviço, método e resultado. Não coloque hostname arbitrário de URL fornecida pelo usuário.

Retries

Counter de retries por operação ajuda a descobrir dependência instável. Veja Retry com Backoff no Node.js.

Cache

Monitore hits, misses, evictions e duração. Calcule hit ratio no PromQL, não mantenha um Gauge manual que pode divergir.

Multiprocessos

Cada processo expõe métricas próprias. Em Cluster ou PM2, use estratégia suportada pela biblioteca ou faça scrape de cada instância. Não some gauges incorretamente.

Consulte Cluster no Node.js.

Kubernetes

Um ServiceMonitor ou PodMonitor pode descobrir pods. Cada pod deve expor o endpoint e receber labels de ambiente e aplicação pelo Prometheus, não pela própria métrica quando possível.

Probes não são métricas

Readiness informa se recebe tráfego; métricas explicam desempenho. Consulte Probes Kubernetes em Node.js.

Scrape interval

Intervalos menores detectam rápido e aumentam volume. Quinze ou trinta segundos são comuns, mas dependem de SLO e custo.

Timeout do scrape

O endpoint deve responder rapidamente. Não faça chamadas a todas as dependências durante a coleta.

Exemplars

Exemplars podem associar um traceId a uma observação de histogram, permitindo saltar de uma latência alta para um trace. Verifique suporte da biblioteca e plataforma.

OpenTelemetry

OpenTelemetry pode produzir métricas e exportá-las para Prometheus. Evite instrumentar a mesma operação duas vezes.

Alertas

Alertas devem representar impacto:

  • taxa de erro acima do SLO;
  • latência p95 elevada;
  • fila envelhecendo;
  • pool saturado;
  • memória próxima do limite;
  • ausência de scrape.

Não alerte em cada métrica

CPU alta sem impacto pode ser uso eficiente. Combine sinais e use duração para evitar alertas por picos breves.

Recording rules

Consultas PromQL complexas e frequentes podem ser pré-calculadas. Isso melhora dashboards e alertas.

Dashboards

Um painel útil inclui tráfego, erros, latência, saturação e versões implantadas. Evite centenas de gráficos sem pergunta operacional.

Segurança

O endpoint não deve revelar dados pessoais. Nomes e help strings também são públicos para quem acessa a rota.

Logs e métricas

Métrica alerta que algo mudou; log fornece detalhes. Consulte Logs com Pino no Node.js.

Testes

Cubra:

  • endpoint e Content-Type;
  • counter incrementado;
  • gauge atualizado;
  • histogram observado;
  • rota normalizada;
  • status code;
  • ausência de IDs em labels;
  • falha de collect;
  • múltiplos registries;
  • reset entre testes.

Registry por teste

function createMetrics() {
  const registry = new client.Registry();
  const counter = new client.Counter({
    name: 'test_operations_total',
    help: 'Operações de teste',
    registers: [registry]
  });

  return { registry, counter };
}

Evite métricas duplicadas no registry global.

Erros comuns

  • User ID como label: cardinalidade explode.
  • URL completa: cada recurso cria série.
  • Summary em várias réplicas: quantis não agregam.
  • Buckets genéricos: percentis ficam pouco úteis.
  • Consulta cara no collect: scrape expira.
  • Endpoint público: arquitetura é exposta.
  • Gauge para contador: resets e taxas ficam incorretos.

Boas práticas

  • Use nomes e unidades padronizados.
  • Escolha o tipo correto.
  • Controle labels.
  • Normalize rotas.
  • Prefira Histogram para latência.
  • Defina buckets pelo SLO.
  • Mantenha /metrics rápido.
  • Restrinja acesso.
  • Crie alertas de impacto.
  • Teste cardinalidade.

Conclusão

Implementar métricas Prometheus no Node.js torna tráfego, erros, latência e saturação observáveis. Counter, Gauge e Histogram cobrem a maioria dos casos quando usados com unidades e labels controlados.

O maior risco é cardinalidade. Rotas normalizadas, categorias limitadas e ausência de IDs mantêm o sistema sustentável. Com endpoint protegido, buckets alinhados ao SLO e alertas baseados em impacto, Prometheus ajuda a detectar problemas antes que se tornem indisponibilidade.

Os 10 Melhores Cursos de Programação de 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita