Permalink
Browse files

Add support for "averages". See inline docs and updated MD.

  • Loading branch information...
1 parent 4e4ed79 commit 5603a427333ea053afee19e180dd6f9f991c082f @jeff-minard-ck committed Jun 14, 2012
Showing with 50 additions and 2 deletions.
  1. +7 −0 README.md
  2. +28 −0 backends/graphite.js
  3. +15 −2 stats.js
View
@@ -30,6 +30,13 @@ Counting
This is a simple counter. Add 1 to the "gorets" bucket. It stays in memory until the flush interval `config.flushInterval`.
+Averages
+--------
+
+ loadAverage:3.5|a
+
+Averages will be collected individually during the flush interval. At flush, they will be summed per unique key and then averaged and reported as a single metric. Flush intervals where there are no reported values for a given key will send no value to the backend.
+
Timing
------
View
@@ -53,6 +53,7 @@ var flush_stats = function graphite_flush(ts, metrics) {
var counters = metrics.counters;
var gauges = metrics.gauges;
var timers = metrics.timers;
+ var averages = metrics.averages;
var pctThreshold = metrics.pctThreshold;
for (key in counters) {
@@ -116,6 +117,33 @@ var flush_stats = function graphite_flush(ts, metrics) {
numStats += 1;
}
+ // Averages:
+ //
+ // This metric method is IMMENSELY useful if you track something like server
+ // load, and you report the metric, let's say, every second. If your flush
+ // interval is 10 seconds, what do you do with the 9 other metrics? With
+ // guages you only get the most recent one. With counters you get some weird
+ // summation of load (which is wrong). What you truly want is the average of
+ // the reported metric over the since the last flush. Finally, averages will
+ // not report a "0" value if you haven't sent anything to statsd, you will
+ // see "null"s in graphite, instead.
+ //
+ // Average all the reported values per given "average key" and send the result to graphite as the metric
+ // This will not submit "0" value to keys for average metrics which have not been reported
+ for (key in averages) {
+ var vals = averages[key],
+ valCount = averages[key].length,
+ valTotal = 0;
+ if (valCount >= 1) {
+ for (idx in vals) {
+ valTotal += vals[idx];
+ }
+ var averageVal = valTotal / valCount;
+ statString += 'stats.' + key + ' ' + averageVal + ' ' + ts + "\n";
+ numStats += 1;
+ }
+ }
+
statString += 'statsd.numStats ' + numStats + ' ' + ts + "\n";
post_stats(statString);
};
View
@@ -9,6 +9,7 @@ var keyCounter = {};
var counters = {};
var timers = {};
var gauges = {};
+var averages = {};
var pctThreshold = null;
var debugInt, flushInterval, keyFlushInt, server, mgmtServer;
var startup_time = Math.round(new Date().getTime() / 1000);
@@ -36,13 +37,14 @@ function flushMetrics() {
var metrics_hash = {
counters: counters,
gauges: gauges,
+ averages: averages,
timers: timers,
pctThreshold: pctThreshold
}
// After all listeners, reset the stats
backendEvents.once('flush', function clear_metrics(ts, metrics) {
- // Clear the counters
+ // Zero the counters
for (key in metrics.counters) {
metrics.counters[key] = 0;
}
@@ -51,6 +53,11 @@ function flushMetrics() {
for (key in metrics.timers) {
metrics.timers[key] = [];
}
+
+ // Clear the averages
+ for (key in averages) {
+ averages[key] = [];
+ }
});
// Flush metrics to each backend.
@@ -75,7 +82,8 @@ config.configFile(process.argv[2], function (config, oldConfig) {
debugInt = setInterval(function () {
util.log("Counters:\n" + util.inspect(counters) +
"\nTimers:\n" + util.inspect(timers) +
- "\nGauges:\n" + util.inspect(gauges));
+ "\nGauges:\n" + util.inspect(gauges) +
+ "\nAverages:\n" + util.inspect(averages));
}, config.debugInterval || 10000);
}
@@ -118,6 +126,11 @@ config.configFile(process.argv[2], function (config, oldConfig) {
timers[key].push(Number(fields[0] || 0));
} else if (fields[1].trim() == "g") {
gauges[key] = Number(fields[0] || 0);
+ } else if (fields[1].trim() == "a") {
+ if (! averages[key]) {
+ averages[key] = [];
+ }
+ averages[key].push(Number(fields[0] || 0));
} else {
if (fields[2] && fields[2].match(/^@([\d\.]+)/)) {
sampleRate = Number(fields[2].match(/^@([\d\.]+)/)[1]);

0 comments on commit 5603a42

Please sign in to comment.