Created
January 26, 2014 07:54
-
-
Save jiangzhuo/8629821 to your computer and use it in GitHub Desktop.
statsd-zabbix-backend with timer_data instead of timers, sometime timer_data is enough
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Flush stats to zabbix (http://www.zabbix.com/). | |
* | |
* To enable this backend, include 'statsd-zabbix-backend' | |
* in the backends * configuration array: | |
* | |
* backends: ['statsd-zabbix-backend'] | |
* | |
* This backend supports the following config options: | |
* | |
* zabbixHost: Hostname of zabbix server. | |
* zabbixPort: Port to contact zabbix server at. | |
* zabbixSender: Path to zabbix_sender utility. | |
* | |
*/ | |
var util = require('util'), | |
proc = require('child_process'); | |
var debug; | |
var flushInterval; | |
var zabbixHost; | |
var zabbixPort; | |
var zabbixSender; | |
var zabbixStats = {}; | |
var post_stats = function zabbix_post_stats(statString) { | |
if (zabbixHost) { | |
if (debug) { | |
util.log(statString); | |
} | |
try { | |
var zabbixExec = proc.exec(zabbixCmd, function(error, stdout, stderr) { | |
if (error) { | |
throw error; | |
} | |
}); | |
zabbixExec.stdin.write(statString); | |
zabbixExec.stdin.end(); | |
} catch(e){ | |
if (debug) { | |
util.log(e); | |
} | |
zabbixStats.last_exception = Math.round(new Date().getTime() / 1000); | |
} | |
} | |
} | |
var zabbix_host_key = function (key) { | |
// Logstash uses a . separator, but what is standard? | |
var host_key = key.split('.'); | |
// Handle a namespace in front of host.key | |
if (host_key.length === 3) { | |
var namespace = host_key[0]; | |
var host = host_key[1]; | |
var key = host_key[2]; | |
// Replace underscores with periods | |
if (namespace === "logstash") { | |
host = host.replace(/_/g, '.'); | |
// Recompile the key from whatever is after logstash.source_host | |
key = host_key.slice(2).join('.'); | |
// Kept for backwards compatibility, should not cause issues | |
key = key.replace(/_/g, '.'); | |
} | |
} else { | |
// Split on host_key by default separator | |
host_key = key.split('_'); | |
var host = host_key[0]; | |
var key = host_key[1]; | |
} | |
return { | |
'host': host, | |
'key': key | |
} | |
} | |
var flush_stats = function zabbix_flush(ts, metrics) { | |
var statString = ''; | |
var numStats = 0; | |
var key; | |
var zabbix; | |
var counters = metrics.counters; | |
var gauges = metrics.gauges; | |
var timer_data = metrics.timer_data; | |
var pctThreshold = metrics.pctThreshold; | |
for (key in counters) { | |
var value = counters[key]; | |
var valuePerSecond = value / (flushInterval / 1000); // calculate "per second" rate | |
zabbix = zabbix_host_key(key); | |
statString += zabbix.host + ' ' + zabbix.key + '[total] ' + ts + ' ' + value + "\n"; | |
statString += zabbix.host + ' ' + zabbix.key + '[avg] ' + ts + ' ' + valuePerSecond + "\n"; | |
numStats += 1; | |
} | |
for (key in timer_data) { | |
var message = ""; | |
var key2; | |
zabbix = zabbix_host_key(key); | |
for (key2 in pctThreshold) { | |
var pct = pctThreshold[key2]; | |
message += zabbix.host + ' ' + zabbix.key + '[mean][' + pct + '] ' + ts + ' ' + timer_data[key]["mean_"+pct] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[upper][' + pct + '] ' + ts + ' ' + timer_data[key]["upper_"+pct] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[upper][' + pct + '] ' + ts + ' ' + timer_data[key]["sum_"+pct] + "\n"; | |
} | |
message += zabbix.host + ' ' + zabbix.key + '[std] ' + ts + ' ' + timer_data[key]["std"] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[upper] ' + ts + ' ' + timer_data[key]["upper"] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[lower] ' + ts + ' ' + timer_data[key]["lower"] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[count] ' + ts + ' ' + timer_data[key]["count"] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[count_ps] ' + ts + ' ' + timer_data[key]["count_ps"] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[sum] ' + ts + ' ' + timer_data[key]["sum"] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[mean] ' + ts + ' ' + timer_data[key]["mean"] + "\n"; | |
message += zabbix.host + ' ' + zabbix.key + '[median] ' + ts + ' ' + timer_data[key]["median"] + "\n"; | |
statString += message; | |
numStats += 1; | |
} | |
for (key in gauges) { | |
zabbix = zabbix_host_key(key); | |
statString += zabbix.host + ' ' + zabbix.key + ' ' + ts + ' ' + gauges[key] + "\n"; | |
numStats += 1; | |
} | |
post_stats(statString); | |
}; | |
var backend_status = function zabbix_status(writeCb) { | |
for (stat in zabbixStats) { | |
writeCb(null, 'zabbix', stat, zabbixStats[stat]); | |
} | |
}; | |
exports.init = function zabbix_init(startup_time, config, events) { | |
debug = config.debug; | |
zabbixHost = config.zabbixHost; | |
zabbixPort = config.zabbixPort; | |
zabbixSender = config.zabbixSender; | |
zabbixCmd = zabbixSender + ' -T -i - -z ' + zabbixHost + ' -p ' + zabbixPort; | |
zabbixStats.last_flush = startup_time; | |
zabbixStats.last_exception = startup_time; | |
flushInterval = config.flushInterval; | |
events.on('flush', flush_stats); | |
events.on('status', backend_status); | |
return true; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment