patternjavascriptModerate
Exposing a Prometheus /metrics endpoint in Node.js with prom-client
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.