Skip to content

Instantly share code, notes, and snippets.

@jiangzhuo
Created January 26, 2014 07:54
Show Gist options
  • Save jiangzhuo/8629821 to your computer and use it in GitHub Desktop.
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
/*
* 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