Skip to content
This repository was archived by the owner on May 5, 2022. It is now read-only.

add method which allows adding custom metrics #17

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -174,6 +174,30 @@ server.listen(port, (err) => {
});
```

## prometheus.addMetric(metricInfo, onDataEvent)

this method allow you to add custom monitoring for metrics.
the first parameter should have `name`, which represent the name of the appmetrics monitoring event. `data`, the dynamic data which will be saved on each event, and a `toString` which will be printed as part of the `metrics` route.
the last function is the listener for the monitoring and it will `this` as the metric info, which allow to save the data differently on each metric monitoring event.

```js
require('appmetrics-prometheus')
.attach()
.addMetric({
name: 'socketio',
data: null,
toString() {
if(this.data) {
return `socketio_last_event ${JSON.stringify(this.data)}`;
}

return '';
}
}, function(data) {
this.data = data;
});
```

## Performance overhead

Our testing has shown that the performance overhead in terms of processing is minimal, adding less than 0.5 % to the CPU usage of your application.
52 changes: 44 additions & 8 deletions lib/appmetrics-prometheus.js
Original file line number Diff line number Diff line change
@@ -35,20 +35,21 @@ var save = {
http: {},
https: {},
};

var extendedMetrics = {};
var globalOptions = {};

exports.attach = function(options) {
if (save.http.Server) {
// Already attached.
return exports;
}
// Protect our options from modification.
options = util._extend({}, options);
globalOptions = util._extend({}, options);

// if the user hasn't supplied appmetrics, require
// here so we get http probe data
if (!options.appmetrics) {
options.appmetrics = require('appmetrics');
if (!globalOptions.appmetrics) {
globalOptions.appmetrics = require('appmetrics');
}

patch(save.http, require('http'));
@@ -59,21 +60,50 @@ exports.attach = function(options) {
save.Server = http.Server;
http.Server = function() {
const server = save.Server.apply(this, arguments);
options.server = server;
monitor(options);
globalOptions.server = server;
monitor(globalOptions);
return server;
};
save.createServer = http.createServer;
http.createServer = function() {
const server = save.createServer.apply(this, arguments);
options.server = server;
monitor(options);
globalOptions.server = server;
monitor(globalOptions);
return server;
};
}
return exports;
};

/**
* this method allow you to add customized metrics that will be visible through prometheus
* metrics endpoint
*
* @param {Object} metricInfo
* @param {string} metricInfo.name the listener monitored metric
* @param {any} metricInfo.data the changing data of the metric
* @param {function} metricInfo.toString the string representation of this object. will be showed as new line in the metrics endpoint
* @param {function} onMetricData function that represent what to do when receiving metric data,
* usually will set the data in order to print the data on metrics endpoint.
*
* @returns exports the exports object for chaining
*/
exports.addMetric = function(metricInfo, onMetricData) {
var appmetrics = globalOptions.appmetrics || require('appmetrics');
var monitoring = appmetrics.monitor();

if (typeof onMetricData !== 'function') {
onMetricData = function(data) {
extendedMetrics[metricInfo.name].data = data;
};
}

extendedMetrics[metricInfo.name] = metricInfo;
monitoring.on(metricInfo.name, onMetricData.bind(extendedMetrics[metricInfo.name]));

return exports;
};

// Start monitoring process and subscribe to the data.
// Don't export monitor
var monitor = function(options) {
@@ -131,6 +161,11 @@ var monitor = function(options) {
res.write(httpRequestTotal);
res.write(httpRequestDuration);
}

for (var metric in extendedMetrics) {
res.write(extendedMetrics[metric].toString() + '\n');
}

res.end();
}

@@ -292,3 +327,4 @@ var monitor = function(options) {
});
return server;
};