Add Prometheus metrics in Nodejs

Tohid haghighi
4 min readOct 15, 2023

Prometheus is an open-source technology designed to provide monitoring and alerting functionality for cloud-native environments, including Kubernetes. It can collect and store metrics as time-series data, recording information with a timestamp.

What is application monitoring and why is it necessary?

Application monitoring is a method that uses software tools to gain insights into your software deployments. This can be achieved by simple health checks to see if the server is available to more advanced setups where a monitoring library is integrated into your server that sends data to a dedicated monitoring service. It can even involve the client side of your application, offering more detailed insights into the user experience.

For every developer, monitoring should be a crucial part of the daily work, because you need to know how the software behaves in production. You can let your testers work with your system and try to mock interactions or high loads, but these techniques will never be the same as the real production workload.

What is Prometheus and how does it work?

Prometheus is an open-source monitoring system that was created in 2012 by Soundcloud. In 2016, Prometheus became the second project (following Kubernetes) to be hosted by the Cloud Native Computing Foundation.

Prometheus

The Prometheus server collects metrics from your servers and other monitoring targets by pulling their metric endpoints over HTTP at a predefined time interval. For ephemeral and batch jobs, for which metrics can’t be scraped periodically due to their short-lived nature, Prometheus offers a Push gateway. This is an intermediate server that monitoring targets can push their metrics to before exiting. The data is retained there until the Prometheus server pulls it later.

The core data structure of Prometheus is the time series, which is essentially a list of timestamped values that are grouped by metric.

With PromQL (Prometheus Query Language), Prometheus provides a functional query language allowing for the selection and aggregation of time series data in real-time. The result of a query can be viewed directly in the Prometheus web UI, or consumed by external systems such as Grafana via the HTTP API.

How to use prom-client to export metrics in Node.js for Prometheus?

prom-client is the most popular Prometheus client library for Node.js. It provides the building blocks to export metrics to Prometheus via the pull and push methods and supports all Prometheus metric types such as histograms, summaries, gauges, and counters.

Setup sample Node.js project

Create a new directory and setup the Node.js project:

$ mkdir example-nodejs-app
$ cd example-nodejs-app
$ npm init -y

Install prom-client

The prom-client npm module can be installed via:

$ npm install prom-client

Exposing default metrics

Every Prometheus client library comes with predefined default metrics that are assumed to be good for all applications on the specific runtime. The prom-client library also follows this convention. The default metrics are useful for monitoring the usage of resources such as memory and CPU.

You can capture and expose the default metrics with following code snippet:

const http = require('http')
const url = require('url')
const client = require('prom-client')
// Create a Registry which registers the metrics
const register = new client.Registry()
// Add a default label which is added to all metrics
register.setDefaultLabels({
app: 'example-nodejs-app'
})
// Enable the collection of default metrics
client.collectDefaultMetrics({ register })
// Define the HTTP server
const server = http.createServer(async (req, res) => {
// Retrieve route from request object
const route = url.parse(req.url).pathname
if (route === '/metrics') {
// Return all metrics the Prometheus exposition format
res.setHeader('Content-Type', register.contentType)
res.end(register.metrics())
}
})
// Start the HTTP server which exposes the metrics on http://localhost:8080/metrics
server.listen(8080)

Copy the above code into a file called server.js and start the Node.js HTTP server with the following command:

$ node server.js

You should now be able to access the metrics via http://localhost:8080/metrics.

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

const app = express();

let collectDefaultMetrics = client.collectDefaultMetrics;
const register = new client.Registry();
//let register = new client.Registry();


// Create custom metrics
const customCounter = new client.Counter({
name: "my_custom_counter",
help: "Custom counter for my application",
});

// Create custom metrics
const userCounter = new client.Counter({
name: "my_user_counter",
help: "User counter for my application",
});

// Create custom metrics
const fileCounter = new client.Counter({
name: "my_file_counter",
help: "File counter for my application",
});

// Add your custom metric to the registry
register.registerMetric(customCounter);
register.registerMetric(userCounter);
register.registerMetric(fileCounter);

client.collectDefaultMetrics({
app: 'node-application-monitoring-app',
prefix: 'node_',
timeout: 10000,
gcDurationBuckets: [0.001, 0.01, 0.1, 1, 2, 5],
register
});
// Create a route to expose /
app.get('/', (req, res) => {
customCounter.inc();
userCounter.inc();
fileCounter.inc();
console.log(register.metrics());
res.send("test");
});

// Create a route to expose metrics
app.get('/metrics', async (req, res) => {
res.setHeader('Content-Type', register.contentType);
res.send(await register.metrics());
});

app.listen(3000, () => {
console.log("Server is running on port 3000");
});

Increment the metric

Whenever you want to record a metric, you can increment it like this:

customCounter.inc();

You can increment your metric based on your application’s logic and business rules.

--

--

Tohid haghighi

Full-Stack Developer | C# | .NET Core | Vuejs | TDD | Javascript