Added functionality to reload configuration file periodically.

date-rolling-file-appender
Daniel Bell 13 years ago
parent ec21ec63f0
commit 69e64932b1

@ -52,7 +52,10 @@ Output:
You can either configure the appenders and log levels manually (as above), or provide a You can either configure the appenders and log levels manually (as above), or provide a
configuration file (`log4js.configure('path/to/file.json')`) explicitly, or just let log4js look for a file called `log4js.json` (it looks in the current directory first, then the require paths, and finally looks for the default config included in the same directory as the `log4js.js` file). configuration file (`log4js.configure('path/to/file.json')`) explicitly, or just let log4js look for a file called `log4js.json` (it looks in the current directory first, then the require paths, and finally looks for the default config included in the same directory as the `log4js.js` file).
An example file can be found in `test/log4js.json`. An example config file with log rolling is in `test/with-log-rolling.json` An example file can be found in `test/log4js.json`. An example config file with log rolling is in `test/with-log-rolling.json`.
By default, the configuration file is checked for changes every 60 seconds, and if changed, reloaded. This allows changes to logging levels
to occur without restarting the application.
You can also pass an object to the configure function, which has the same properties as the json versions. You can also pass an object to the configure function, which has the same properties as the json versions.
## connect/express logger ## connect/express logger

