Merge pull request #140 from karlvlam/master

Add custom field support to GELF appender
This commit is contained in:
Gareth Jones 2013-07-07 16:17:23 -07:00
commit 46721465a1
2 changed files with 88 additions and 3 deletions

View File

@ -34,22 +34,61 @@ levelMapping[levels.FATAL] = LOG_CRIT;
* @param hostname - hostname of the current host (default:os hostname) * @param hostname - hostname of the current host (default:os hostname)
* @param facility - facility to log to (default:nodejs-server) * @param facility - facility to log to (default:nodejs-server)
*/ */
function gelfAppender (layout, host, port, hostname, facility) { function gelfAppender (layout, host, port, hostname, facility, customFields) {
host = host || 'localhost'; host = host || 'localhost';
port = port || 12201; port = port || 12201;
hostname = hostname || require('os').hostname(); hostname = hostname || require('os').hostname();
facility = facility || 'nodejs-server'; facility = facility || 'nodejs-server';
layout = layout || layouts.messagePassThroughLayout; layout = layout || layouts.messagePassThroughLayout;
var defaultCustomFields = customFields || {};
var client = dgram.createSocket("udp4"); var client = dgram.createSocket("udp4");
process.on('exit', function() { process.on('exit', function() {
if (client) client.close(); if (client) client.close();
}); });
/**
* Add custom fields (start with underscore )
* - if the first object passed to the logger contains 'GELF' field, add copy the underscore fields to the message
* @param loggingEvent
* @param msg
*/
function addCustomFields(loggingEvent, msg){
/* append defaultCustomFields firsts */
var keys = Object.keys(defaultCustomFields);
for (var i in keys){
var key = keys[i];
// skip _id field for graylog2, skip keys not starts with UNDERSCORE
if (!key.match(/^_/) || key === "_id") continue;
msg[key] = defaultCustomFields[key];
}
/* append custom fields per message */
var data = loggingEvent.data;
if (!Array.isArray(data) || data.length === 0) return;
var firstData = data[0];
if (!firstData['GELF']) return; // identify with GELF field defined
var keys = Object.keys(firstData);
for (var i in keys){
var key = keys[i];
// skip _id field for graylog2, skip keys not starts with UNDERSCORE
if (!key.match(/^_/) || key === "_id") continue;
msg[key] = firstData[key];
}
/* the custom field object should be removed, so it will not be looged by the later appenders */
loggingEvent.data.shift();
}
function preparePacket(loggingEvent) { function preparePacket(loggingEvent) {
var msg = {}; var msg = {};
addCustomFields(loggingEvent, msg);
msg.full_message = layout(loggingEvent); msg.full_message = layout(loggingEvent);
msg.short_message = msg.full_message; msg.short_message = msg.full_message;
@ -88,7 +127,7 @@ function configure(config) {
if (config.layout) { if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout); layout = layouts.layout(config.layout.type, config.layout);
} }
return gelfAppender(layout, config.host, config.port, config.hostname, config.facility); return gelfAppender(layout, config.host, config.port, config.hostname, config.facility, config.customFields);
} }
exports.appender = gelfAppender; exports.appender = gelfAppender;

View File

@ -135,5 +135,51 @@ vows.describe('log4js gelfAppender').addBatch({
assert.equal(message.facility, 'nonsense'); assert.equal(message.facility, 'nonsense');
} }
} }
},
'with custom fields options': {
topic: function() {
var setup = setupLogging({
host: 'somewhere',
port: 12345,
hostname: 'cheese',
facility: 'nonsense',
customFields: {
_every1: 'Hello every one',
_every2: 'Hello every two'
}
});
var myFields = {
GELF: true,
_every2: 'Overwritten!',
_myField: 'This is my field!'
};
setup.logger.debug(myFields, "Just testing.");
return setup;
},
'the dgram packet': {
topic: function(setup) {
return setup.dgram;
},
'should pick up the options': function(dgram) {
assert.equal(dgram.socket.host, 'somewhere');
assert.equal(dgram.socket.port, 12345);
}
},
'the uncompressed packet': {
topic: function(setup) {
var message = JSON.parse(setup.compress.uncompressed);
return message;
},
'should pick up the options': function(message) {
assert.equal(message.host, 'cheese');
assert.equal(message.facility, 'nonsense');
assert.equal(message._every1, 'Hello every one'); // the default value
assert.equal(message._every2, 'Overwritten!'); // the overwritten value
assert.equal(message._myField, 'This is my field!'); // the value for this message only
assert.equal(message.short_message, 'Just testing.'); // skip the field object
assert.equal(message.full_message, 'Just testing.'); // should be as same as short_message
}
}
} }
}).export(module); }).export(module);