Allow adding of appenders as objects

Previously, appenders could only be added by specifying the filepath
to the appender. This required the appender's path to be specified
either relative to the log4js installation, relative to a NODE_PATH
token, or absolute. This creates a coupling between the log4js
configurer and the log4js installation location, or a coupling between
the log4js configurer and the global NODE_PATH. This commit removes
the coupling by allowing the loading of appenders to be done relative
to the log4js configurer.
This commit is contained in:
John Engler 2014-03-11 02:07:58 -07:00
parent 83ad0babf3
commit 28f7c87a0e
2 changed files with 47 additions and 1 deletions

View File

@ -290,13 +290,44 @@ function restoreConsole() {
}); });
} }
function loadAppender(appender) { /**
* Load an appenderModule based on the provided appender filepath. Will first
* check if the appender path is a subpath of the log4js "lib/appenders" directory.
* If not, it will attempt to load the the appender as complete path.
*
* @param {string} appender The filepath for the appender.
* @returns {Object|null} The required appender or null if appender could not be loaded.
* @private
*/
function requireAppender(appender) {
var appenderModule; var appenderModule;
try { try {
appenderModule = require('./appenders/' + appender); appenderModule = require('./appenders/' + appender);
} catch (e) { } catch (e) {
appenderModule = require(appender); appenderModule = require(appender);
} }
return appenderModule;
}
/**
* Load an appender. Provided the appender path to be loaded. If appenderModule is defined,
* it will be used in place of requiring the appender module.
*
* @param {string} appender The path to the appender module.
* @param {Object|void} [appenderModule] The pre-required appender module. When provided,
* instead of requiring the appender by its path, this object will be used.
* @returns {void}
* @private
*/
function loadAppender(appender, appenderModule) {
if (!appenderModule) {
appenderModule = requireAppender(appender);
}
if (!appenderModule) {
throw new Error("Invalid log4js appender: " + util.inspect(appender));
}
module.exports.appenders[appender] = appenderModule.appender.bind(appenderModule); module.exports.appenders[appender] = appenderModule.appender.bind(appenderModule);
appenderMakers[appender] = appenderModule.configure.bind(appenderModule); appenderMakers[appender] = appenderModule.configure.bind(appenderModule);
} }

View File

@ -86,6 +86,21 @@ vows.describe('log4js configure').addBatch({
assert.isFunction(log4js.appenderMakers['some/other/external']); assert.isFunction(log4js.appenderMakers['some/other/external']);
} }
}, },
'when appender object loaded via loadAppender': {
topic: function() {
var testAppender = makeTestAppender(),
log4js = sandbox.require('../lib/log4js');
log4js.loadAppender('some/other/external', testAppender);
return log4js;
},
'should load appender with provided object': function(log4js) {
assert.ok(log4js.appenders['some/other/external']);
},
'should add appender configure function to appenderMakers': function(log4js) {
assert.isFunction(log4js.appenderMakers['some/other/external']);
}
},
'when configuration file loaded via LOG4JS_CONFIG environment variable': { 'when configuration file loaded via LOG4JS_CONFIG environment variable': {
topic: function() { topic: function() {
process.env.LOG4JS_CONFIG = 'some/path/to/mylog4js.json'; process.env.LOG4JS_CONFIG = 'some/path/to/mylog4js.json';