Skip to main content
Version: Self Hosted Turbo

Prometheus exporter for Nodejs

Add a file named prometheus.js

var Register = require('prom-client').register; 
var Counter = require('prom-client').Counter;
var Histogram = require('prom-client').Histogram;
var Summary = require('prom-client').Summary;
var ResponseTime = require('response-time');

/**
\* A Prometheus counter that counts the invocations of the different HTTP verbs

\* e.g. a GET and a POST call will be counted as 2 different calls
`*/

module.exports.numOfRequests = numOfRequests = new Counter({
name: 'numOfRequests',
help: 'Number of requests made',
labelNames: ['method']
});


/**
\* A Prometheus counter that counts the invocations with different paths

\* e.g. /foo and /bar will be counted as 2 different paths
*/

module.exports.pathsTaken = pathsTaken = new Counter({
name: 'pathsTaken',
help: 'Paths taken in the app',
labelNames: ['path']
});

/**
\* A Prometheus summary to record the HTTP method, path, response code and response time
*/

module.exports.responses = responses = new Summary({
name: 'responses',
help: 'Response time in millis',
labelNames: ['method', 'path', 'status']
});

/**
\* This funtion will start the collection of metrics and should be called from within in the main js file
*/

module.exports.startCollection = function () {
require('prom-client').collectDefaultMetrics();
};

/**
\* This function increments the counters that are executed on the request side of an invocation

\* Currently it increments the counters for numOfPaths and pathsTaken
*/

module.exports.requestCounters = function (req, res, next) {
if (req.path != '/metrics') {
​ numOfRequests.inc({ method: req.method });
​ pathsTaken.inc({ path: req.path });
}
next();
}

/**
\* This function increments the counters that are executed on the response side of an invocation

\* Currently it updates the responses summary
*/

module.exports.responseCounters = ResponseTime(function (req, res, time) {
if(req.url != '/metrics') {
​ responses.labels(req.method, req.url, res.statusCode).observe(time);
}

})

/**
\* In order to have Prometheus get the data from this app a specific URL is registered
*/

module.exports.injectMetricsRoute = function (App) {
App.get('/metrics', (req, res) => {
​ res.set('Content-Type', Register.contentType);
​ res.end(Register.metrics());
});
};

Import Prometheus to application main file (app.js).

var Prometheus = require('./prometheus'); 

app.use(Prometheus.requestCounters);

app.use(Prometheus.responseCounters);

Prometheus.injectMetricsRoute(app);

Prometheus.startCollection();