Skip to content
Merged
Show file tree
Hide file tree
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
38 changes: 37 additions & 1 deletion lib/statsFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,42 @@ function applyStatsFns (Client) {
};
};

/**
* Decorates an async function with timing recording behaviour.
*
* This version of `timer` will record the time take for the asyncronus action returned by `func`
* not just the execution time of `func` itself.
*
* @param func {<T,A>(...A):Promise<T>} The function to run
* @param stat {String|Array} The stat(s) to send
* @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
* @param tags {Array=} The Array of tags to add to metrics. Optional.
* @param callback {Function=} Callback when message is done being delivered. Optional.
*/
Client.prototype.asyncTimer = function (func, stat, sampleRate, tags, callback) {
var self = this;
return function() {
var end = hrtimer();
var p = func.apply(null, arguments);
var recordStat = function() { self.timing(stat, end(), sampleRate, tags, callback); };
p.then(recordStat, recordStat);
return p;
};
};

function hrtimer() {
var start = process.hrtime();

return function () {
var durationComponents = process.hrtime(start);
var seconds = durationComponents[0];
var nanoseconds = durationComponents[1];
var duration = seconds * 1000 + nanoseconds / 1E6;
return duration;
};
}


/**
* Increments a stat by a specified amount
* @param stat {String|Array} The stat(s) to send
Expand Down Expand Up @@ -267,4 +303,4 @@ function applyStatsFns (Client) {
};
}

module.exports = applyStatsFns;
module.exports = applyStatsFns;
29 changes: 28 additions & 1 deletion test/timer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';

var StatsD = require('../lib/statsd');
var assert = require('assert');

var createStatsdClient = require('./helpers').createStatsdClient;
Expand Down Expand Up @@ -105,5 +105,32 @@ module.exports = function runTimerTestSuite() {
});
});
});

it('should record "user time" of promise', function () {
/* globals Promise */
var statsd = new StatsD({mock:true});

var onehundredMsFunc = function () { return delay(100); };

var instrumented = statsd.asyncTimer(onehundredMsFunc, 'name-thingy');

return instrumented().then(function() {

var stat = statsd.mockBuffer[0];
var name = stat.split(/:|\|/)[0];
var time = stat.split(/:|\|/)[1];

assert.equal(name, 'name-thingy');
assert.ok(parseFloat(time) >= 100);
assert.ok(parseFloat(time) < 200);
});
});
});
};


function delay(n) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, n);
});
}