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 ----'.
This commit is contained in:
Luis Malheiro
2013-12-10 23:55:08 +01:00
parent fb072dd70d
commit 6fa998408a
4 changed files with 94 additions and 33 deletions

View File

@@ -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) {

View File

@@ -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
};

View File

@@ -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();

View File

@@ -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() {