Skip to content

Commit

Permalink
Add post-timer labels (#1) (#30)
Browse files Browse the repository at this point in the history
* Add post-timer labels (#1)

* add post-timer label support to summary

no reason to add a parameter into the first nested function, since that's only used in Summary.labels

* allow startLabels to be undefined

* add post-timer label support for gauges and histograms

* add extend to gauge.js

* add gauge tests (#2)

* add gauge tests

* add histogram tests

* add summary tests

* add timer + label documentation to readme

* add comments

* lint files
  • Loading branch information
notkevin888 authored and siimon committed Sep 6, 2016
1 parent 2600846 commit de29e47
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 9 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ gauge.set({ method: 'GET', statusCode: '200' }, 100); // 1st version, Set value
gauge.labels('GET', '200').set(100); // 2nd version, Same as above
```

It is also possible to use timers with labels, both before and after the timer is created:
```js
var end = startTimer({ method: 'GET' }); // Set method to GET, we don't know statusCode yet
xhrRequest(function(err, res) {
if (err) {
end({ statusCode: '500' }); // Sets value to xhrRequest duration in seconds with statusCode 500
} else {
end({ statusCode: '200' }); // Sets value to xhrRequest duration in seconds with statusCode 200
}
});
```

#### Pushgateway

It is possible to push metrics via a [Pushgateway](https://github.com/prometheus/pushgateway).
Expand Down
7 changes: 4 additions & 3 deletions lib/gauge.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var register = require('./register');
var type = 'gauge';

var isNumber = require('./util').isNumber;
var extend = require('util-extend');
var createValue = require('./util').setValue;
var getProperties = require('./util').getPropertiesFromObj;
var getLabels = require('./util').getLabels;
Expand Down Expand Up @@ -133,13 +134,13 @@ function setToCurrentTime(labels) {
};
}

function startTimer(labels) {
function startTimer(startLabels) {
var gauge = this;
return function() {
var start = new Date();
return function() {
return function(endLabels) {
var end = new Date();
gauge.set(labels, (end - start) / 1000);
gauge.set(extend(startLabels || {}, endLabels), (end - start) / 1000);
};
};
}
Expand Down
6 changes: 3 additions & 3 deletions lib/histogram.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ Histogram.prototype.labels = function() {
};
};

function startTimer(labels) {
function startTimer(startLabels) {
var histogram = this;
return function() {
var start = new Date();
return function() {
return function(endLabels) {
var end = new Date();
histogram.observe(labels, (end - start) / 1000);
histogram.observe(extend(startLabels || {}, endLabels), (end - start) / 1000);
};
};
}
Expand Down
7 changes: 4 additions & 3 deletions lib/summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,17 @@ Summary.prototype.labels = function() {
};
};

function startTimer(labels) {
function startTimer(startLabels) {
var summary = this;
return function() {
var start = new Date();
return function() {
return function(endLabels) {
var end = new Date();
summary.observe(labels, (end - start) / 1000);
summary.observe(extend(startLabels || {}, endLabels), (end - start) / 1000);
};
};
}

function validateInput(name, help, labels) {
if(!help) {
throw new Error('Missing mandatory help parameter');
Expand Down
17 changes: 17 additions & 0 deletions test/gaugeTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ describe('gauge', function() {
expectValue(1);
clock.restore();
});
it('should be able to start a timer and set labels afterwards', function(){
var clock = sinon.useFakeTimers();
var end = instance.startTimer();
clock.tick(1000);
end({ 'code': 200 });
expectValue(1);
clock.restore();
});
it('should allow labels before and after timers', function(){
instance = new Gauge('name', 'help', ['code', 'success']);
var clock = sinon.useFakeTimers();
var end = instance.startTimer({ 'code': 200 });
clock.tick(1000);
end({ 'success': 'SUCCESS' });
expectValue(1);
clock.restore();
});
});

function expectValue(val) {
Expand Down
23 changes: 23 additions & 0 deletions test/histogramTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,29 @@ describe('histogram', function() {
expect(res.value).to.equal(1);
clock.restore();
});

it('should start a timer and set labels afterwards', function(){
var clock = sinon.useFakeTimers();
var end = instance.startTimer();
clock.tick(500);
end({ 'method': 'get' });
var res = getValueByLeAndLabel(0.5, 'method', 'get', instance.get().values);
expect(res.value).to.equal(1);
clock.restore();
});

it('should allow labels before and after timers', function(){
instance = new Histogram('histogram_labels', 'Histogram with labels fn', [ 'method', 'success' ]);
var clock = sinon.useFakeTimers();
var end = instance.startTimer({ 'method': 'get' });
clock.tick(500);
end({ 'success': 'SUCCESS' });
var res1 = getValueByLeAndLabel(0.5, 'method', 'get', instance.get().values);
var res2 = getValueByLeAndLabel(0.5, 'success', 'SUCCESS', instance.get().values);
expect(res1.value).to.equal(1);
expect(res2.value).to.equal(1);
clock.restore();
});
});

function getValueByName(name, values) {
Expand Down
76 changes: 76 additions & 0 deletions test/summaryTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
describe('summary', function() {
var Summary = require('../index').summary;
var expect = require('chai').expect;
var sinon = require('sinon');
var instance;

beforeEach(function() {
Expand Down Expand Up @@ -156,5 +157,80 @@ describe('summary', function() {
};
expect(fn).to.throw(Error);
});

it('should start a timer', function() {
var clock = sinon.useFakeTimers();
var end = instance.labels('GET', '/test').startTimer();
clock.tick(1000);
end();
var values = instance.get().values;
expect(values).to.have.length(3);
expect(values[0].labels.method).to.equal('GET');
expect(values[0].labels.endpoint).to.equal('/test');
expect(values[0].labels.quantile).to.equal(0.9);
expect(values[0].value).to.equal(1);

expect(values[1].metricName).to.equal('summary_test_sum');
expect(values[1].labels.method).to.equal('GET');
expect(values[1].labels.endpoint).to.equal('/test');
expect(values[1].value).to.equal(1);

expect(values[2].metricName).to.equal('summary_test_count');
expect(values[2].labels.method).to.equal('GET');
expect(values[2].labels.endpoint).to.equal('/test');
expect(values[2].value).to.equal(1);

clock.restore();
});

it('should start a timer and set labels afterwards', function(){
var clock = sinon.useFakeTimers();
var end = instance.startTimer();
clock.tick(1000);
end({ 'method': 'GET', 'endpoint': '/test' });
var values = instance.get().values;
expect(values).to.have.length(3);
expect(values[0].labels.method).to.equal('GET');
expect(values[0].labels.endpoint).to.equal('/test');
expect(values[0].labels.quantile).to.equal(0.9);
expect(values[0].value).to.equal(1);

expect(values[1].metricName).to.equal('summary_test_sum');
expect(values[1].labels.method).to.equal('GET');
expect(values[1].labels.endpoint).to.equal('/test');
expect(values[1].value).to.equal(1);

expect(values[2].metricName).to.equal('summary_test_count');
expect(values[2].labels.method).to.equal('GET');
expect(values[2].labels.endpoint).to.equal('/test');
expect(values[2].value).to.equal(1);

clock.restore();
});

it('should allow labels before and after timers', function(){
var clock = sinon.useFakeTimers();
var end = instance.startTimer({ 'method': 'GET' });
clock.tick(1000);
end({ 'endpoint': '/test' });
var values = instance.get().values;
expect(values).to.have.length(3);
expect(values[0].labels.method).to.equal('GET');
expect(values[0].labels.endpoint).to.equal('/test');
expect(values[0].labels.quantile).to.equal(0.9);
expect(values[0].value).to.equal(1);

expect(values[1].metricName).to.equal('summary_test_sum');
expect(values[1].labels.method).to.equal('GET');
expect(values[1].labels.endpoint).to.equal('/test');
expect(values[1].value).to.equal(1);

expect(values[2].metricName).to.equal('summary_test_count');
expect(values[2].labels.method).to.equal('GET');
expect(values[2].labels.endpoint).to.equal('/test');
expect(values[2].value).to.equal(1);

clock.restore();
});
});
});

0 comments on commit de29e47

Please sign in to comment.