diff --git a/0.7-changes b/0.7-changes index 973de67..33d8aab 100644 --- a/0.7-changes +++ b/0.7-changes @@ -10,4 +10,6 @@ appenders now only need to provide configure function log4js.configure now only takes single argument (no options) tests use mocha not vows replaced my debug lib with tjholowaychuk's debug (more of a standard) -options.cwd removed - filenames should always be specified in full, not relative \ No newline at end of file +options.cwd removed - filenames should always be specified in full, not relative +loglevelfilter changed to accept a list of log levels it allows +appenders that wrap other appenders must reference them by name diff --git a/lib/appenders/logLevelFilter.js b/lib/appenders/logLevelFilter.js index ddbb61c..2aa89cb 100644 --- a/lib/appenders/logLevelFilter.js +++ b/lib/appenders/logLevelFilter.js @@ -1,21 +1,40 @@ "use strict"; var levels = require('../levels') +, debug = require('debug')('log4js:logLevelFilter') , log4js = require('../log4js'); -function logLevelFilter (levelString, appender) { - var level = levels.toLevel(levelString); +function logLevelFilter(allowedLevels, appender) { return function(logEvent) { - if (logEvent.level.isGreaterThanOrEqualTo(level)) { + debug("Checking ", logEvent.level, " against ", allowedLevels); + if (allowedLevels.some(function(item) { return item.level === logEvent.level.level; })) { + debug("Sending ", logEvent, " to appender ", appender); appender(logEvent); } }; } -function configure(config) { - log4js.loadAppender(config.appender.type); - var appender = log4js.appenderMakers[config.appender.type](config.appender); - return logLevelFilter(config.level, appender); +function configure(config, appenderByName) { + if (!Array.isArray(config.allow)) { + throw new Error("No allowed log levels specified."); + } + + var allowedLevels = config.allow.map(function(allowed) { + var level = levels.toLevel(allowed); + if (!level) { + throw new Error("Unrecognised log level '" + allowed + "'."); + } + return level; + }); + + if (allowedLevels.length === 0) { + throw new Error("No allowed log levels specified."); + } + + if (!config.appender) { + throw new Error("Missing an appender."); + } + + return logLevelFilter(allowedLevels, appenderByName(config.appender)); } -exports.appender = logLevelFilter; exports.configure = configure; diff --git a/lib/log4js.js b/lib/log4js.js index 511a54c..109fe3c 100644 --- a/lib/log4js.js +++ b/lib/log4js.js @@ -200,6 +200,14 @@ function clearAppenders () { appenders = {}; } +function appenderByName(name) { + if (appenders.hasOwnProperty(name)) { + return appenders[name]; + } else { + throw new Error("Appender '" + name + "' not found."); + } +} + function configureAppenders(appenderMap) { clearAppenders(); Object.keys(appenderMap).forEach(function(appenderName) { @@ -207,7 +215,7 @@ function configureAppenders(appenderMap) { loadAppender(appenderConfig.type); appenderConfig.makers = appenderMakers; try { - appenders[appenderName] = appenderMakers[appenderConfig.type](appenderConfig); + appenders[appenderName] = appenderMakers[appenderConfig.type](appenderConfig, appenderByName); } catch(e) { throw new Error("log4js configuration problem for appender '" + appenderName + "'. Error was " + e.stack); } diff --git a/test/logLevelFilter-test.js b/test/logLevelFilter-test.js index c976689..7eef8cd 100644 --- a/test/logLevelFilter-test.js +++ b/test/logLevelFilter-test.js @@ -1,16 +1,124 @@ "use strict"; -var vows = require('vows') -, fs = require('fs') -, assert = require('assert'); +var should = require('should') +, sandbox = require('sandboxed-module') +, log4js = require('../lib/log4js'); -function remove(filename) { - try { - fs.unlinkSync(filename); - } catch (e) { - //doesn't really matter if it failed - } -} +describe('log level filter', function() { + describe('when configured correctly', function() { + var events = [], logger; + before(function() { + var log4js_sandboxed = sandbox.require( + '../lib/log4js', + { requires: + { './appenders/console': + { configure: function() { return function(evt) { events.push(evt); }; } } + } + } + ); + log4js_sandboxed.configure({ + appenders: { + "console": { type: "console", layout: { type: "messagePassThrough" } }, + "errors only": { + type: "logLevelFilter", + allow: [ "ERROR", "FATAL" ], + appender: "console" + } + }, + categories: { + default: { level: "DEBUG", appenders: [ "errors only" ] } + } + }); + logger = log4js_sandboxed.getLogger("test"); + }); + + it('should pass events to an appender if they match', function() { + logger.error("oh no"); + logger.fatal("boom"); + + events.should.have.length(2); + events[0].data[0].should.eql("oh no"); + events[1].data[0].should.eql("boom"); + }); + + it('should not pass events to the appender if they do not match', function() { + events.should.have.length(2); + logger.debug("cheese"); + events.should.have.length(2); + logger.info("yawn"); + events.should.have.length(2); + }); + }); + + it('should complain if it has no appender', function() { + (function() { + log4js.configure({ + appenders: { + "errors": { + type: "logLevelFilter", + allow: [ "ERROR", "FATAL" ] + } + }, + categories: { + default: { level: "DEBUG", appenders: [ "errors" ] } + } + }); + }).should.throw(/Missing an appender\./); + }); + + it('should complain if it has no list of allowed levels', function() { + (function() { + log4js.configure({ + appenders: { + "console": { type: "console" }, + "errors": { + type: "logLevelFilter", + appender: "console" + } + }, + categories: { + default: { level: "DEBUG", appenders: [ "errors" ] } + } + }); + }).should.throw(/No allowed log levels specified\./); + }); + + it('should complain if the referenced appender does not exist', function() { + (function() { + log4js.configure({ + appenders: { + "errors": { + type: "logLevelFilter", + allow: [ "ERROR" ], + appender: "console" + } + }, + categories: { + default: { level: "DEBUG", appenders: [ "errors" ] } + } + }); + }).should.throw(/Appender 'console' not found\./); + }); + + it('should complain if the list of levels is not valid', function() { + (function() { + log4js.configure({ + appenders: { + "errors": { + type: "logLevelFilter", + allow: [ "cheese", "biscuits", "ERROR" ], + appender: { type: "console" } + } + }, + categories: { + default: { level: "DEBUG", appenders: [ "errors" ] } + } + }); + }).should.throw(/Unrecognised log level 'cheese'\./); + }); +}); + +/* vows.describe('log4js logLevelFilter').addBatch({ 'appender': { topic: function() { @@ -76,3 +184,4 @@ vows.describe('log4js logLevelFilter').addBatch({ } } }).export(module); +*/