chronos
Version:
Log cronjob results to graylog2
130 lines (109 loc) • 3.21 kB
JavaScript
var _ = require('underscore')._;
var exec = require('child_process').exec;
var Chronos = module.exports = {};
// some reasonable defaults, can be overwritten by /etc/chronos.json or /usr/local/etc/chronos.json
var defaults = {
mode: "graylog2",
amqp: {
host: '127.0.0.1',
port: 5672,
key: 'logging',
login: 'guest',
password: 'guest',
vhost: '/',
},
graylog2: {
host: '127.0.0.1',
port: 12201,
},
stage: false,
};
// nice environment settings formatting
// SOME_VAR: value
function getEnvSettings() {
return _.map(process.env, function(v, k) { return k + ': ' + v; }).join("\n");
};
// Overwrite default configuration, used by the binary
Chronos.configure = function(opts) {
defaults = _.extend(defaults, opts);
};
// run a job, cmdArray should contain exactly one element being the actual
Chronos.run = function(opts) {
// time in milliseconds the job was started at
var startTime = (new Date()).getTime();
var jobName = opts.jobname;
var stage = opts.stage;
var cmdString = opts.command;
// execute!
exec(cmdString, function(err, stdout, stderr) {
// extract exit code of the command
var exitCode = err === null ? 0 : err.code;
// time in milliseconds the job was finished
var endTime = (new Date()).getTime();
// construct GELF message
var message = {
facility: 'chronos',
level: exitCode === 0 ? 7 : 3, // success => debug (7), else: error (3)
short_message: 'Cronjob "' + jobName + '" ' + (exitCode === 0 ? 'was executed' : 'has failed'),
timestamp: ((new Date()).getTime() / 1000) >> 0,
_startTime: startTime,
_endTime: endTime,
_runTime: (endTime - startTime),
host: require('os').hostname(),
_eventType: 'cronjob',
version: '1.0',
_jobName: jobName,
_command: cmdString,
_exitCode: exitCode,
_user: process.env['USER'],
};
// more verbose information that may or may not be requested
stage = stage || defaults.stage;
if (stage) {
message._stage = stage;
}
if (opts.env) {
message._env = getEnvSettings();
}
if (opts.stdout) {
message._stdout = stdout;
}
if (opts.stderr) {
message._stderr = stderr;
}
var rawGELF = JSON.stringify(message);
// connect to AMQP server and publish the message
if (defaults.mode === 'amqp') {
var amqp = require('amqp');
var conn = amqp.createConnection(defaults.amqp);
conn.on('ready', function() {
conn.publish(defaults.amqp.key, rawGELF);
// kill connection after 10 milliseconds
setTimeout(function() {
conn.end();
}, 10);
});
} else if(defaults.mode === 'graylog2') {
var buffer = new Buffer(rawGELF);
require('zlib').deflate(buffer, function(err, compressedGELF) {
if (err) return;
if (compressedGELF.length > 8192) {
// TODO: chunked support, see: https://github.com/Graylog2/graylog2-docs/wiki/GELF
return;
}
var client = require('dgram').createSocket('udp4');
client.send(
compressedGELF,
0,
compressedGELF.length,
defaults.graylog2.port,
defaults.graylog2.host,
function(err, byteCount) {
console.log("Sent directly.");
client.close();
}
);
});
}
});
}