Skip to content

Commit

Permalink
Changed config.percentThreshold to also accept a list of percentiles.
Browse files Browse the repository at this point in the history
The percentThreshold config parameter can now accept a single value or
a list of values. A statistic for each percentile threshold will be
generated analogous to how the single-value threshold stats were
generated before.

Updated documentation and example config file as well.
  • Loading branch information
Neil Hooey committed Mar 7, 2012
1 parent 2377c9b commit dd789c7
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 17 deletions.
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -33,6 +33,13 @@ Timing

The glork took 320ms to complete this time. StatsD figures out 90th percentile, average (mean), lower and upper bounds for the flush interval. The percentile threshold can be tweaked with `config.percentThreshold`.

The percentile threshold can be a single value, or a list of values, and will generate the following list of stats for each threshold:

stats.timers.$KEY.mean_$PCT
stats.timers.$KEY.upper_$PCT

Where `$KEY` is the key you stats key you specify when sending to statsd, and `$PCT` is the percentile threshold.

Sampling
--------

Expand Down
3 changes: 2 additions & 1 deletion exampleConfig.js
Expand Up @@ -21,7 +21,8 @@ Optional Variables:
debugInterval: interval to print debug information [ms, default: 10000]
dumpMessages: log all incoming messages
flushInterval: interval (in ms) to flush to Graphite
percentThreshold: for time information, calculate the Nth percentile
percentThreshold: for time information, calculate the Nth percentile(s)
(can be a single value or list of floating-point values)
[%, default: 90]
keyFlush: log the most frequently sent keys [object, default: undefined]
interval: how often to log frequent keys [ms, default: 0]
Expand Down
43 changes: 27 additions & 16 deletions stats.js
Expand Up @@ -165,6 +165,11 @@ config.configFile(process.argv[2], function (config, oldConfig) {

var flushInterval = Number(config.flushInterval || 10000);

var pctThreshold = config.percentThreshold || 90;
if (!Array.isArray(pctThreshold)) {
pctThreshold = [ pctThreshold ]; // listify percentiles so single values work the same
}

flushInt = setInterval(function () {
var statString = '';
var ts = Math.round(new Date().getTime() / 1000);
Expand All @@ -184,7 +189,6 @@ config.configFile(process.argv[2], function (config, oldConfig) {

for (key in timers) {
if (timers[key].length > 0) {
var pctThreshold = config.percentThreshold || 90;
var values = timers[key].sort(function (a,b) { return a-b; });
var count = values.length;
var min = values[0];
Expand All @@ -193,28 +197,35 @@ config.configFile(process.argv[2], function (config, oldConfig) {
var mean = min;
var maxAtThreshold = max;

if (count > 1) {
var thresholdIndex = Math.round(((100 - pctThreshold) / 100) * count);
var numInThreshold = count - thresholdIndex;
values = values.slice(0, numInThreshold);
maxAtThreshold = values[numInThreshold - 1];
var message = "";

var key2;

// average the remaining timings
var sum = 0;
for (var i = 0; i < numInThreshold; i++) {
sum += values[i];
for (key2 in pctThreshold) {
var pct = pctThreshold[key2];
if (count > 1) {
var thresholdIndex = Math.round(((100 - pct) / 100) * count);
var numInThreshold = count - thresholdIndex;
var pctValues = values.slice(0, numInThreshold);
maxAtThreshold = pctValues[numInThreshold - 1];

// average the remaining timings
var sum = 0;
for (var i = 0; i < numInThreshold; i++) {
sum += pctValues[i];
}

mean = sum / numInThreshold;
}

mean = sum / numInThreshold;
message += 'stats.timers.' + key + '.mean_' + pct + ' ' + mean + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.upper_' + pct + ' ' + maxAtThreshold + ' ' + ts + "\n";
}

timers[key] = [];

var message = "";
message += 'stats.timers.' + key + '.mean ' + mean + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.upper ' + max + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.upper_' + pctThreshold + ' ' + maxAtThreshold + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.lower ' + min + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.upper ' + max + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.lower ' + min + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.count ' + count + ' ' + ts + "\n";
statString += message;

Expand Down

0 comments on commit dd789c7

Please sign in to comment.