prom-client library: Monitoring Node.js applications with Prometheus
In modern web development, monitoring application performance and health has become a necessity. One of the most popular solutions for collecting and analyzing metrics is Prometheus — an open-source system that collects data in the form of time series. For integration with Node.js, there is an official library prom-client, which makes it easy to export metrics in a format understandable to Prometheus.
In this article, we will thoroughly examine how to install and use prom-client, what types of metrics are available, and how to integrate them with the Express web framework.
Installation and setup
First, install the library via npm:
npm install prom-clientAfter installation, import it into your application:
const prometheus = require('prom-client');const express = require('express');const app = express();Main metric types
The prom-client library supports four main Prometheus metric types:
- Counter — a counter that only increases (e.g., number of requests).
- Gauge — a value that can both increase and decrease (e.g., number of active connections).
- Histogram — a histogram measuring value distribution (e.g., response time).
- Summary — summary statistics, similar to Histogram, but with more precise quantiles.
Example: Counter (request counter)
Let's create a counter to track the total number of HTTP requests:
const httpRequestsTotal = new prometheus.Counter({ name: 'http_requests_total', help: 'Total number of HTTP requests', labelNames: ['method', 'route', 'status']});
// Middleware for counting requestsapp.use((req, res, next) => { res.on('finish', () => { httpRequestsTotal.inc({ method: req.method, route: req.path, status: res.statusCode }); }); next();});Example: Gauge (active connections)
Gauge is convenient for tracking current state, for example, the number of active users:
const activeUsers = new prometheus.Gauge({ name: 'active_users', help: 'Number of active users'});
app.get('/login', (req, res) => { activeUsers.inc(); // Increase on login res.send('Logged in');});
app.get('/logout', (req, res) => { activeUsers.dec(); // Decrease on logout res.send('Logged out');});Example: Histogram (response time)
Histogram allows you to measure how long request processing takes:
const httpRequestDuration = new prometheus.Histogram({ name: 'http_request_duration_seconds', help: 'Duration of HTTP requests in seconds', labelNames: ['method', 'route'], buckets: [0.1, 0.5, 1, 2, 5] // Bucket boundaries in seconds});
app.use((req, res, next) => { const end = httpRequestDuration.startTimer(); res.on('finish', () => { end({ method: req.method, route: req.path }); }); next();});Exporting metrics for Prometheus
For Prometheus to collect data, you need to create an endpoint (usually /metrics) that returns all registered metrics:
app.get('/metrics', async (req, res) => { res.set('Content-Type', prometheus.register.contentType); res.end(await prometheus.register.metrics());});
app.listen(3000, () => { console.log('Server running on port 3000');});Custom metrics with labels
You can add labels for more detailed filtering. For example, let's split metrics by API versions:
const apiCalls = new prometheus.Counter({