Prometheus Metrics for Express
express-prom-bundle is an Express.js middleware designed to integrate popular Prometheus metrics into an application with minimal configuration. It bundles essential metrics, notably `up` and `http_request_duration_seconds`, which can be configured as either a histogram or a summary and labeled with HTTP status codes, methods, and paths. The current stable version is 8.0.0, which requires Express.js v5 and `prom-client` v15 or higher. The library maintains a steady release cadence, incorporating dependabot updates and new features, with major versions typically aligning with peer dependency updates. A key differentiator is its focus on ease of use, providing a consolidated solution for common Express metric needs, as well as features like path normalization and custom label support. Its middleware order dependency allows for selective metric collection, and it explicitly supports both CommonJS and ESM environments, shipping with TypeScript type definitions.
Common errors
-
Error: Cannot find module 'prom-client'
cause The `prom-client` library is a peer dependency and must be installed explicitly alongside `express-prom-bundle`.fixRun `npm install prom-client` or `yarn add prom-client` in your project. -
TypeError: Router.use() requires a middleware function but got a Object
cause This error often indicates a mismatch between your Express.js version and the `express-prom-bundle` version, specifically using `express-prom-bundle` v8.x with `express` v4.x.fixUpgrade your `express` installation to `express@5` (e.g., `npm install express@5 @types/express@5`) or downgrade `express-prom-bundle` to a v7.x release. -
TypeError: promClient.collectDefaultMetrics is not a function (or similar prom-client API error)
cause This typically occurs when `express-prom-bundle` (especially v7+) is used with an incompatible, older version of `prom-client` (e.g., prior to v15.0.0).fixEnsure that your `prom-client` installation is version `15.0.0` or higher to match the peer dependency requirements of `express-prom-bundle` v7+. -
Metrics not appearing for some Express routes when accessing /metrics
cause The `express-prom-bundle` middleware was registered in Express's middleware chain *after* the routes it should be monitoring.fixEnsure that `app.use(metricsMiddleware)` is called *before* any of the `app.get()`, `app.post()`, or other route handlers that you intend to have metrics collected for.
Warnings
- breaking Version 8.0.0 of `express-prom-bundle` updates its peer dependency to `express@5`.
- breaking Version 7.0.0 of `express-prom-bundle` bumped its peer dependency for `prom-client` to `>=15.0.0`.
- gotcha The order of middleware registration is crucial: only routes registered *after* `express-prom-bundle`'s middleware will be measured.
- gotcha While the `metricsPath` option allows customization of the Prometheus metrics endpoint, it is highly recommended to stick to the default `/metrics` path.
Install
-
npm install express-prom-bundle -
yarn add express-prom-bundle -
pnpm add express-prom-bundle
Imports
- promBundle
const promBundle = require('express-prom-bundle');import promBundle from 'express-prom-bundle';
- register
const register = require('prom-client').register;import { register } from 'prom-client'; - PromBundleOptions
import { PromBundleOptions } from 'express-prom-bundle';import type { PromBundleOptions } from 'express-prom-bundle';
Quickstart
import express from 'express';
import promBundle from 'express-prom-bundle';
const app = express();
// Configure the metrics middleware
const metricsMiddleware = promBundle({
includeMethod: true,
includePath: true, // IMPORTANT: only measures routes registered AFTER this middleware
customLabels: { service_name: 'my-express-app' },
promClient: { collectDefaultMetrics: {} } // Collect default Node.js process metrics
});
// Register the metrics middleware BEFORE your routes
app.use(metricsMiddleware);
// Define your application routes
app.get('/', (req, res) => {
res.send('Hello, Prometheus!');
});
app.get('/api/users/:id', (req, res) => {
// Simulate an async operation
setTimeout(() => {
res.json({ id: req.params.id, name: `User ${req.params.id}` });
}, Math.random() * 200);
});
app.get('/error', (req, res) => {
res.status(500).send('Internal Server Error');
});
// The /metrics endpoint is automatically exposed by default
// Access it at http://localhost:3000/metrics
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Express app listening on port ${PORT}`);
console.log(`Metrics available at http://localhost:${PORT}/metrics`);
});