Prometheus Client for Node.js
Prometheus client for Node.js (`prom-client`) is a comprehensive toolkit for instrumenting Node.js applications with Prometheus metrics. It supports all standard Prometheus metric types including counters, gauges, histograms, and summaries, alongside OpenMetrics and Exemplars which were introduced in version 15.0.0. The package is currently stable at version 15.1.3, with a release cadence that sees frequent patch and minor updates addressing bugs and adding features, while major versions are released less often to accommodate significant changes like Node.js version support adjustments and new Prometheus protocol features. Key differentiators include its robust support for Node.js `cluster` module aggregation, providing sensible defaults for common metrics, and a rich set of built-in 'default metrics' for runtime performance and resource usage. It ships with TypeScript types, enabling strong typing for metric definitions and interactions.
Common errors
-
Error: A metric with the name 'my_metric_name' has already been registered.
cause Attempting to register a metric with a name that is already in use by another metric within the same registry.fixEnsure each metric has a unique name within a given `Registry` instance. If you intend to use a single global metric, define it once and reuse the instance. If using multiple registries, ensure the metric is only registered to its intended registry. -
TypeError: Cannot read properties of undefined (reading 'inc')
cause Attempting to interact with a metric (e.g., `inc()`, `set()`) before it has been properly initialized or if the variable holding the metric instance is `undefined`.fixVerify that the metric object is correctly instantiated and assigned before any operations are performed on it. This often happens if a metric is defined conditionally or in a scope where it's not accessible. -
Error: Labels are not unique.
cause When defining a metric with `labelNames`, providing duplicate names in the array.fixReview the `labelNames` array provided in the metric constructor and remove any duplicate label names. Each label name must be unique. -
Error: Missing label 'method' on metric 'my_app_http_requests_total'
cause When observing a metric (e.g., `inc()`, `set()`), required labels defined in `labelNames` were omitted or misspelled.fixEnsure all labels specified in the `labelNames` array during metric definition are provided when observing the metric, with exact matching keys. For example, if `labelNames: ['method']` then call `inc({ method: 'GET' })`.
Warnings
- breaking Version 15.0.0 dropped support for Node.js versions 10, 12, 14, 17, and 19. Applications on these older Node.js versions must upgrade their Node.js runtime or stay on a `prom-client` version below 15.0.0.
- gotcha When using Node.js's `cluster` module, individual worker metrics will not provide a complete view. Metrics need to be aggregated from all workers in the master process to get accurate global metrics. Custom metrics require configuring the `aggregator` property for correct aggregation.
- gotcha Some default metrics, specifically those concerning File Descriptors and Memory details, are only available on Linux operating systems. On other platforms (e.g., macOS, Windows), these metrics will not be collected or exposed.
- gotcha Incorrectly formatted or non-unique labels can lead to errors during metric creation or observation. Labels must adhere to Prometheus naming conventions, and each unique combination of labels for a given metric should ideally represent a distinct series.
- breaking Version 15.0.0 introduced support for OpenMetrics and Exemplars. While this adds powerful new capabilities, consuming Prometheus servers or scrapers must be compatible with OpenMetrics format if these features are used. The `contentType` constant was also adjusted for these formats in v15.1.2.
Install
-
npm install prom-client -
yarn add prom-client -
pnpm add prom-client
Imports
- Registry
const Registry = require('prom-client').Registry;import { Registry } from 'prom-client'; - collectDefaultMetrics
import collectDefaultMetrics from 'prom-client';
import { collectDefaultMetrics } from 'prom-client'; - Counter
const Counter = require('prom-client').Counter;import { Counter } from 'prom-client';
Quickstart
import express from 'express';
import { collectDefaultMetrics, Registry, Counter } from 'prom-client';
const app = express();
const port = process.env.PORT || 3000;
// Create a new registry to register custom metrics
const register = new Registry();
// Collect default metrics like CPU, memory, event loop lag, etc.
// These are registered to the custom 'register' instance.
collectDefaultMetrics({
register: register,
prefix: 'my_app_',
labels: { APP_NAME: 'my_service' }
});
// Create a custom counter metric
const httpRequestCounter = new Counter({
name: 'my_app_http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status'],
registers: [register]
});
// Example route to increment the counter
app.get('/', (req, res) => {
httpRequestCounter.inc({ method: 'GET', route: '/', status: 200 });
res.send('Hello World!');
});
// Expose metrics at the /metrics endpoint
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
console.log(`Metrics available at http://localhost:${port}/metrics`);
});