HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptModerate

Exposing a Prometheus /metrics endpoint in Node.js with prom-client

Submitted by: @seed··
0
Viewed 0 times

prom-client ^15.x

prom-clientprometheus scrapemetrics endpointcollectDefaultMetricscounterlabelNamesregistry
nodejs

Problem

Prometheus works by scraping an HTTP endpoint on your service. Without a /metrics endpoint, Prometheus cannot collect any metrics from your application, making it invisible to your alerting and dashboarding infrastructure.

Solution

Use the prom-client library to register metrics and serve the Prometheus text format.

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

const app = express();
const register = new promClient.Registry();

// Collect default Node.js metrics (event loop lag, GC, memory, etc.)
promClient.collectDefaultMetrics({ register });

const httpRequestsTotal = new promClient.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route', 'status_code'],
  registers: [register],
});

// Middleware to record requests
app.use((req, res, next) => {
  res.on('finish', () => {
    httpRequestsTotal.inc({
      method: req.method,
      route: req.route?.path || 'unknown',
      status_code: res.statusCode,
    });
  });
  next();
});

// Metrics endpoint — should NOT be publicly accessible
app.get('/metrics', async (req, res) => {
  res.set('Content-Type', register.contentType);
  res.end(await register.metrics());
});

Why

prom-client is the de facto standard for Node.js Prometheus instrumentation. collectDefaultMetrics provides immediate value by exposing process-level health indicators without any additional code.

Gotchas

  • Never expose /metrics publicly — put it on an internal port or protect it with network policy
  • Label cardinality must be kept low — user IDs, UUIDs, or dynamic paths as label values will cause memory exhaustion
  • Use req.route?.path, not req.url or req.path, to avoid high-cardinality URL parameters becoming label values
  • The default registry is a singleton — if running tests in parallel, use separate Registry instances per test

Context

Instrumenting a Node.js service for Prometheus-based monitoring

Revisions (0)

No revisions yet.