From 545d7800c8b64af8c8ec8c87dd6cf5b3f25f66a7 Mon Sep 17 00:00:00 2001 From: Daniel Schauenberg Date: Tue, 7 Aug 2012 23:21:30 -0400 Subject: [PATCH] modify key namespacing to be easier to configure This makes some changes to what the default key namespaces are and how they are configured. Basically it puts the config under the graphite key and doesn't need the user to take care of where dots are set. --- backends/graphite.js | 77 ++++++++++++++++++++++++++++++++------------ exampleConfig.js | 9 +++--- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/backends/graphite.js b/backends/graphite.js index bd73c84..420e548 100644 --- a/backends/graphite.js +++ b/backends/graphite.js @@ -19,11 +19,20 @@ var debug; var flushInterval; var graphiteHost; var graphitePort; + +// prefix configuration +var globalPrefix; var prefixPersecond; -var prefixCount; +var prefixCounter; var prefixTimer; var prefixGauge; +// set up namespaces +var globalNamespace = []; +var counterNamespace = []; +var timerNamespace = []; +var gaugesNamespace = []; + var graphiteStats = {}; var post_stats = function graphite_post_stats(statString) { @@ -39,8 +48,9 @@ var post_stats = function graphite_post_stats(statString) { }); graphite.on('connect', function() { var ts = Math.round(new Date().getTime() / 1000); - statString += 'stats.statsd.graphiteStats.last_exception ' + last_exception + ' ' + ts + "\n"; - statString += 'stats.statsd.graphiteStats.last_flush ' + last_flush + ' ' + ts + "\n"; + var namespace = globalNamespace.concat('statsd'); + statString += namespace.join(".") + '.graphiteStats.last_exception ' + last_exception + ' ' + ts + "\n"; + statString += namespace.join(".") + '.graphiteStats.last_flush ' + last_flush + ' ' + ts + "\n"; this.write(statString); this.end(); graphiteStats.last_flush = Math.round(new Date().getTime() / 1000); @@ -66,11 +76,13 @@ var flush_stats = function graphite_flush(ts, metrics) { var pctThreshold = metrics.pctThreshold; for (key in counters) { + var namespace = counterNamespace.concat(key); + var namespace_num = counterNamespace.concat('stats_counts', key); var value = counters[key]; var valuePerSecond = value / (flushInterval / 1000); // calculate "per second" rate - statString += prefixPersecond + key + ' ' + valuePerSecond + ' ' + ts + "\n"; - statString += prefixCount + key + ' ' + value + ' ' + ts + "\n"; + statString += namespace.join(".") + ' ' + valuePerSecond + ' ' + ts + "\n"; + statString += namespace_num.join(".") + ' ' + value + ' ' + ts + "\n"; numStats += 1; } @@ -82,6 +94,9 @@ var flush_stats = function graphite_flush(ts, metrics) { var min = values[0]; var max = values[count - 1]; + var namespace = timerNamespace.concat(key); + var the_key = namespace.join("."); + var cumulativeValues = [min]; for (var i = 1; i < count; i++) { cumulativeValues.push(values[i] + cumulativeValues[i-1]); @@ -108,9 +123,9 @@ var flush_stats = function graphite_flush(ts, metrics) { var clean_pct = '' + pct; clean_pct.replace('.', '_'); - message += prefixTimer + key + '.mean_' + clean_pct + ' ' + mean + ' ' + ts + "\n"; - message += prefixTimer + key + '.upper_' + clean_pct + ' ' + maxAtThreshold + ' ' + ts + "\n"; - message += prefixTimer + key + '.sum_' + clean_pct + ' ' + sum + ' ' + ts + "\n"; + message += the_key + '.mean_' + clean_pct + ' ' + mean + ' ' + ts + "\n"; + message += the_key + '.upper_' + clean_pct + ' ' + maxAtThreshold + ' ' + ts + "\n"; + message += the_key + '.sum_' + clean_pct + ' ' + sum + ' ' + ts + "\n"; } sum = cumulativeValues[count-1]; @@ -122,12 +137,12 @@ var flush_stats = function graphite_flush(ts, metrics) { } var stddev = Math.sqrt(sumOfDiffs / count); - message += prefixTimer + key + '.std ' + stddev + ' ' + ts + "\n"; - message += prefixTimer + key + '.upper ' + max + ' ' + ts + "\n"; - message += prefixTimer + key + '.lower ' + min + ' ' + ts + "\n"; - message += prefixTimer + key + '.count ' + count + ' ' + ts + "\n"; - message += prefixTimer + key + '.sum ' + sum + ' ' + ts + "\n"; - message += prefixTimer + key + '.mean ' + mean + ' ' + ts + "\n"; + message += the_key + '.std ' + stddev + ' ' + ts + "\n"; + message += the_key + '.upper ' + max + ' ' + ts + "\n"; + message += the_key + '.lower ' + min + ' ' + ts + "\n"; + message += the_key + '.count ' + count + ' ' + ts + "\n"; + message += the_key + '.sum ' + sum + ' ' + ts + "\n"; + message += the_key + '.mean ' + mean + ' ' + ts + "\n"; statString += message; @@ -136,12 +151,14 @@ var flush_stats = function graphite_flush(ts, metrics) { } for (key in gauges) { - statString += prefixGauge + key + ' ' + gauges[key] + ' ' + ts + "\n"; + var namespace = gaugesNamespace.concat(key); + statString += namespace.join(".") + ' ' + gauges[key] + ' ' + ts + "\n"; numStats += 1; } - statString += 'statsd.numStats ' + numStats + ' ' + ts + "\n"; - statString += 'stats.statsd.graphiteStats.calculationtime ' + (Date.now() - starttime) + ' ' + ts + "\n"; + var namespace = globalNamespace.concat('statsd'); + statString += namespace.join(".") + '.numStats ' + numStats + ' ' + ts + "\n"; + statString += namespace.join(".") + '.graphiteStats.calculationtime ' + (Date.now() - starttime) + ' ' + ts + "\n"; post_stats(statString); }; @@ -155,10 +172,28 @@ exports.init = function graphite_init(startup_time, config, events) { debug = config.debug; graphiteHost = config.graphiteHost; graphitePort = config.graphitePort; - prefixPersecond = config.prefixPersecond || "statsd."; - prefixCount = config.prefixCount || "stats_counts."; - prefixTimer = config.prefixTimer || "stats.timers."; - prefixGauge = config.prefixGauge || "stats.gauges."; + config.graphite = config.graphite || {}; + globalPrefix = config.graphite.globalPrefix || "stats"; + prefixCounter = config.graphite.prefixCounter || "counters"; + prefixTimer = config.graphite.prefixTimer || "timers"; + prefixGauge = config.graphite.prefixGauge || "gauges"; + + if (globalPrefix !== "") { + globalNamespace.push(globalPrefix); + counterNamespace.push(globalPrefix); + timerNamespace.push(globalPrefix); + gaugesNamespace.push(globalPrefix); + } + + if (prefixCounter !== "") { + counterNamespace.push(prefixCounter); + } + if (prefixTimer !== "") { + timerNamespace.push(prefixTimer); + } + if (prefixGauge !== "") { + gaugesNamespace.push(prefixGauge); + } graphiteStats.last_flush = startup_time; graphiteStats.last_exception = startup_time; diff --git a/exampleConfig.js b/exampleConfig.js index 41ec12a..871e9a0 100644 --- a/exampleConfig.js +++ b/exampleConfig.js @@ -44,10 +44,11 @@ Optional Variables: application: name of the application for syslog [string, default: statsd] level: log level for [node-]syslog [string, default: LOG_INFO] - prefixPersecond: graphite prefix for counter per second metrics [default: "statsd."] - prefixCount: graphite prefix for count metrics [default: "stats_counts."] - prefixTimer: graphite prefix for timer metrics [default: "stats.timers."] - prefixGauge: graphite prefix for gauge metrics [default: "stats.gauges."] + graphite: + globalPrefix: global prefix to use for sending stats to graphite [default: "stats"] + prefixCounter: graphite prefix for counter metrics [default: "counters"] + prefixTimer: graphite prefix for timer metrics [default: "timers"] + prefixGauge: graphite prefix for gauge metrics [default: "gauges"] */ { graphitePort: 2003