@ -56,22 +56,22 @@ var events = require('events')
, loggers = {} , loggers = {}
, appenderMakers = { , appenderMakers = {
"file": function(config, fileAppender) { "file": function(config, fileAppender) {
var layout; var layout;
if (config.layout) { if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout); layout = layouts.layout(config.layout.type, config.layout);
} }
return fileAppender(config.filename, layout, config.maxLogSize, config.backups, config.pollInterval); return fileAppender(config.filename, layout, config.maxLogSize, config.backups, config.pollInterval);
}, },
"console": function(config, fileAppender, consoleAppender) { "console": function(config, fileAppender, consoleAppender) {
var layout; var layout;
if (config.layout) { if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout); layout = layouts.layout(config.layout.type, config.layout);
} }
return consoleAppender(layout); return consoleAppender(layout);
}, },
"logLevelFilter": function(config, fileAppender, consoleAppender) { "logLevelFilter": function(config, fileAppender, consoleAppender) {
var appender = appenderMakers[config.appender.type](config.appender, fileAppender, consoleAppender); var appender = appenderMakers[config.appender.type](config.appender, fileAppender, consoleAppender);
return logLevelFilter(config.level, appender); return logLevelFilter(config.level, appender);
} }
}; };
@ -85,25 +85,25 @@ function getLogger (categoryName) {
// Use default logger if categoryName is not specified or invalid // Use default logger if categoryName is not specified or invalid
if (!(typeof categoryName == "string")) { if (!(typeof categoryName == "string")) {
categoryName = DEFAULT_CATEGORY; categoryName = DEFAULT_CATEGORY;
} }
var appenderList; var appenderList;
if (!loggers[categoryName]) { if (!loggers[categoryName]) {
// Create the logger for this name if it doesn't already exist // Create the logger for this name if it doesn't already exist
loggers[categoryName] = new Logger(categoryName); loggers[categoryName] = new Logger(categoryName);
if (appenders[categoryName]) { if (appenders[categoryName]) {
appenderList = appenders[categoryName]; appenderList = appenders[categoryName];
appenderList.forEach(function(appender) { appenderList.forEach(function(appender) {
loggers[categoryName].addListener("log", appender); loggers[categoryName].addListener("log", appender);
}); });
} }
if (appenders[ALL_CATEGORIES]) { if (appenders[ALL_CATEGORIES]) {
appenderList = appenders[ALL_CATEGORIES]; appenderList = appenders[ALL_CATEGORIES];
appenderList.forEach(function(appender) { appenderList.forEach(function(appender) {
loggers[categoryName].addListener("log", appender); loggers[categoryName].addListener("log", appender);
}); });
} }
} }
return loggers[categoryName]; return loggers[categoryName];
@ -116,63 +116,67 @@ function addAppender () {
var args = Array.prototype.slice.call(arguments); var args = Array.prototype.slice.call(arguments);
var appender = args.shift(); var appender = args.shift();
if (args.length == 0 || args[0] === undefined) { if (args.length == 0 || args[0] === undefined) {
args = [ ALL_CATEGORIES ]; args = [ ALL_CATEGORIES ];
} }
//argument may already be an array //argument may already be an array
if (Array.isArray(args[0])) { if (Array.isArray(args[0])) {
args = args[0]; args = args[0];
} }
args.forEach(function(category) { args.forEach(function(category) {
if (!appenders[category]) { if (!appenders[category]) {
appenders[category] = []; appenders[category] = [];
} }
appenders[category].push(appender); appenders[category].push(appender);
if (category === ALL_CATEGORIES) { if (category === ALL_CATEGORIES) {
for (var logger in loggers) { for (var logger in loggers) {
if (loggers.hasOwnProperty(logger)) { if (loggers.hasOwnProperty(logger)) {
loggers[logger].addListener("log", appender); loggers[logger].addListener("log", appender);
} }
} }
} else if (loggers[category]) { } else if (loggers[category]) {
loggers[category].addListener("log", appender); loggers[category].addListener("log", appender);
} }
}); });
} }
function clearAppenders () { function clearAppenders () {
appenders = {}; appenders = {};
for (var logger in loggers) { for (var logger in loggers) {
if (loggers.hasOwnProperty(logger)) { if (loggers.hasOwnProperty(logger)) {
loggers[logger].removeAllListeners("log"); loggers[logger].removeAllListeners("log");
} }
} }
} }
function configureAppenders(appenderList, fileAppender, consoleAppender) { function configureAppenders(appenderList, fileAppender, consoleAppender) {
clearAppenders(); clearAppenders();
if (appenderList) { if (appenderList) {
appenderList.forEach(function(appenderConfig) { appenderList.forEach(function(appenderConfig) {
var appender = appenderMakers[appenderConfig.type](appenderConfig, fileAppender, consoleAppender); var appender = appenderMakers[appenderConfig.type](appenderConfig, fileAppender, consoleAppender);
if (appender) { if (appender) {
addAppender(appender, appenderConfig.category); addAppender(appender, appenderConfig.category);
} else { } else {
throw new Error("log4js configuration problem for "+sys.inspect(appenderConfig)); throw new Error("log4js configuration problem for "+sys.inspect(appenderConfig));
} }
}); });
} else { } else {
addAppender(consoleAppender); addAppender(consoleAppender);
} }
} }
function configureLevels(levels) { function configureLevels(levels) {
if (levels) { if (levels) {
for (var category in levels) { for (var category in levels) {
if (levels.hasOwnProperty(category)) { if (levels.hasOwnProperty(category)) {
getLogger(category).setLevel(levels[category]); getLogger(category).setLevel(levels[category]);
} }
} }
} else {
for (l in loggers) {
loggers[l].setLevel();
}
} }
} }
@ -230,18 +234,18 @@ Logger.prototype.isLevelEnabled = function(otherLevel) {
['Trace','Debug','Info','Warn','Error','Fatal'].forEach( ['Trace','Debug','Info','Warn','Error','Fatal'].forEach(
function(levelString) { function(levelString) {
var level = levels.toLevel(levelString); var level = levels.toLevel(levelString);
Logger.prototype['is'+levelString+'Enabled'] = function() { Logger.prototype['is'+levelString+'Enabled'] = function() {
return this.isLevelEnabled(level); return this.isLevelEnabled(level);
}; };
Logger.prototype[levelString.toLowerCase()] = function () { Logger.prototype[levelString.toLowerCase()] = function () {
if (this.isLevelEnabled(level)) { if (this.isLevelEnabled(level)) {
var args = Array.prototype.slice.call(arguments); var args = Array.prototype.slice.call(arguments);
args.unshift(level); args.unshift(level);
Logger.prototype.log.apply(this, args); Logger.prototype.log.apply(this, args);
} }
}; };
} }
); );
@ -261,9 +265,9 @@ function getDefaultLogger () {
function logLevelFilter (levelString, appender) { function logLevelFilter (levelString, appender) {
var level = levels.toLevel(levelString); var level = levels.toLevel(levelString);
return function(logEvent) { return function(logEvent) {
if (logEvent.level.isGreaterThanOrEqualTo(level)) { if (logEvent.level.isGreaterThanOrEqualTo(level)) {
appender(logEvent); appender(logEvent);
} }
} }
} }
@ -271,7 +275,7 @@ function logLevelFilter (levelString, appender) {
function consoleAppender (layout) { function consoleAppender (layout) {
layout = layout || layouts.colouredLayout; layout = layout || layouts.colouredLayout;
return function(loggingEvent) { return function(loggingEvent) {
console._preLog4js_log(layout(loggingEvent)); console._preLog4js_log(layout(loggingEvent));
}; };
} }
@ -298,7 +302,7 @@ function fileAppender (file, layout, logSize, numBackups, filePollInterval) {
}); });
return function(loggingEvent) { return function(loggingEvent) {
logFile.write(layout(loggingEvent)+'\n'); logFile.write(layout(loggingEvent)+'\n');
}; };
} }
@ -343,21 +347,6 @@ function fileExists (filename) {
} }
} }
function configure (configurationFileOrObject) {
var config = configurationFileOrObject;
if (typeof(config) === "string") {
config = JSON.parse(fs.readFileSync(config, "utf8"));
}
if (config) {
try {
configureAppenders(config.appenders, fileAppender, consoleAppender);
configureLevels(config.levels);
} catch (e) {
throw new Error("Problem reading log4js config " + sys.inspect(config) + ". Error was \"" + e.message + "\" ("+e.stack+")");
}
}
}
function findConfiguration() { function findConfiguration() {
//add current directory onto the list of configPaths //add current directory onto the list of configPaths
var paths = ['.'].concat(require.paths); var paths = ['.'].concat(require.paths);
@ -377,6 +366,79 @@ function findConfiguration() {
return undefined; return undefined;
} }
function loadConfigurationFile(filename) {
filename = filename || findConfiguration();
if (filename) {
return JSON.parse(fs.readFileSync(filename, "utf8"));
}
return undefined;
}
function configureOnceOff(config) {
if (config) {
try {
configureAppenders(config.appenders, fileAppender, consoleAppender);
configureLevels(config.levels);
} catch (e) {
throw new Error("Problem reading log4js config " + sys.inspect(config) + ". Error was \"" + e.message + "\" ("+e.stack+")");
}
}
}
var configState = {};
function reloadConfiguration() {
var filename = configState.filename || findConfiguration(),
mtime;
if (!filename) {
// can't find anything to reload
return;
}
try {
mtime = fs.statSync(filename).mtime;
} catch (e) {
getLogger('log4js').warn('Failed to load configuration file ' + filename);
return;
}
if (configState.lastFilename && configState.lastFilename === filename) {
if (mtime.getTime() > configState.lastMTime.getTime()) {
configState.lastMTime = mtime;
} else {
filename = null;
}
} else {
configState.lastFilename = filename;
configState.lastMTime = mtime;
}
configureOnceOff(loadConfigurationFile(filename));
}
function initReloadConfiguration(filename, options) {
if (configState.timerId) {
clearInterval(configState.timerId);
delete configState.timerId;
}
configState.filename = filename;
configState.timerId = setInterval(reloadConfiguration, options.reloadSecs*1000);
}
function configure (configurationFileOrObject, options) {
var config = configurationFileOrObject;
if (config === undefined || config === null || typeof(config) === 'string') {
options = options || { reloadSecs: 60 };
if (options.reloadSecs) {
initReloadConfiguration(config, options);
}
configureOnceOff(loadConfigurationFile(config));
} else {
options = options || {};
if (options.reloadSecs) {
getLogger('log4js').warn('Ignoring configuration reload parameter for "object" configuration.');
}
configureOnceOff(config);
}
}
function replaceConsole(logger) { function replaceConsole(logger) {
function replaceWith(fn) { function replaceWith(fn) {
return function() { return function() {

@ -4,82 +4,82 @@ var vows = require('vows')
vows.describe('log4js').addBatch({ vows.describe('log4js').addBatch({
'getLogger': { 'getLogger': {
topic: function() { topic: function() {
var log4js = require('../lib/log4js'); var log4js = require('../lib/log4js');
log4js.clearAppenders(); log4js.clearAppenders();
var logger = log4js.getLogger('tests'); var logger = log4js.getLogger('tests');
logger.setLevel("DEBUG"); logger.setLevel("DEBUG");
return logger; return logger;
}, },
'should take a category and return a logger': function(logger) { 'should take a category and return a logger': function(logger) {
assert.equal(logger.category, 'tests'); assert.equal(logger.category, 'tests');
assert.equal(logger.level.toString(), "DEBUG"); assert.equal(logger.level.toString(), "DEBUG");
assert.isFunction(logger.debug); assert.isFunction(logger.debug);
assert.isFunction(logger.info); assert.isFunction(logger.info);
assert.isFunction(logger.warn); assert.isFunction(logger.warn);
assert.isFunction(logger.error); assert.isFunction(logger.error);
assert.isFunction(logger.fatal); assert.isFunction(logger.fatal);
}, },
'log events' : { 'log events' : {
topic: function(logger) { topic: function(logger) {
var events = []; var events = [];
logger.addListener("log", function (logEvent) { events.push(logEvent); }); logger.addListener("log", function (logEvent) { events.push(logEvent); });
logger.debug("Debug event"); logger.debug("Debug event");
logger.trace("Trace event 1"); logger.trace("Trace event 1");
logger.trace("Trace event 2"); logger.trace("Trace event 2");
logger.warn("Warning event"); logger.warn("Warning event");
logger.error("Aargh!", new Error("Pants are on fire!")); logger.error("Aargh!", new Error("Pants are on fire!"));
logger.error("Simulated CouchDB problem", { err: 127, cause: "incendiary underwear" }); logger.error("Simulated CouchDB problem", { err: 127, cause: "incendiary underwear" });
return events; return events;
}, },
'should emit log events': function(events) { 'should emit log events': function(events) {
assert.equal(events[0].level.toString(), 'DEBUG'); assert.equal(events[0].level.toString(), 'DEBUG');
assert.equal(events[0].data[0], 'Debug event'); assert.equal(events[0].data[0], 'Debug event');
assert.instanceOf(events[0].startTime, Date); assert.instanceOf(events[0].startTime, Date);
}, },
'should not emit events of a lower level': function(events) { 'should not emit events of a lower level': function(events) {
assert.length(events, 4); assert.length(events, 4);
assert.equal(events[1].level.toString(), 'WARN'); assert.equal(events[1].level.toString(), 'WARN');
}, },
'should include the error if passed in': function (events) { 'should include the error if passed in': function (events) {
assert.instanceOf(events[2].data[1], Error); assert.instanceOf(events[2].data[1], Error);
assert.equal(events[2].data[1].message, 'Pants are on fire!'); assert.equal(events[2].data[1].message, 'Pants are on fire!');
} }
}, },
}, },
'fileAppender': { 'fileAppender': {
topic: function() { topic: function() {
var appender var appender
, logmessages = [] , logmessages = []
, thing = "thing" , thing = "thing"
, fakeFS = { , fakeFS = {
createWriteStream: function() { createWriteStream: function() {
assert.equal(arguments[0], './tmp-tests.log'); assert.equal(arguments[0], './tmp-tests.log');
assert.isObject(arguments[1]); assert.isObject(arguments[1]);
assert.equal(arguments[1].flags, 'a'); assert.equal(arguments[1].flags, 'a');
assert.equal(arguments[1].mode, 0644); assert.equal(arguments[1].mode, 0644);
assert.equal(arguments[1].encoding, 'utf8'); assert.equal(arguments[1].encoding, 'utf8');
return { return {
write: function(message) { write: function(message) {
logmessages.push(message); logmessages.push(message);
} }
, end: function() {} , end: function() {}
, destroySoon: function() {} , destroySoon: function() {}
}; };
}, },
watchFile: function() { watchFile: function() {
throw new Error("watchFile should not be called if logSize is not defined"); throw new Error("watchFile should not be called if logSize is not defined");
} }
}, },
log4js = sandbox.require( log4js = sandbox.require(
'../lib/log4js', '../lib/log4js',
{ {
requires: { requires: {
@ -87,20 +87,20 @@ vows.describe('log4js').addBatch({
} }
} }
); );
log4js.clearAppenders(); log4js.clearAppenders();
appender = log4js.fileAppender('./tmp-tests.log', log4js.layouts.messagePassThroughLayout); appender = log4js.fileAppender('./tmp-tests.log', log4js.layouts.messagePassThroughLayout);
log4js.addAppender(appender, 'file-test'); log4js.addAppender(appender, 'file-test');
var logger = log4js.getLogger('file-test'); var logger = log4js.getLogger('file-test');
logger.debug("this is a test"); logger.debug("this is a test");
return logmessages; return logmessages;
}, },
'should write log messages to file': function(logmessages) { 'should write log messages to file': function(logmessages) {
assert.length(logmessages, 1); assert.length(logmessages, 1);
assert.equal(logmessages, "this is a test\n"); assert.equal(logmessages, "this is a test\n");
} }
}, },
'fileAppender - with rolling based on size and number of files to keep': { 'fileAppender - with rolling based on size and number of files to keep': {
@ -203,28 +203,28 @@ vows.describe('log4js').addBatch({
}, },
'configure' : { 'configure' : {
topic: function() { topic: function() {
var messages = {}, fakeFS = { var messages = {}, fakeFS = {
createWriteStream: function(file) { createWriteStream: function(file) {
return { return {
write: function(message) { write: function(message) {
if (!messages.hasOwnProperty(file)) { if (!messages.hasOwnProperty(file)) {
messages[file] = []; messages[file] = [];
} }
messages[file].push(message); messages[file].push(message);
} }
, end: function() {} , end: function() {}
, destroySoon: function() {} , destroySoon: function() {}
}; };
}, },
readFileSync: function(file, encoding) { readFileSync: function(file, encoding) {
return require('fs').readFileSync(file, encoding); return require('fs').readFileSync(file, encoding);
}, },
watchFile: function(file) { watchFile: function(file) {
messages.watchedFile = file; messages.watchedFile = file;
} }
}, },
log4js = sandbox.require( log4js = sandbox.require(
'../lib/log4js' '../lib/log4js'
, { , {
requires: { requires: {
@ -232,38 +232,38 @@ vows.describe('log4js').addBatch({
} }
} }
); );
return [ log4js, messages ]; return [ log4js, messages ];
}, },
'should load appender configuration from a json file': function(args) { 'should load appender configuration from a json file': function(args) {
var log4js = args[0], messages = args[1]; var log4js = args[0], messages = args[1];
delete messages['tmp-tests.log']; delete messages['tmp-tests.log'];
log4js.clearAppenders(); log4js.clearAppenders();
//this config file defines one file appender (to ./tmp-tests.log) //this config file defines one file appender (to ./tmp-tests.log)
//and sets the log level for "tests" to WARN //and sets the log level for "tests" to WARN
log4js.configure('test/log4js.json'); log4js.configure('test/log4js.json');
var logger = log4js.getLogger("tests"); var logger = log4js.getLogger("tests");
logger.info('this should not be written to the file'); logger.info('this should not be written to the file');
logger.warn('this should be written to the file'); logger.warn('this should be written to the file');
assert.length(messages['tmp-tests.log'], 1); assert.length(messages['tmp-tests.log'], 1);
assert.equal(messages['tmp-tests.log'][0], 'this should be written to the file\n'); assert.equal(messages['tmp-tests.log'][0], 'this should be written to the file\n');
}, },
'should handle logLevelFilter configuration': function(args) { 'should handle logLevelFilter configuration': function(args) {
var log4js = args[0], messages = args[1]; var log4js = args[0], messages = args[1];
delete messages['tmp-tests.log']; delete messages['tmp-tests.log'];
delete messages['tmp-tests-warnings.log']; delete messages['tmp-tests-warnings.log'];
log4js.clearAppenders(); log4js.clearAppenders();
log4js.configure('test/with-logLevelFilter.json'); log4js.configure('test/with-logLevelFilter.json');
var logger = log4js.getLogger("tests"); var logger = log4js.getLogger("tests");
logger.info('main'); logger.info('main');
logger.error('both'); logger.error('both');
logger.warn('both'); logger.warn('both');
logger.debug('main'); logger.debug('main');
assert.length(messages['tmp-tests.log'], 4); assert.length(messages['tmp-tests.log'], 4);
assert.length(messages['tmp-tests-warnings.log'], 2); assert.length(messages['tmp-tests-warnings.log'], 2);
assert.deepEqual(messages['tmp-tests.log'], ['main\n','both\n','both\n','main\n']); assert.deepEqual(messages['tmp-tests.log'], ['main\n','both\n','both\n','main\n']);
assert.deepEqual(messages['tmp-tests-warnings.log'], ['both\n','both\n']); assert.deepEqual(messages['tmp-tests-warnings.log'], ['both\n','both\n']);
}, },
'should handle fileAppender with log rolling' : function(args) { 'should handle fileAppender with log rolling' : function(args) {
var log4js = args[0], messages = args[1]; var log4js = args[0], messages = args[1];
delete messages['tmp-test.log']; delete messages['tmp-test.log'];
@ -271,23 +271,23 @@ vows.describe('log4js').addBatch({
assert.equal(messages.watchedFile, 'tmp-test.log'); assert.equal(messages.watchedFile, 'tmp-test.log');
}, },
'should handle an object or a file name': function(args) { 'should handle an object or a file name': function(args) {
var log4js = args[0], var log4js = args[0],
messages = args[1], messages = args[1],
config = { config = {
"appenders": [ "appenders": [
{ {
"type" : "file", "type" : "file",
"filename" : "cheesy-wotsits.log", "filename" : "cheesy-wotsits.log",
"maxLogSize" : 1024, "maxLogSize" : 1024,
"backups" : 3, "backups" : 3,
"pollInterval" : 15 "pollInterval" : 15
} }
] ]
}; };
delete messages['cheesy-wotsits.log']; delete messages['cheesy-wotsits.log'];
log4js.configure(config); log4js.configure(config);
assert.equal(messages.watchedFile, 'cheesy-wotsits.log'); assert.equal(messages.watchedFile, 'cheesy-wotsits.log');
} }
}, },
'with no appenders defined' : { 'with no appenders defined' : {
@ -306,7 +306,7 @@ vows.describe('log4js').addBatch({
} }
} }
); );
logger = log4js.getLogger("some-logger"); logger = log4js.getLogger("some-logger");
logger.debug("This is a test"); logger.debug("This is a test");
return message; return message;
}, },
@ -428,7 +428,7 @@ vows.describe('log4js').addBatch({
debug: this.log, debug: this.log,
error: this.log error: this.log
}, },
log4js = sandbox.require( log4js = sandbox.require(
'../lib/log4js', '../lib/log4js',
{ {
requires: { requires: {
@ -440,7 +440,7 @@ vows.describe('log4js').addBatch({
} }
); );
logger = log4js.getLogger('a-test'); logger = log4js.getLogger('a-test');
logger.debug("this is a test"); logger.debug("this is a test");
return [ pathsChecked, message, modulePath ]; return [ pathsChecked, message, modulePath ];
@ -535,16 +535,81 @@ vows.describe('log4js').addBatch({
} }
}, },
'configuration persistence' : { 'configuration persistence' : {
'should maintain appenders between requires': function () { 'should maintain appenders between requires': function () {
var logEvent, firstLog4js = require('../lib/log4js'), secondLog4js; var logEvent, firstLog4js = require('../lib/log4js'), secondLog4js;
firstLog4js.clearAppenders(); firstLog4js.clearAppenders();
firstLog4js.addAppender(function(evt) { logEvent = evt; }); firstLog4js.addAppender(function(evt) { logEvent = evt; });
secondLog4js = require('../lib/log4js'); secondLog4js = require('../lib/log4js');
secondLog4js.getLogger().info("This should go to the appender defined in firstLog4js"); secondLog4js.getLogger().info("This should go to the appender defined in firstLog4js");
assert.equal(logEvent.data[0], "This should go to the appender defined in firstLog4js"); assert.equal(logEvent.data[0], "This should go to the appender defined in firstLog4js");
} }
},
'configuration reload' : {
topic: function() {
var pathsChecked = [],
messages = [],
logger,
modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
fakeFS = {
config: { appenders: [ { type: 'console', layout: { type: 'messagePassThrough' } } ],
levels: { 'a-test' : 'INFO' } },
readFileSync: function (file, encoding) {
assert.equal(file, modulePath);
assert.equal(encoding, 'utf8');
return JSON.stringify(fakeFS.config);
},
statSync: function (path) {
pathsChecked.push(path);
if (path === modulePath) {
return { mtime: new Date() };
} else {
throw new Error("no such file");
}
}
},
fakeConsole = {
log : function (msg) { messages.push(msg); },
info: this.log,
warn: this.log,
debug: this.log,
error: this.log
},
setIntervalCallback,
fakeSetInterval = function(cb, timeout) {
setIntervalCallback = cb;
},
log4js = sandbox.require(
'../lib/log4js',
{
requires: {
'fs': fakeFS
},
globals: {
'console': fakeConsole,
'setInterval' : fakeSetInterval,
}
}
);
logger = log4js.getLogger('a-test');
logger.info("info1");
logger.debug("debug2 - should be ignored");
delete fakeFS.config.levels;
setIntervalCallback();
logger.info("info3");
logger.debug("debug4");
return [ pathsChecked, messages, modulePath ];
},
'should configure log4js from first log4js.json found': function(args) {
var messages = args[1];
assert.length(messages, 3);
assert.equal(messages[0], 'info1');
assert.equal(messages[1], 'info3');
assert.equal(messages[2], 'debug4');
}
} }
}).export(module); }).export(module);

Loading…
Cancel
Save