diff --git a/lib/appenders/categoryFilter.js b/lib/appenders/categoryFilter.js new file mode 100644 index 0000000..7a35624 --- /dev/null +++ b/lib/appenders/categoryFilter.js @@ -0,0 +1,24 @@ +var levels = require('../levels'); +var log4js = require('../log4js'); + +function contains(list, value) { + return list.indexOf(value) !== -1; +} + +function categoryFilter (excludes, appender) { + if (typeof(excludes) === 'string') excludes = [excludes]; + return function(logEvent) { + if (excludes.indexOf(logEvent.categoryName) === -1) { + appender(logEvent); + } + } +} + +function configure(config) { + log4js.loadAppender(config.appender.type); + var appender = log4js.appenderMakers[config.appender.type](config.appender); + return categoryFilter(config.exclude, appender); +} + +exports.appender = categoryFilter; +exports.configure = configure; diff --git a/test/categoryFilter-test.js b/test/categoryFilter-test.js new file mode 100644 index 0000000..30dd42d --- /dev/null +++ b/test/categoryFilter-test.js @@ -0,0 +1,79 @@ +'use strict'; + +var vows = require('vows') +, fs = require('fs') +, assert = require('assert'); + +function remove(filename) { + try { + fs.unlinkSync(filename); + } catch (e) { + //doesn't really matter if it failed + } +} + +vows.describe('log4js categoryFilter').addBatch({ + 'appender': { + topic: function() { + + var log4js = require('../lib/log4js'), logEvents = [], webLogger, appLogger; + log4js.clearAppenders(); + var appender = require('../lib/appenders/categoryFilter').appender(['app'], function(evt) { logEvents.push(evt); }); + log4js.addAppender(appender, ["app","web"]); + + webLogger = log4js.getLogger("web"); + appLogger = log4js.getLogger("app"); + + webLogger.debug('This should get logged'); + appLogger.debug('This should not'); + webLogger.debug('Hello again'); + log4js.getLogger('db').debug('This shouldn\'t be included by the appender anyway'); + + return logEvents; + }, + 'should only pass matching category' : function(logEvents) { + assert.equal(logEvents.length, 2); + assert.equal(logEvents[0].data[0], 'This should get logged'); + assert.equal(logEvents[1].data[0], 'Hello again'); + } + }, + + 'configure': { + topic: function() { + var log4js = require('../lib/log4js') + , logger, weblogger; + + remove(__dirname + '/categoryFilter-web.log'); + remove(__dirname + '/categoryFilter-noweb.log'); + + log4js.configure('test/with-categoryFilter.json'); + logger = log4js.getLogger("app"); + weblogger = log4js.getLogger("web"); + + logger.info('Loading app'); + logger.debug('Initialising indexes'); + weblogger.info('00:00:00 GET / 200'); + weblogger.warn('00:00:00 GET / 500'); + //wait for the file system to catch up + setTimeout(this.callback, 100); + }, + 'tmp-tests.log': { + topic: function() { + fs.readFile(__dirname + '/categoryFilter-noweb.log', 'utf8', this.callback); + }, + 'should contain all log messages': function(contents) { + var messages = contents.trim().split('\n'); + assert.deepEqual(messages, ['Loading app','Initialising indexes']); + } + }, + 'tmp-tests-web.log': { + topic: function() { + fs.readFile(__dirname + '/categoryFilter-web.log','utf8',this.callback); + }, + 'should contain only error and warning log messages': function(contents) { + var messages = contents.trim().split('\n'); + assert.deepEqual(messages, ['00:00:00 GET / 200','00:00:00 GET / 500']); + } + } + } +}).export(module); diff --git a/test/with-categoryFilter.json b/test/with-categoryFilter.json new file mode 100644 index 0000000..7998cc8 --- /dev/null +++ b/test/with-categoryFilter.json @@ -0,0 +1,23 @@ +{ + "appenders": [ + { + "type": "categoryFilter", + "exclude": "web", + "appender": { + "type": "file", + "filename": "test/categoryFilter-noweb.log", + "layout": { + "type": "messagePassThrough" + } + } + }, + { + "category": "web", + "type": "file", + "filename": "test/categoryFilter-web.log", + "layout": { + "type": "messagePassThrough" + } + } + ] +}