Skip to content

Commit

Permalink
Extra metrics (#34)
Browse files Browse the repository at this point in the history
* Make sure to reset mock timers

* Add some helpful metrics
  • Loading branch information
SimenB authored and siimon committed Sep 7, 2016
1 parent e9ba25e commit 116c0b6
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ automatically for you when you do `require('prom-client')`.

NOTE: Some of the metrics, concerning File Descriptors and Memory, are only available on Linux.

In addition, some Node-specific metrics are included, such as event loop lag, and active handles. See what metrics there are in
[lib/metrics](lib/metrics).

The function returned from `defaultMetrics` takes 2 options, a blacklist of metrics to skip, and a timeout for how often the probe should
be fired. By default all probes are launched every 10 seconds, but this can be modified like this:

Expand Down
8 changes: 7 additions & 1 deletion lib/defaultMetrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ var processStartTime = require('./metrics/processStartTime');
var osMemoryHeap = require('./metrics/osMemoryHeap');
var processOpenFileDescriptors = require('./metrics/processOpenFileDescriptors');
var processMaxFileDescriptors = require('./metrics/processMaxFileDescriptors');
var eventLoopLag = require('./metrics/eventLoopLag');
var processHandles = require('./metrics/processHandles');
var processRequests = require('./metrics/processRequests');

var metrics = {
processCpuTotal: processCpuTotal,
processStartTime: processStartTime,
osMemoryHeap: osMemoryHeap,
processOpenFileDescriptors: processOpenFileDescriptors,
processMaxFileDescriptors: processMaxFileDescriptors
processMaxFileDescriptors: processMaxFileDescriptors,
eventLoopLag: eventLoopLag,
processHandles: processHandles,
processRequests: processRequests
};

var existingInterval = null;
Expand Down
20 changes: 20 additions & 0 deletions lib/metrics/eventLoopLag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

var Gauge = require('../gauge');

function reportEventloopLag(start, gauge){
var delta = process.hrtime(start);
var nanosec = delta[0] * 1e9 + delta[1];
var ms = nanosec / 1e6;

gauge.set(Math.round(ms));
}

module.exports = function() {
var gauge = new Gauge('node_eventloop_lag_milliseconds', 'Lag of event loop in milliseconds.');

return function() {
var start = process.hrtime();
setImmediate(reportEventloopLag, start, gauge);
};
};
17 changes: 17 additions & 0 deletions lib/metrics/processHandles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

var Gauge = require('../gauge');

module.exports = function() {
// Don't do anything if the function is removed in later nodes (exists in node@6)
if(typeof process._getActiveHandles !== 'function') {
return function () {
};
}

var gauge = new Gauge('node_active_handles_total', 'Number of active handles.');

return function() {
gauge.set(process._getActiveHandles().length);
};
};
16 changes: 16 additions & 0 deletions lib/metrics/processRequests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

var Gauge = require('../gauge');

module.exports = function() { // Don't do anything if the function is removed in later nodes (exists in node@6)
if(typeof process._getActiveRequests !== 'function') {
return function () {
};
}

var gauge = new Gauge('node_active_requests_total', 'Number of active requests.');

return function() {
gauge.set(process._getActiveRequests().length);
};
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"scripts": {
"test": "npm run lint && npm run test-unit",
"lint": "eslint --ignore-pattern doc/ --ignore-path .gitignore .",
"test-unit": "mocha test/"
"test-unit": "mocha --recursive test/"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions test/defaultMetrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ describe('defaultMetrics', function() {
it('should add metrics to the registry', function() {
expect(register.getMetricsAsJSON()).to.have.length(0);
interval = defaultMetrics();
expect(register.getMetricsAsJSON()).to.have.length(3);
expect(register.getMetricsAsJSON()).to.have.length(6);
});

it('should allow blacklisting unwanted metrics', function() {
expect(register.getMetricsAsJSON()).to.have.length(0);
interval = defaultMetrics(['osMemoryHeap']);
expect(register.getMetricsAsJSON()).to.have.length(2);
expect(register.getMetricsAsJSON()).to.have.length(5);
});
});
1 change: 1 addition & 0 deletions test/gaugeTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ describe('gauge', function() {
var clock = sinon.useFakeTimers();
instance.setToCurrentTime();
expectValue(new Date().getTime());
clock.restore();
});

it('should not allow non numbers', function() {
Expand Down
31 changes: 31 additions & 0 deletions test/metrics/eventLoopLagTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict';

describe('eventLoopLag', function () {
var expect = require('chai').expect;
var register = require('../../index').register;
var eventLoopLag = require('../../lib/metrics/eventLoopLag');

before(function () {
register.clear();
});

afterEach(function () {
register.clear();
});

it('should add metric to the registry', function (done) {
expect(register.getMetricsAsJSON()).to.have.length(0);
eventLoopLag()();

setTimeout(function () {
var metrics = register.getMetricsAsJSON();
expect(metrics).to.have.length(1);

expect(metrics[0].help).to.equal('Lag of event loop in milliseconds.');
expect(metrics[0].type).to.equal('gauge');
expect(metrics[0].name).to.equal('node_eventloop_lag_milliseconds');

done();
}, 5);
});
});
28 changes: 28 additions & 0 deletions test/metrics/processHandlesTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

describe('processHandles', function () {
var expect = require('chai').expect;
var register = require('../../index').register;
var processHandles = require('../../lib/metrics/processHandles');

before(function () {
register.clear();
});

afterEach(function () {
register.clear();
});

it('should add metric to the registry', function () {
expect(register.getMetricsAsJSON()).to.have.length(0);

processHandles()();

var metrics = register.getMetricsAsJSON();

expect(metrics).to.have.length(1);
expect(metrics[0].help).to.equal('Number of active handles.');
expect(metrics[0].type).to.equal('gauge');
expect(metrics[0].name).to.equal('node_active_handles_total');
});
});
28 changes: 28 additions & 0 deletions test/metrics/processRequestsTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

describe('processRequests', function () {
var expect = require('chai').expect;
var register = require('../../index').register;
var processRequests = require('../../lib/metrics/processRequests');

before(function () {
register.clear();
});

afterEach(function () {
register.clear();
});

it('should add metric to the registry', function () {
expect(register.getMetricsAsJSON()).to.have.length(0);

processRequests()();

var metrics = register.getMetricsAsJSON();

expect(metrics).to.have.length(1);
expect(metrics[0].help).to.equal('Number of active requests.');
expect(metrics[0].type).to.equal('gauge');
expect(metrics[0].name).to.equal('node_active_requests_total');
});
});

0 comments on commit 116c0b6

Please sign in to comment.