Merge pull request #357 from shakacode/add-loggly-tagged

Add new appender logglyTagged
This commit is contained in:
Gareth Jones 2016-03-09 10:44:23 +11:00
commit b1ae1218a6
2 changed files with 95 additions and 21 deletions

View File

@ -5,8 +5,46 @@ var layouts = require('../layouts')
, passThrough = layouts.messagePassThroughLayout;
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
function numKeys(o) {
var res = 0;
for (var k in o) {
if (o.hasOwnProperty(k)) res++;
}
return res;
}
/**
* Loggly Appender. Sends logging events to Loggly using node-loggly
* @param msg - array of args for logging.
* @returns { deTaggedMsg: [], additionalTags: [] }
*/
function processTags(msgListArgs) {
var msgList = (msgListArgs.length === 1 ? [msgListArgs[0]] : Array.apply(null, msgListArgs));
return msgList.reduce(function (accum, element, currentIndex, array) {
if (isAnyObject(element) && Array.isArray(element.tags) && numKeys(element) == 1) {
accum.additionalTags = accum.additionalTags.concat(element.tags);
} else {
accum.deTaggedData.push(element);
}
return accum;
}, { deTaggedData: [], additionalTags: [] });
}
/**
* Loggly Appender. Sends logging events to Loggly using node-loggly, optionally adding tags.
*
* This appender will scan the msg from the logging event, and pull out any argument of the
* shape `{ tags: [] }` so that it's possibleto add tags in a normal logging call.
*
* For example:
*
* logger.info({ tags: ['my-tag-1', 'my-tag-2'] }, 'Some message', someObj, ...)
*
* And then this appender will remove the tags param and append it to the config.tags.
*
* @param config object with loggly configuration data
* {
@ -21,13 +59,21 @@ function logglyAppender(config, layout) {
if(!layout) layout = passThrough;
return function(loggingEvent) {
var msg = layout(loggingEvent);
var result = processTags(loggingEvent.data);
var deTaggedData = result.deTaggedData;
var additionalTags = result.additionalTags;
// Replace the data property with the deTaggedData
loggingEvent.data = deTaggedData;
var msg = layout(loggingEvent);
client.log({
msg: msg,
level: loggingEvent.level.levelStr,
category: loggingEvent.categoryName,
hostname: os.hostname().toString(),
});
}, additionalTags);
}
}

View File

@ -1,18 +1,18 @@
"use strict";
var vows = require('vows')
, assert = require('assert')
, log4js = require('../lib/log4js')
, sandbox = require('sandboxed-module')
;
, assert = require('assert')
, log4js = require('../lib/log4js')
, sandbox = require('sandboxed-module')
;
function setupLogging(category, options) {
var msgs = [];
var fakeLoggly = {
createClient: function (options) {
createClient: function(options) {
return {
config: options,
log: function (msg, tags) {
log: function(msg, tags) {
msgs.push({
msg: msg,
tags: tags
@ -50,7 +50,7 @@ function setupLogging(category, options) {
});
log4js.addAppender(logglyModule.configure(options), category);
return {
logger: log4js.getLogger(category),
loggly: fakeLoggly,
@ -61,22 +61,50 @@ function setupLogging(category, options) {
}
log4js.clearAppenders();
function setupTaggedLogging() {
return setupLogging('loggly', {
token: 'your-really-long-input-token',
subdomain: 'your-subdomain',
tags: ['loggly-tag1', 'loggly-tag2', 'loggly-tagn']
});
}
vows.describe('log4js logglyAppender').addBatch({
'minimal config': {
'with minimal config': {
topic: function() {
var setup = setupLogging('loggly', {
token: 'your-really-long-input-token',
subdomain: 'your-subdomain',
tags: ['loggly-tag1', 'loggly-tag2', 'loggly-tagn']
});
setup.logger.log('trace', 'Log event #1');
var setup = setupTaggedLogging();
setup.logger.log('trace', 'Log event #1', 'Log 2', { tags: ['tag1', 'tag2'] });
return setup;
},
'there should be one message only': function (topic) {
//console.log('topic', topic);
'has a results.length of 1': function(topic) {
assert.equal(topic.results.length, 1);
},
'has a result msg with both args concatenated': function(topic) {
assert.equal(topic.results[0].msg.msg, 'Log event #1 Log 2');
},
'has a result tags with the arg that contains tags': function(topic) {
assert.deepEqual(topic.results[0].tags, ['tag1', 'tag2']);
}
}
}).addBatch({
'config with object with tags and other keys': {
topic: function() {
var setup = setupTaggedLogging();
// ignore this tags object b/c there are 2 keys
setup.logger.log('trace', 'Log event #1', { other: 'other', tags: ['tag1', 'tag2'] });
return setup;
},
'has a results.length of 1': function(topic) {
assert.equal(topic.results.length, 1);
},
'has a result msg with the args concatenated': function(topic) {
assert.equal(topic.results[0].msg.msg,
'Log event #1 { other: \'other\', tags: [ \'tag1\', \'tag2\' ] }');
},
'has a result tags with the arg that contains no tags': function(topic) {
assert.deepEqual(topic.results[0].tags, []);
}
}
}).export(module);