From 6fa998408a2272b6c7891350105063f16f804232 Mon Sep 17 00:00:00 2001 From: Luis Malheiro Date: Tue, 10 Dec 2013 23:55:08 +0100 Subject: [PATCH] Adds subcategories to the appenders and loggers. Adds property "level" at the file appender to limit the levels that a file appender accepts. Creates a MARK category that always write to the log. That's useful to write things like '---- STARTED ----'. --- lib/appenders/file.js | 28 +++++++++---- lib/levels.js | 1 + lib/log4js.js | 96 ++++++++++++++++++++++++++++++++----------- lib/logger.js | 2 +- 4 files changed, 94 insertions(+), 33 deletions(-) diff --git a/lib/appenders/file.js b/lib/appenders/file.js index 8a7d113..d7ce702 100644 --- a/lib/appenders/file.js +++ b/lib/appenders/file.js @@ -6,7 +6,8 @@ var layouts = require('../layouts') , streams = require('../streams') , os = require('os') , eol = os.EOL || '\n' -, openFiles = []; +, openFiles = [] +, levels = require('../levels'); //close open files on process exit. process.on('exit', function() { @@ -26,7 +27,7 @@ process.on('exit', function() { * @param numBackups - the number of log files to keep after logSize * has been reached (default 5) */ -function fileAppender (file, layout, logSize, numBackups) { +function fileAppender (file, layout, logSize, numBackups, level) { var bytesWritten = 0; file = path.normalize(file); layout = layout || layouts.basicLayout; @@ -60,10 +61,23 @@ function fileAppender (file, layout, logSize, numBackups) { // push file to the stack of open handlers openFiles.push(logFile); - - return function(loggingEvent) { - logFile.write(layout(loggingEvent) + eol, "utf8"); - }; + + if (level) { + + var obj = levels.toLevel(level, levels.TRACE); + return function(loggingEvent) { + if (obj.isLessThanOrEqualTo(loggingEvent.level)) + logFile.write(layout(loggingEvent) + eol, "utf8"); + }; + + } else { + + return function(loggingEvent) { + logFile.write(layout(loggingEvent) + eol, "utf8"); + }; + + } + } function configure(config, options) { @@ -76,7 +90,7 @@ function configure(config, options) { config.filename = path.join(options.cwd, config.filename); } - return fileAppender(config.filename, layout, config.maxLogSize, config.backups); + return fileAppender(config.filename, layout, config.maxLogSize, config.backups, config.level); } function shutdown(cb) { diff --git a/lib/levels.js b/lib/levels.js index 0637099..45ebf64 100644 --- a/lib/levels.js +++ b/lib/levels.js @@ -63,6 +63,7 @@ module.exports = { WARN: new Level(30000, "WARN"), ERROR: new Level(40000, "ERROR"), FATAL: new Level(50000, "FATAL"), + MARK: new Level(Number.MAX_VALUE-1, "MARK"), OFF: new Level(Number.MAX_VALUE, "OFF"), toLevel: toLevel }; diff --git a/lib/log4js.js b/lib/log4js.js index 2e1f25c..cb799d1 100644 --- a/lib/log4js.js +++ b/lib/log4js.js @@ -92,6 +92,22 @@ function getBufferedLogger(categoryName) { return logger; } +function normalizeCategory (category) { + return category + '.'; +} + +function doesLevelEntryContainsLogger (levelCategory, loggerCategory) { + var normalizedLevelCategory = normalizeCategory(levelCategory); + var normalizedLoggerCategory = normalizeCategory(loggerCategory); + return normalizedLoggerCategory.substring(0, normalizedLevelCategory.length) == normalizedLevelCategory; +} + +function doesAppenderContainsLogger (appenderCategory, loggerCategory) { + var normalizedAppenderCategory = normalizeCategory(appenderCategory); + var normalizedLoggerCategory = normalizeCategory(loggerCategory); + return normalizedLoggerCategory.substring(0, normalizedAppenderCategory.length) == normalizedAppenderCategory; +} + /** * Get a logger instance. Instance is cached on categoryName level. @@ -99,32 +115,51 @@ function getBufferedLogger(categoryName) { * @return {Logger} instance of logger for the category * @static */ -function getLogger (categoryName) { +function getLogger (loggerCategoryName) { // Use default logger if categoryName is not specified or invalid - if (typeof categoryName !== "string") { - categoryName = Logger.DEFAULT_CATEGORY; + if (typeof loggerCategoryName !== "string") { + loggerCategoryName = Logger.DEFAULT_CATEGORY; } - var appenderList; - if (!hasLogger(categoryName)) { + if (!hasLogger(loggerCategoryName)) { + + var level = undefined; + + // If there's a "levels" entry in the configuration + if (levels.config) { + // Goes through the categories in the levels configuration entry, starting by the "higher" ones. + var keys = Object.keys(levels.config).sort(); + for (var idx = 0; idx < keys.length; idx++) { + var levelCategory = keys[idx]; + if (doesLevelEntryContainsLogger(levelCategory, loggerCategoryName)) { + // level for the logger + level = levels.config[levelCategory]; + } + } + } + // Create the logger for this name if it doesn't already exist - loggers[categoryName] = new Logger(categoryName); - if (appenders[categoryName]) { - appenderList = appenders[categoryName]; - appenderList.forEach(function(appender) { - loggers[categoryName].addListener("log", appender); - }); + loggers[loggerCategoryName] = new Logger(loggerCategoryName, level); + + var appenderList; + for(var appenderCategory in appenders) { + if (doesAppenderContainsLogger(appenderCategory, loggerCategoryName)) { + appenderList = appenders[appenderCategory]; + appenderList.forEach(function(appender) { + loggers[loggerCategoryName].addListener("log", appender); + }); + } } if (appenders[ALL_CATEGORIES]) { appenderList = appenders[ALL_CATEGORIES]; appenderList.forEach(function(appender) { - loggers[categoryName].addListener("log", appender); + loggers[loggerCategoryName].addListener("log", appender); }); } } - return loggers[categoryName]; + return loggers[loggerCategoryName]; } /** @@ -141,13 +176,19 @@ function addAppender () { args = args[0]; } - args.forEach(function(category) { - addAppenderToCategory(appender, category); + args.forEach(function(appenderCategory) { + addAppenderToCategory(appender, appenderCategory); - if (category === ALL_CATEGORIES) { + if (appenderCategory === ALL_CATEGORIES) { addAppenderToAllLoggers(appender); - } else if (hasLogger(category)) { - loggers[category].addListener("log", appender); + } else { + + for(var loggerCategory in loggers) { + if (doesAppenderContainsLogger(appenderCategory,loggerCategory)) { + loggers[loggerCategory].addListener("log", appender); + } + } + } }); } @@ -193,14 +234,19 @@ function configureAppenders(appenderList, options) { } } -function configureLevels(levels) { - if (levels) { - for (var category in levels) { - if (levels.hasOwnProperty(category)) { +function configureLevels(_levels) { + levels.config = _levels; // Keep it so we can create loggers later using this cfg + if (_levels) { + var keys = Object.keys(levels.config).sort(); + for (var idx in keys) { + var category = keys[idx]; + for(var loggerCategory in loggers) { + if (doesLevelEntryContainsLogger(category, loggerCategory)) { + loggers[loggerCategory].setLevel(_levels[category]); + } if(category === ALL_CATEGORIES) { setGlobalLogLevel(levels[category]); - } - getLogger(category).setLevel(levels[category]); + } } } } @@ -231,8 +277,8 @@ function loadConfigurationFile(filename) { function configureOnceOff(config, options) { if (config) { try { - configureAppenders(config.appenders, options); configureLevels(config.levels); + configureAppenders(config.appenders, options); if (config.replaceConsole) { replaceConsole(); diff --git a/lib/logger.js b/lib/logger.js index 3615a18..67bb35d 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -63,7 +63,7 @@ Logger.prototype.isLevelEnabled = function(otherLevel) { return this.level.isLessThanOrEqualTo(otherLevel); }; -['Trace','Debug','Info','Warn','Error','Fatal'].forEach( +['Trace','Debug','Info','Warn','Error','Fatal', 'Mark'].forEach( function(levelString) { var level = levels.toLevel(levelString); Logger.prototype['is'+levelString+'Enabled'] = function() {