diff --git a/README.md b/README.md index a6efadae..687ea196 100644 --- a/README.md +++ b/README.md @@ -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 -------- diff --git a/exampleConfig.js b/exampleConfig.js index 41921a99..af08b4a4 100644 --- a/exampleConfig.js +++ b/exampleConfig.js @@ -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] diff --git a/stats.js b/stats.js index d047c430..ff2e0675 100644 --- a/stats.js +++ b/stats.js @@ -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); @@ -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]; @@ -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;