mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
310 lines
8.4 KiB
JavaScript
310 lines
8.4 KiB
JavaScript
"use strict";
|
|
/*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @fileoverview log4js is a library to log in JavaScript in similar manner
|
|
* than in log4j for Java. The API should be nearly the same.
|
|
*
|
|
* <h3>Example:</h3>
|
|
* <pre>
|
|
* var logging = require('log4js');
|
|
* logging.configure({
|
|
* appenders: {
|
|
* "errorFile": { type: "file", filename: "error.log" }
|
|
* },
|
|
* categories: {
|
|
* "default": { level: "ERROR", appenders: [ "errorFile" ] }
|
|
* }
|
|
* });
|
|
* //get a logger
|
|
* var log = logging.getLogger("some-category");
|
|
*
|
|
* ...
|
|
*
|
|
* //call the log
|
|
* log.error("oh noes");
|
|
* </pre>
|
|
*
|
|
* NOTE: the authors below are the original browser-based log4js authors
|
|
* don't try to contact them about bugs in this version :)
|
|
* @version 1.0
|
|
* @author Stephan Strittmatter - http://jroller.com/page/stritti
|
|
* @author Seth Chisamore - http://www.chisamore.com
|
|
* @since 2005-05-20
|
|
* @static
|
|
* Website: http://log4js.berlios.de
|
|
*/
|
|
var debug = require('./debug')('core')
|
|
, fs = require('fs')
|
|
, util = require('util')
|
|
, layouts = require('./layouts')
|
|
, levels = require('./levels')
|
|
, Logger = require('./logger')
|
|
, appenders = {}
|
|
, categories = {}
|
|
, appenderMakers = {}
|
|
, defaultConfig = {
|
|
appenders: {
|
|
console: { type: "console" }
|
|
},
|
|
categories: {
|
|
default: { level: levels.DEBUG, appenders: [ "console" ] }
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get a logger instance.
|
|
* @param {String} categoryName name of category to log to.
|
|
* @return {Logger} instance of logger for the category
|
|
* @static
|
|
*/
|
|
function getLogger (categoryName) {
|
|
debug("getLogger(" + categoryName + ")");
|
|
|
|
return new Logger(dispatch, categoryName || 'default');
|
|
}
|
|
|
|
/**
|
|
* Log event routing to appenders
|
|
* This would be a good place to implement category hierarchies/wildcards, etc
|
|
*/
|
|
function dispatch(event) {
|
|
debug("event is " + util.inspect(event));
|
|
var category = categories[event.category] || categories.default;
|
|
debug("category.level[" + category.level + "] <= " + event.level + " ? " + category.level.isLessThanOrEqualTo(event.level));
|
|
|
|
if (category.level.isLessThanOrEqualTo(event.level)) {
|
|
category.appenders.forEach(function(appender) {
|
|
appenders[appender](event);
|
|
});
|
|
}
|
|
}
|
|
|
|
/*
|
|
var configState = {};
|
|
|
|
function loadConfigurationFile(filename) {
|
|
if (filename) {
|
|
return JSON.parse(fs.readFileSync(filename, "utf8"));
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
function configureOnceOff(config, options) {
|
|
if (config) {
|
|
try {
|
|
configureAppenders(config.appenders, options);
|
|
configureLevels(config.levels);
|
|
|
|
if (config.replaceConsole) {
|
|
replaceConsole();
|
|
} else {
|
|
restoreConsole();
|
|
}
|
|
} catch (e) {
|
|
throw new Error(
|
|
"Problem reading log4js config " + util.inspect(config) +
|
|
". Error was \"" + e.message + "\" (" + e.stack + ")"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
function reloadConfiguration() {
|
|
var mtime = getMTime(configState.filename);
|
|
if (!mtime) return;
|
|
|
|
if (configState.lastMTime && (mtime.getTime() > configState.lastMTime.getTime())) {
|
|
configureOnceOff(loadConfigurationFile(configState.filename));
|
|
}
|
|
configState.lastMTime = mtime;
|
|
}
|
|
|
|
function getMTime(filename) {
|
|
var mtime;
|
|
try {
|
|
mtime = fs.statSync(configState.filename).mtime;
|
|
} catch (e) {
|
|
getLogger('log4js').warn('Failed to load configuration file ' + filename);
|
|
}
|
|
return mtime;
|
|
}
|
|
|
|
function initReloadConfiguration(filename, options) {
|
|
if (configState.timerId) {
|
|
clearInterval(configState.timerId);
|
|
delete configState.timerId;
|
|
}
|
|
configState.filename = filename;
|
|
configState.lastMTime = getMTime(filename);
|
|
configState.timerId = setInterval(reloadConfiguration, options.reloadSecs*1000);
|
|
}
|
|
*/
|
|
|
|
function load(file) {
|
|
return JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
}
|
|
|
|
function configure(configurationFileOrObject) {
|
|
var filename, config = configurationFileOrObject || process.env.LOG4JS_CONFIG;
|
|
|
|
if (!config || !(typeof config === 'string' || typeof config === 'object')) {
|
|
throw new Error("You must specify configuration as an object or a filename.");
|
|
}
|
|
|
|
if (typeof config === 'string') {
|
|
filename = config;
|
|
config = load(filename);
|
|
}
|
|
|
|
if (!config.appenders || !Object.keys(config.appenders).length) {
|
|
throw new Error("You must specify at least one appender.");
|
|
}
|
|
|
|
configureAppenders(config.appenders);
|
|
|
|
validateCategories(config.categories);
|
|
categories = config.categories;
|
|
|
|
/*
|
|
var config = configurationFileOrObject;
|
|
config = config || process.env.LOG4JS_CONFIG;
|
|
options = options || {};
|
|
|
|
if (config === undefined || config === null || typeof(config) === 'string') {
|
|
if (options.reloadSecs) {
|
|
initReloadConfiguration(config, options);
|
|
}
|
|
config = loadConfigurationFile(config) || defaultConfig;
|
|
} else {
|
|
if (options.reloadSecs) {
|
|
getLogger('log4js').warn(
|
|
'Ignoring configuration reload parameter for "object" configuration.'
|
|
);
|
|
}
|
|
}
|
|
configureOnceOff(config, options);
|
|
*/
|
|
}
|
|
|
|
function validateCategories(cats) {
|
|
if (!cats || !cats.default) {
|
|
throw new Error("You must specify an appender for the default category");
|
|
}
|
|
|
|
Object.keys(cats).forEach(function(categoryName) {
|
|
var category = cats[categoryName], inputLevel = category.level;
|
|
if (!category.level) {
|
|
throw new Error("You must specify a level for category '" + categoryName + "'.");
|
|
}
|
|
category.level = levels.toLevel(inputLevel);
|
|
if (!category.level) {
|
|
throw new Error("Level '" + inputLevel + "' is not valid for category '" + categoryName + "'. Acceptable values are: " + levels.levels.join(', ') + ".");
|
|
}
|
|
|
|
if (!category.appenders || !category.appenders.length) {
|
|
throw new Error("You must specify an appender for category '" + categoryName + "'.");
|
|
}
|
|
|
|
category.appenders.forEach(function(appender) {
|
|
if (!appenders[appender]) {
|
|
throw new Error("Appender '" + appender + "' for category '" + categoryName + "' does not exist. Known appenders are: " + Object.keys(appenders).join(', ') + ".");
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function clearAppenders () {
|
|
debug("clearing appenders");
|
|
appenders = {};
|
|
}
|
|
|
|
function configureAppenders(appenderMap) {
|
|
clearAppenders();
|
|
Object.keys(appenderMap).forEach(function(appenderName) {
|
|
var appender, appenderConfig = appenderMap[appenderName];
|
|
loadAppender(appenderConfig.type);
|
|
appenderConfig.makers = appenderMakers;
|
|
try {
|
|
appenders[appenderName] = appenderMakers[appenderConfig.type](appenderConfig);
|
|
} catch(e) {
|
|
throw new Error("log4js configuration problem for appender '" + appenderName + "'. Error was " + e.stack);
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadAppender(appender) {
|
|
var appenderModule;
|
|
try {
|
|
appenderModule = require('./appenders/' + appender);
|
|
} catch (e) {
|
|
try {
|
|
appenderModule = require(appender);
|
|
} catch (err) {
|
|
throw new Error("Could not load appender of type '" + appender + "'.");
|
|
}
|
|
}
|
|
appenderMakers[appender] = appenderModule.configure.bind(appenderModule);
|
|
}
|
|
|
|
/*
|
|
var originalConsoleFunctions = {
|
|
log: console.log,
|
|
debug: console.debug,
|
|
info: console.info,
|
|
warn: console.warn,
|
|
error: console.error
|
|
};
|
|
|
|
function replaceConsole(logger) {
|
|
function replaceWith(fn) {
|
|
return function() {
|
|
fn.apply(logger, arguments);
|
|
};
|
|
}
|
|
logger = logger || getLogger("console");
|
|
['log','debug','info','warn','error'].forEach(function (item) {
|
|
console[item] = replaceWith(item === 'log' ? logger.info : logger[item]);
|
|
});
|
|
}
|
|
|
|
function restoreConsole() {
|
|
['log', 'debug', 'info', 'warn', 'error'].forEach(function (item) {
|
|
console[item] = originalConsoleFunctions[item];
|
|
});
|
|
}
|
|
|
|
*/
|
|
module.exports = {
|
|
getLogger: getLogger,
|
|
configure: configure,
|
|
/*
|
|
replaceConsole: replaceConsole,
|
|
restoreConsole: restoreConsole,
|
|
|
|
levels: levels,
|
|
|
|
layouts: layouts,
|
|
appenders: {},
|
|
appenderMakers: appenderMakers,
|
|
connectLogger: require('./connect-logger').connectLogger
|
|
*/
|
|
};
|
|
|
|
//set ourselves up
|
|
debug("Starting configuration");
|
|
configure(defaultConfig);
|
|
|