Designing a Node.js Metrics Endpoint for Prometheus

Mehran
4 min readMar 15, 2023

--

Prometheus is an excellent open-source tool that collects data from different places, and you can use it to make cool dashboards. You can create the dashboards in Prometheus or connect them to another tool called Grafana to make even cooler ones.

With Prometheus, you can learn all kinds of stuff about your system's work. It’s great for determining if something is going wrong or needing to make changes to improve performance. And when you connect it to Grafana, you can make all kinds of sweet visualizations to help you better understand your data.

If you want to keep an eye on what’s going on with your systems and make cool dashboards to show off, Prometheus is the tool for you!

In this post, I will walk you through building a metric endpoint in Node.js and how to scrape it using Prometheus.

import { Registry, collectDefaultMetrics, Counter } from 'prom-client'
import express from 'express'

// create a registry to hold metrics
const registry = new Registry()

// enable default metrics like CPU usage, memory usage, etc.
collectDefaultMetrics({ register: registry })

// create a counter to track the number of requests
const requestCounter = new Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
registers: [registry],
labelNames: ['method', 'path', 'status'],
})

// create an express app
const app = express()

// define a route to increment the request counter
app.get('/hello', (req, res) => {
requestCounter.labels(req.method, req.path, res.statusCode.toString()).inc()
res.send('Hello World!')
})

// expose the metrics for Prometheus to scrape
app.get('/metrics', async (req, res) => {
const result = await registry.metrics()
res.send(result)
})

// start the server
app.listen(3000, () => {
// eslint-disable-next-line no-console
// @ts-ignore
console.log('Server listening on port 3000')
})

In this code, we use express to create an endpoint and prom-client to create custom metrics that Prometheus can scrape.

Creating custom metrics

Prom-client provides a great feature that allows users to create their metrics. Check out the code snippet below for an example of creating custom metrics.

const requestCounter = new Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
registers: [registry],
labelNames: ['method', 'path', 'status'],
})

Collect metrics

We must utilize the previously created “requestCounter” object to gather metrics. Check out the following code snippet to see how it’s done.

requestCounter.labels(req.method, req.path, res.statusCode.toString()).inc()

Metric endpoint

Prometheus relies on a metric endpoint to scrape data, and the code snippet below demonstrates how to create such an endpoint.

app.get('/metrics', async (req, res) => {
const result = await registry.metrics()
res.send(result)
})

Run the service

With the code prepared, it’s time to launch the service. To execute the TypeScript directly, you can utilize the ts-node package.

npm install ts-node

Now it is time to run the service by running the below command

ts-node --files index.ts

Testing the service

To confirm your service is operational, ensure you can successfully call these two GET endpoints and receive a 200 status code.

http://localhost:3000/metrics
http://localhost:3000/hello

Installing Prometheus on Mac

Okay, now it’s time to install Prometheus! I’ll show you how to do it on a Mac, but the process should be similar to other operating systems.

brew install prometheus

Be patient; this process might take a few minutes to finish. Once the installation is complete, you must run the following command to start Prometheus.

brew services start prometheus

Update Prometheus Configuration

Before Prometheus can scrape your endpoint to collect metrics, you need to configure Prometheus and set up all necessary parameters. To do this, first, locate the prometheus.yml file on your system. If you installed Prometheus using Homebrew, you could find the YAML file at the following path:

/usr/local/etc

Add the metrics endpoint to the scrape_configs section of the yml file.

  - job_name: 'node-app'
scrape_interval: 10s
static_configs:
- targets: [ 'localhost:3000' ]

The final yaml file should look like this

global:
scrape_interval: 15s

scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: 'node-app'
scrape_interval: 10s
static_configs:
- targets: [ 'localhost:3000' ]

Open Prometheus

Head to the below endpoint to open Prometheus

http://localhost:9090/

To verify if Prometheus can scrape your service’s metrics endpoint, open the Configuration submenu from the Status menu, as shown in the accompanying screenshot.

Prometheus Configuration

You should be able to see your service configuration here.

Targets

Navigate to the Targets submenu under the Status menu to verify the health status of your service. If Prometheus has successfully connected to your service, you should see a display similar to the provided screenshot.

Target status

Collect metrics

You need to make an API call to the /hello endpoint to gather metrics from the service. Make sure to do this multiple times to accumulate sufficient data.

http://localhost:3000/hello

Graph

Now it’s time to query the collected metrics in Prometheus. To do this, navigate to the Graph menu and enter the following text in the expression text box. This represents the custom metric the service gathers when a call is made to the /hello endpoint. In addition to this metric, the prom-client automatically collects numerous other metrics. To view a list of all these metrics, you can call the /metrics endpoint of your service.

http_requests_total

I hope this brief tutorial has helped you better understand how Prometheus operates and how to create a metrics endpoint in a Node.js service.

--

--

Mehran
Mehran

Written by Mehran

Tech Team Lead | Cloud, Video & Microservices Expert | Insights on streaming innovations & programming. #ContinuousLearning

No responses yet