Merged Gareth's latest changes in
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
var layouts = require('../layouts');
|
||||||
|
|
||||||
|
function consoleAppender (layout) {
|
||||||
|
layout = layout || layouts.colouredLayout;
|
||||||
|
return function(loggingEvent) {
|
||||||
|
console._preLog4js_log(layout(loggingEvent));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function configure(config) {
|
||||||
|
var layout;
|
||||||
|
if (config.layout) {
|
||||||
|
layout = layouts.layout(config.layout.type, config.layout);
|
||||||
|
}
|
||||||
|
return consoleAppender(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.name = "console";
|
||||||
|
exports.appender = consoleAppender;
|
||||||
|
exports.configure = configure;
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
var layouts = require('../layouts')
|
||||||
|
, fs = require('fs');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Appender writing the logs to a text file. Supports rolling of logs by size.
|
||||||
|
*
|
||||||
|
* @param file file log messages will be written to
|
||||||
|
* @param layout a function that takes a logevent and returns a string (defaults to basicLayout).
|
||||||
|
* @param logSize - the maximum size (in bytes) for a log file, if not provided then logs won't be rotated.
|
||||||
|
* @param numBackups - the number of log files to keep after logSize has been reached (default 5)
|
||||||
|
* @param filePollInterval - the time in seconds between file size checks (default 30s)
|
||||||
|
*/
|
||||||
|
function fileAppender (file, layout, logSize, numBackups, filePollInterval) {
|
||||||
|
layout = layout || layouts.basicLayout;
|
||||||
|
numBackups = numBackups === undefined ? 5 : numBackups;
|
||||||
|
filePollInterval = filePollInterval * 1000 || 30000;
|
||||||
|
|
||||||
|
function setupLogRolling () {
|
||||||
|
fs.watchFile(
|
||||||
|
file,
|
||||||
|
{
|
||||||
|
persistent: false,
|
||||||
|
interval: filePollInterval
|
||||||
|
},
|
||||||
|
function (curr, prev) {
|
||||||
|
if (curr.size >= logSize) {
|
||||||
|
rollThatLog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rollThatLog () {
|
||||||
|
if (numBackups > 0) {
|
||||||
|
//roll the backups (rename file.n-1 to file.n, where n <= numBackups)
|
||||||
|
for (var i=numBackups; i > 0; i--) {
|
||||||
|
if (i > 1) {
|
||||||
|
if (fileExists(file + '.' + (i-1))) {
|
||||||
|
fs.renameSync(file+'.'+(i-1), file+'.'+i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fs.renameSync(file, file+'.1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//let's make a new file
|
||||||
|
var newLogFileFD = fs.openSync(file, 'a', 0644)
|
||||||
|
, oldLogFileFD = logFile.fd;
|
||||||
|
logFile.fd = newLogFileFD;
|
||||||
|
fs.close(oldLogFileFD);
|
||||||
|
} else {
|
||||||
|
fs.truncate(logFile.fd, logSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileExists (filename) {
|
||||||
|
try {
|
||||||
|
fs.statSync(filename);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openTheStream() {
|
||||||
|
var stream = fs.createWriteStream(file, { flags: 'a', mode: 0644, encoding: 'utf8' });
|
||||||
|
stream.on("open", function() {
|
||||||
|
canWrite = true;
|
||||||
|
while (logEventBuffer.length > 0 && canWrite) {
|
||||||
|
canWrite = writeToLog(logEventBuffer.shift());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
stream.on("error", function (err) {
|
||||||
|
console.error("log4js.fileAppender - Error happened ", err);
|
||||||
|
});
|
||||||
|
stream.on("drain", function() {
|
||||||
|
canWrite = true;
|
||||||
|
while (logEventBuffer.length > 0 && canWrite) {
|
||||||
|
canWrite = writeToLog(logEventBuffer.shift());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var logEventBuffer = []
|
||||||
|
, canWrite = false
|
||||||
|
, logFile = openTheStream();
|
||||||
|
|
||||||
|
if (logSize > 0) {
|
||||||
|
setupLogRolling();
|
||||||
|
}
|
||||||
|
|
||||||
|
//close the file on process exit.
|
||||||
|
process.on('exit', function() {
|
||||||
|
logFile.end();
|
||||||
|
logFile.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
function writeToLog(loggingEvent) {
|
||||||
|
return logFile.write(layout(loggingEvent)+'\n', "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(loggingEvent) {
|
||||||
|
//because the log stream is opened asynchronously, we don't want to write
|
||||||
|
//until it is ready.
|
||||||
|
if (canWrite) {
|
||||||
|
canWrite = writeToLog(loggingEvent);
|
||||||
|
} else {
|
||||||
|
logEventBuffer.push(loggingEvent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function configure(config) {
|
||||||
|
var layout;
|
||||||
|
if (config.layout) {
|
||||||
|
layout = layouts.layout(config.layout.type, config.layout);
|
||||||
|
}
|
||||||
|
return fileAppender(config.filename, layout, config.maxLogSize, config.backups, config.pollInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.name = "file";
|
||||||
|
exports.appender = fileAppender;
|
||||||
|
exports.configure = configure;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
var levels = require('../levels');
|
||||||
|
|
||||||
|
function logLevelFilter (levelString, appender) {
|
||||||
|
var level = levels.toLevel(levelString);
|
||||||
|
return function(logEvent) {
|
||||||
|
if (logEvent.level.isGreaterThanOrEqualTo(level)) {
|
||||||
|
appender(logEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function configure(config) {
|
||||||
|
var appender = config.makers[config.appender.type](config.appender);
|
||||||
|
return logLevelFilter(config.level, appender);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.name = "logLevelFilter";
|
||||||
|
exports.appender = logLevelFilter;
|
||||||
|
exports.configure = configure;
|
||||||
+3
-3
@@ -38,9 +38,9 @@ function formatLogData(logData) {
|
|||||||
return match;
|
return match;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
if (data.length > 0) {
|
} else {
|
||||||
output += '\n';
|
//put it back, it's not a format string
|
||||||
}
|
data.unshift(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.forEach(function (item) {
|
data.forEach(function (item) {
|
||||||
|
|||||||
+32
-121
@@ -18,8 +18,6 @@
|
|||||||
* @fileoverview log4js is a library to log in JavaScript in similar manner
|
* @fileoverview log4js is a library to log in JavaScript in similar manner
|
||||||
* than in log4j for Java. The API should be nearly the same.
|
* than in log4j for Java. The API should be nearly the same.
|
||||||
*
|
*
|
||||||
* This file contains all log4js code and is the only file required for logging.
|
|
||||||
*
|
|
||||||
* <h3>Example:</h3>
|
* <h3>Example:</h3>
|
||||||
* <pre>
|
* <pre>
|
||||||
* var logging = require('log4js');
|
* var logging = require('log4js');
|
||||||
@@ -37,6 +35,8 @@
|
|||||||
* log.trace("trace me" );
|
* log.trace("trace me" );
|
||||||
* </pre>
|
* </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
|
* @version 1.0
|
||||||
* @author Stephan Strittmatter - http://jroller.com/page/stritti
|
* @author Stephan Strittmatter - http://jroller.com/page/stritti
|
||||||
* @author Seth Chisamore - http://www.chisamore.com
|
* @author Seth Chisamore - http://www.chisamore.com
|
||||||
@@ -50,30 +50,12 @@ var events = require('events')
|
|||||||
, sys = require('sys')
|
, sys = require('sys')
|
||||||
, layouts = require('./layouts')
|
, layouts = require('./layouts')
|
||||||
, levels = require('./levels')
|
, levels = require('./levels')
|
||||||
|
, consoleAppender = require('./appenders/console').appender
|
||||||
, DEFAULT_CATEGORY = '[default]'
|
, DEFAULT_CATEGORY = '[default]'
|
||||||
, ALL_CATEGORIES = '[all]'
|
, ALL_CATEGORIES = '[all]'
|
||||||
, appenders = {}
|
, appenders = {}
|
||||||
, loggers = {}
|
, loggers = {}
|
||||||
, appenderMakers = {
|
, appenderMakers = {};
|
||||||
"file": function(config, fileAppender) {
|
|
||||||
var layout;
|
|
||||||
if (config.layout) {
|
|
||||||
layout = layouts.layout(config.layout.type, config.layout);
|
|
||||||
}
|
|
||||||
return fileAppender(config.filename, layout, config.maxLogSize, config.backups, config.pollInterval);
|
|
||||||
},
|
|
||||||
"console": function(config, fileAppender, consoleAppender) {
|
|
||||||
var layout;
|
|
||||||
if (config.layout) {
|
|
||||||
layout = layouts.layout(config.layout.type, config.layout);
|
|
||||||
}
|
|
||||||
return consoleAppender(layout);
|
|
||||||
},
|
|
||||||
"logLevelFilter": function(config, fileAppender, consoleAppender) {
|
|
||||||
var appender = appenderMakers[config.appender.type](config.appender, fileAppender, consoleAppender);
|
|
||||||
return logLevelFilter(config.level, appender);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a logger instance. Instance is cached on categoryName level.
|
* Get a logger instance. Instance is cached on categoryName level.
|
||||||
@@ -150,11 +132,13 @@ function clearAppenders () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureAppenders(appenderList, fileAppender, consoleAppender) {
|
function configureAppenders(appenderList) {
|
||||||
clearAppenders();
|
clearAppenders();
|
||||||
if (appenderList) {
|
if (appenderList) {
|
||||||
appenderList.forEach(function(appenderConfig) {
|
appenderList.forEach(function(appenderConfig) {
|
||||||
var appender = appenderMakers[appenderConfig.type](appenderConfig, fileAppender, consoleAppender);
|
var appender;
|
||||||
|
appenderConfig.makers = appenderMakers;
|
||||||
|
appender = appenderMakers[appenderConfig.type](appenderConfig);
|
||||||
if (appender) {
|
if (appender) {
|
||||||
addAppender(appender, appenderConfig.category);
|
addAppender(appender, appenderConfig.category);
|
||||||
} else {
|
} else {
|
||||||
@@ -162,7 +146,7 @@ function configureAppenders(appenderList, fileAppender, consoleAppender) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addAppender(consoleAppender);
|
addAppender(consoleAppender());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,91 +246,6 @@ function getDefaultLogger () {
|
|||||||
return getLogger(DEFAULT_CATEGORY);
|
return getLogger(DEFAULT_CATEGORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
function logLevelFilter (levelString, appender) {
|
|
||||||
var level = levels.toLevel(levelString);
|
|
||||||
return function(logEvent) {
|
|
||||||
if (logEvent.level.isGreaterThanOrEqualTo(level)) {
|
|
||||||
appender(logEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function consoleAppender (layout) {
|
|
||||||
layout = layout || layouts.colouredLayout;
|
|
||||||
return function(loggingEvent) {
|
|
||||||
console._preLog4js_log(layout(loggingEvent));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File Appender writing the logs to a text file. Supports rolling of logs by size.
|
|
||||||
*
|
|
||||||
* @param file file log messages will be written to
|
|
||||||
* @param layout a function that takes a logevent and returns a string (defaults to basicLayout).
|
|
||||||
* @param logSize - the maximum size (in bytes) for a log file, if not provided then logs won't be rotated.
|
|
||||||
* @param numBackups - the number of log files to keep after logSize has been reached (default 5)
|
|
||||||
* @param filePollInterval - the time in seconds between file size checks (default 30s)
|
|
||||||
*/
|
|
||||||
function fileAppender (file, layout, logSize, numBackups, filePollInterval) {
|
|
||||||
layout = layout || layouts.basicLayout;
|
|
||||||
var logFile = fs.createWriteStream(file, { flags: 'a', mode: 0644, encoding: 'utf8' });
|
|
||||||
|
|
||||||
if (logSize > 0) {
|
|
||||||
setupLogRolling(logFile, file, logSize, numBackups || 5, (filePollInterval * 1000) || 30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
//close the file on process exit.
|
|
||||||
process.on('exit', function() {
|
|
||||||
logFile.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
return function(loggingEvent) {
|
|
||||||
logFile.write(layout(loggingEvent)+'\n');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupLogRolling (logFile, filename, logSize, numBackups, filePollInterval) {
|
|
||||||
fs.watchFile(
|
|
||||||
filename,
|
|
||||||
{
|
|
||||||
persistent: false,
|
|
||||||
interval: filePollInterval
|
|
||||||
},
|
|
||||||
function (curr, prev) {
|
|
||||||
if (curr.size >= logSize) {
|
|
||||||
rollThatLog(logFile, filename, numBackups);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rollThatLog (logFile, filename, numBackups) {
|
|
||||||
//first close the current one.
|
|
||||||
logFile.end();
|
|
||||||
//roll the backups (rename file.n-1 to file.n, where n <= numBackups)
|
|
||||||
for (var i=numBackups; i > 0; i--) {
|
|
||||||
if (i > 1) {
|
|
||||||
if (fileExists(filename + '.' + (i-1))) {
|
|
||||||
fs.renameSync(filename+'.'+(i-1), filename+'.'+i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fs.renameSync(filename, filename+'.1');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//open it up again
|
|
||||||
logFile = fs.createWriteStream(filename, { flags: 'a', mode: 0644, encoding: "utf8" });
|
|
||||||
}
|
|
||||||
|
|
||||||
function fileExists (filename) {
|
|
||||||
try {
|
|
||||||
fs.statSync(filename);
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,7 +276,7 @@ function loadConfigurationFile(filename) {
|
|||||||
function configureOnceOff(config) {
|
function configureOnceOff(config) {
|
||||||
if (config) {
|
if (config) {
|
||||||
try {
|
try {
|
||||||
configureAppenders(config.appenders, fileAppender, consoleAppender);
|
configureAppenders(config.appenders);
|
||||||
configureLevels(config.levels);
|
configureLevels(config.levels);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error("Problem reading log4js config " + sys.inspect(config) + ". Error was \"" + e.message + "\" ("+e.stack+")");
|
throw new Error("Problem reading log4js config " + sys.inspect(config) + ". Error was \"" + e.message + "\" ("+e.stack+")");
|
||||||
@@ -447,16 +346,21 @@ function replaceConsole(logger) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
['log','debug','info','warn','error'].forEach(function (item) {
|
['log','debug','info','warn','error'].forEach(function (item) {
|
||||||
console['_preLog4js_'+item] = console[item];
|
if (console['_preLog4js_log'] === undefined) {
|
||||||
|
console['_preLog4js_'+item] = console[item];
|
||||||
|
}
|
||||||
console[item] = replaceWith(item === 'log' ? logger.info : logger[item]);
|
console[item] = replaceWith(item === 'log' ? logger.info : logger[item]);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//set ourselves up if we can find a default log4js.json
|
function loadAppenders() {
|
||||||
configure(findConfiguration());
|
var appenderList = fs.readdirSync(__dirname + '/appenders');
|
||||||
//replace console.log, etc with log4js versions
|
appenderList.forEach(function(file) {
|
||||||
replaceConsole(getLogger("console"));
|
var appenderModule = require('./appenders/' + file);
|
||||||
|
module.exports.appenders[appenderModule.name] = appenderModule.appender;
|
||||||
|
appenderMakers[appenderModule.name] = appenderModule.configure;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getLogger: getLogger,
|
getLogger: getLogger,
|
||||||
@@ -469,16 +373,23 @@ module.exports = {
|
|||||||
levels: levels,
|
levels: levels,
|
||||||
setGlobalLogLevel: setGlobalLogLevel,
|
setGlobalLogLevel: setGlobalLogLevel,
|
||||||
|
|
||||||
consoleAppender: consoleAppender,
|
|
||||||
fileAppender: fileAppender,
|
|
||||||
logLevelFilter: logLevelFilter,
|
|
||||||
|
|
||||||
layouts: layouts,
|
layouts: layouts,
|
||||||
|
appenders: {},
|
||||||
connectLogger: require('./connect-logger').connectLogger
|
connectLogger: require('./connect-logger').connectLogger
|
||||||
};
|
};
|
||||||
|
|
||||||
|
loadAppenders();
|
||||||
|
//set ourselves up if we can find a default log4js.json
|
||||||
|
configure(findConfiguration());
|
||||||
|
//replace console.log, etc with log4js versions
|
||||||
|
replaceConsole(getLogger("console"));
|
||||||
|
|
||||||
//keep the old-style layouts
|
//keep the old-style layouts
|
||||||
['basicLayout','messagePassThroughLayout','colouredLayout','coloredLayout'].forEach(function(item) {
|
['basicLayout','messagePassThroughLayout','colouredLayout','coloredLayout'].forEach(function(item) {
|
||||||
module.exports[item] = layouts[item];
|
module.exports[item] = layouts[item];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//and the old-style appenders
|
||||||
|
module.exports.consoleAppender = module.exports.appenders.console;
|
||||||
|
module.exports.fileAppender = module.exports.appenders.file;
|
||||||
|
module.exports.logLevelFilter = module.exports.appenders.logLevelFilter;
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
var log4js = require('./lib/log4js')
|
||||||
|
, log
|
||||||
|
, i = 0;
|
||||||
|
log4js.configure({
|
||||||
|
"appenders": [
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"filename": "tmp-test.log",
|
||||||
|
"maxLogSize": 1024,
|
||||||
|
"backups": 3,
|
||||||
|
"pollInterval": 0.1,
|
||||||
|
"category": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "console"
|
||||||
|
, category: "console"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
log = log4js.getLogger("test");
|
||||||
|
|
||||||
|
function doTheLogging(x) {
|
||||||
|
log.info("Logging something %d", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ; i < 100000; i++) {
|
||||||
|
doTheLogging(i);
|
||||||
|
}
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "log4js",
|
"name": "log4js",
|
||||||
"version": "0.3.4",
|
"version": "0.3.5",
|
||||||
"description": "Port of Log4js to work with node.",
|
"description": "Port of Log4js to work with node.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"logging",
|
"logging",
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
var vows = require('vows')
|
||||||
|
, fs = require('fs')
|
||||||
|
, log4js = require('../lib/log4js')
|
||||||
|
, assert = require('assert');
|
||||||
|
|
||||||
|
log4js.clearAppenders();
|
||||||
|
|
||||||
|
function remove(filename) {
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(filename);
|
||||||
|
} catch (e) {
|
||||||
|
//doesn't really matter if it failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vows.describe('log4js fileAppender').addBatch({
|
||||||
|
|
||||||
|
'with default fileAppender settings': {
|
||||||
|
topic: function() {
|
||||||
|
var testFile = __dirname + '/fa-default-test.log'
|
||||||
|
, logger = log4js.getLogger('default-settings');
|
||||||
|
remove(testFile);
|
||||||
|
log4js.addAppender(log4js.fileAppender(testFile), 'default-settings');
|
||||||
|
|
||||||
|
logger.info("This should be in the file.");
|
||||||
|
|
||||||
|
fs.readFile(testFile, "utf8", this.callback);
|
||||||
|
},
|
||||||
|
'should write log messages to the file': function(err, fileContents) {
|
||||||
|
assert.include(fileContents, "This should be in the file.\n");
|
||||||
|
},
|
||||||
|
'log messages should be in the basic layout format': function(err, fileContents) {
|
||||||
|
assert.match(fileContents, /\[\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{3}\] \[INFO\] default-settings - /);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'with a max file size and no backups': {
|
||||||
|
topic: function() {
|
||||||
|
var testFile = __dirname + '/fa-maxFileSize-test.log'
|
||||||
|
, logger = log4js.getLogger('max-file-size');
|
||||||
|
remove(testFile);
|
||||||
|
//log file of 50 bytes maximum, no backups, check every 10ms for changes
|
||||||
|
log4js.addAppender(log4js.fileAppender(testFile, log4js.layouts.basicLayout, 50, 0, 0.01), 'max-file-size');
|
||||||
|
logger.info("This is the first log message.");
|
||||||
|
//we have to wait before writing the second one, because node is too fast for the file system.
|
||||||
|
var that = this;
|
||||||
|
setTimeout(function() {
|
||||||
|
logger.info("This is the second log message.");
|
||||||
|
fs.readFile(testFile, "utf8", that.callback);
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
'log file should only contain the second message': function(err, fileContents) {
|
||||||
|
assert.include(fileContents, "This is the second log message.\n");
|
||||||
|
assert.equal(fileContents.indexOf("This is the first log message."), -1);
|
||||||
|
},
|
||||||
|
'the number of files': {
|
||||||
|
topic: function() {
|
||||||
|
fs.readdir(__dirname, this.callback);
|
||||||
|
},
|
||||||
|
'starting with the test file name should be one': function(err, files) {
|
||||||
|
var logFiles = files.filter(function(file) { return file.indexOf('fa-maxFileSize-test.log') > -1; });
|
||||||
|
assert.length(logFiles, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'with a max file size and 2 backups': {
|
||||||
|
topic: function() {
|
||||||
|
var testFile = __dirname + '/fa-maxFileSize-with-backups-test.log'
|
||||||
|
, logger = log4js.getLogger('max-file-size-backups');
|
||||||
|
remove(testFile);
|
||||||
|
remove(testFile+'.1');
|
||||||
|
remove(testFile+'.2');
|
||||||
|
|
||||||
|
//log file of 50 bytes maximum, 2 backups, check every 10ms for changes
|
||||||
|
log4js.addAppender(log4js.fileAppender(testFile, log4js.layouts.basicLayout, 50, 2, 0.01), 'max-file-size-backups');
|
||||||
|
logger.info("This is the first log message.");
|
||||||
|
//we have to wait before writing the second one, because node is too fast for the file system.
|
||||||
|
var that = this;
|
||||||
|
setTimeout(function() {
|
||||||
|
logger.info("This is the second log message.");
|
||||||
|
}, 200);
|
||||||
|
setTimeout(function() {
|
||||||
|
logger.info("This is the third log message.");
|
||||||
|
}, 400);
|
||||||
|
setTimeout(function() {
|
||||||
|
logger.info("This is the fourth log message.");
|
||||||
|
fs.readdir(__dirname, that.callback);
|
||||||
|
}, 600);
|
||||||
|
},
|
||||||
|
'the log files': {
|
||||||
|
topic: function(files) {
|
||||||
|
var logFiles = files.filter(function(file) { return file.indexOf('fa-maxFileSize-with-backups-test.log') > -1; });
|
||||||
|
return logFiles;
|
||||||
|
},
|
||||||
|
'should be 3': function (files) {
|
||||||
|
assert.length(files, 3);
|
||||||
|
},
|
||||||
|
'should be named in sequence': function (files) {
|
||||||
|
assert.deepEqual(files, ['fa-maxFileSize-with-backups-test.log', 'fa-maxFileSize-with-backups-test.log.1', 'fa-maxFileSize-with-backups-test.log.2']);
|
||||||
|
},
|
||||||
|
'and the contents of the first file': {
|
||||||
|
topic: function(logFiles) {
|
||||||
|
fs.readFile(logFiles[0], "utf8", this.callback);
|
||||||
|
},
|
||||||
|
'should be the last log message': function(err, contents) {
|
||||||
|
assert.include(contents, 'This is the fourth log message.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'and the contents of the second file': {
|
||||||
|
topic: function(logFiles) {
|
||||||
|
fs.readFile(logFiles[1], "utf8", this.callback);
|
||||||
|
},
|
||||||
|
'should be the third log message': function(err, contents) {
|
||||||
|
assert.include(contents, 'This is the third log message.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'and the contents of the third file': {
|
||||||
|
topic: function(logFiles) {
|
||||||
|
fs.readFile(logFiles[2], "utf8", this.callback);
|
||||||
|
},
|
||||||
|
'should be the second log message': function(err, contents) {
|
||||||
|
assert.include(contents, 'This is the second log message.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).addBatch({
|
||||||
|
'configure' : {
|
||||||
|
'with fileAppender': {
|
||||||
|
topic: function() {
|
||||||
|
var log4js = require('../lib/log4js')
|
||||||
|
, logger;
|
||||||
|
//this config file defines one file appender (to ./tmp-tests.log)
|
||||||
|
//and sets the log level for "tests" to WARN
|
||||||
|
log4js.configure('test/log4js.json');
|
||||||
|
logger = log4js.getLogger('tests');
|
||||||
|
logger.info('this should not be written to the file');
|
||||||
|
logger.warn('this should be written to the file');
|
||||||
|
|
||||||
|
fs.readFile('tmp-tests.log', 'utf8', this.callback);
|
||||||
|
},
|
||||||
|
'should load appender configuration from a json file': function(err, contents) {
|
||||||
|
assert.include(contents, 'this should be written to the file\n');
|
||||||
|
assert.equal(contents.indexOf('this should not be written to the file'), -1);
|
||||||
|
},
|
||||||
|
'and log rolling': {
|
||||||
|
topic: function() {
|
||||||
|
var sandbox = require('sandboxed-module')
|
||||||
|
, that = this
|
||||||
|
, fileAppender = sandbox.require(
|
||||||
|
'../lib/appenders/file.js'
|
||||||
|
, { requires:
|
||||||
|
{ 'fs':
|
||||||
|
{
|
||||||
|
watchFile: function(filename, options, cb) {
|
||||||
|
that.callback(null, filename);
|
||||||
|
}
|
||||||
|
, createWriteStream: function() {
|
||||||
|
return {
|
||||||
|
on: function() {}
|
||||||
|
, end: function() {}
|
||||||
|
, destroy: function() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
fileAppender.configure({
|
||||||
|
filename: "cheese.log"
|
||||||
|
, maxLogSize: 100
|
||||||
|
, backups: 5
|
||||||
|
, pollInterval: 30
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'should watch the log file': function(watchedFile) {
|
||||||
|
assert.equal(watchedFile, 'cheese.log');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}).export(module);
|
||||||
+19
-12
@@ -65,7 +65,19 @@ vows.describe('log4js layouts').addBatch({
|
|||||||
, toString: function() { return "ERROR"; }
|
, toString: function() { return "ERROR"; }
|
||||||
}
|
}
|
||||||
}), "thing 1");
|
}), "thing 1");
|
||||||
}
|
},
|
||||||
|
'should output the first item even if it is not a string': function(layout) {
|
||||||
|
assert.equal(layout({
|
||||||
|
data: [ { thing: 1} ]
|
||||||
|
, startTime: new Date(2010, 11, 5, 14, 18, 30, 45)
|
||||||
|
, categoryName: "cheese"
|
||||||
|
, level: {
|
||||||
|
colour: "green"
|
||||||
|
, toString: function() { return "ERROR"; }
|
||||||
|
}
|
||||||
|
}), "{ thing: 1 }");
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
'basicLayout': {
|
'basicLayout': {
|
||||||
@@ -90,29 +102,24 @@ vows.describe('log4js layouts').addBatch({
|
|||||||
error = new Error("Some made-up error"),
|
error = new Error("Some made-up error"),
|
||||||
stack = error.stack.split(/\n/);
|
stack = error.stack.split(/\n/);
|
||||||
|
|
||||||
event.data = ['this is a test', error];
|
event.data = ['this is a test ', error];
|
||||||
output = layout(event);
|
output = layout(event);
|
||||||
lines = output.split(/\n/);
|
lines = output.split(/\n/);
|
||||||
|
|
||||||
assert.length(lines, stack.length+1);
|
assert.length(lines, stack.length);
|
||||||
assert.equal(lines[0], "[2010-12-05 14:18:30.045] [DEBUG] tests - this is a test");
|
assert.equal(lines[0], "[2010-12-05 14:18:30.045] [DEBUG] tests - this is a test Error: Some made-up error");
|
||||||
assert.equal(lines[1], "Error: Some made-up error");
|
|
||||||
for (var i = 1; i < stack.length; i++) {
|
for (var i = 1; i < stack.length; i++) {
|
||||||
assert.equal(lines[i+1], stack[i]);
|
assert.equal(lines[i+1], stack[i+1]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'should output any extra data in the log event as util.inspect strings': function(args) {
|
'should output any extra data in the log event as util.inspect strings': function(args) {
|
||||||
var layout = args[0], event = args[1], output, lines;
|
var layout = args[0], event = args[1], output, lines;
|
||||||
event.data = ['this is a test', {
|
event.data = ['this is a test ', {
|
||||||
name: 'Cheese',
|
name: 'Cheese',
|
||||||
message: 'Gorgonzola smells.'
|
message: 'Gorgonzola smells.'
|
||||||
}];
|
}];
|
||||||
output = layout(event);
|
output = layout(event);
|
||||||
lines = output.split(/\n/);
|
assert.equal(output, "[2010-12-05 14:18:30.045] [DEBUG] tests - this is a test { name: 'Cheese', message: 'Gorgonzola smells.' }");
|
||||||
|
|
||||||
assert.length(lines, 2);
|
|
||||||
assert.equal(lines[0], "[2010-12-05 14:18:30.045] [DEBUG] tests - this is a test");
|
|
||||||
assert.equal(lines[1], "{ name: 'Cheese', message: 'Gorgonzola smells.' }");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
var vows = require('vows')
|
||||||
|
, fs = require('fs')
|
||||||
|
, assert = require('assert');
|
||||||
|
|
||||||
|
function remove(filename) {
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(filename);
|
||||||
|
} catch (e) {
|
||||||
|
//doesn't really matter if it failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vows.describe('log4js logLevelFilter').addBatch({
|
||||||
|
'appender': {
|
||||||
|
topic: function() {
|
||||||
|
var log4js = require('../lib/log4js'), logEvents = [], logger;
|
||||||
|
log4js.clearAppenders();
|
||||||
|
log4js.addAppender(log4js.logLevelFilter('ERROR', function(evt) { logEvents.push(evt); }), "logLevelTest");
|
||||||
|
logger = log4js.getLogger("logLevelTest");
|
||||||
|
logger.debug('this should not trigger an event');
|
||||||
|
logger.warn('neither should this');
|
||||||
|
logger.error('this should, though');
|
||||||
|
logger.fatal('so should this');
|
||||||
|
return logEvents;
|
||||||
|
},
|
||||||
|
'should only pass log events greater than or equal to its own level' : function(logEvents) {
|
||||||
|
assert.length(logEvents, 2);
|
||||||
|
assert.equal(logEvents[0].data[0], 'this should, though');
|
||||||
|
assert.equal(logEvents[1].data[0], 'so should this');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'configure': {
|
||||||
|
topic: function() {
|
||||||
|
var log4js = require('../lib/log4js')
|
||||||
|
, logger;
|
||||||
|
|
||||||
|
remove(__dirname + '/logLevelFilter.log');
|
||||||
|
remove(__dirname + '/logLevelFilter-warnings.log');
|
||||||
|
|
||||||
|
log4js.configure('test/with-logLevelFilter.json');
|
||||||
|
logger = log4js.getLogger("tests");
|
||||||
|
logger.info('main');
|
||||||
|
logger.error('both');
|
||||||
|
logger.warn('both');
|
||||||
|
logger.debug('main');
|
||||||
|
|
||||||
|
return logger;
|
||||||
|
},
|
||||||
|
'tmp-tests.log': {
|
||||||
|
topic: function() {
|
||||||
|
fs.readFile(__dirname + '/logLevelFilter.log', 'utf8', this.callback);
|
||||||
|
},
|
||||||
|
'should contain all log messages': function(contents) {
|
||||||
|
var messages = contents.trim().split('\n');
|
||||||
|
assert.deepEqual(messages, ['main','both','both','main']);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'tmp-tests-warnings.log': {
|
||||||
|
topic: function() {
|
||||||
|
fs.readFile(__dirname + '/logLevelFilter-warnings.log','utf8',this.callback);
|
||||||
|
},
|
||||||
|
'should contain only error and warning log messages': function(contents) {
|
||||||
|
var messages = contents.trim().split('\n');
|
||||||
|
assert.deepEqual(messages, ['both','both']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).export(module);
|
||||||
+120
-269
@@ -55,225 +55,33 @@ vows.describe('log4js').addBatch({
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
'fileAppender': {
|
'invalid configuration': {
|
||||||
topic: function() {
|
'should throw an exception': function() {
|
||||||
var appender
|
assert.throws(function() {
|
||||||
, logmessages = []
|
log4js.configure({ "type": "invalid" });
|
||||||
, thing = "thing"
|
});
|
||||||
, fakeFS = {
|
|
||||||
createWriteStream: function() {
|
|
||||||
assert.equal(arguments[0], './tmp-tests.log');
|
|
||||||
assert.isObject(arguments[1]);
|
|
||||||
assert.equal(arguments[1].flags, 'a');
|
|
||||||
assert.equal(arguments[1].mode, 0644);
|
|
||||||
assert.equal(arguments[1].encoding, 'utf8');
|
|
||||||
return {
|
|
||||||
write: function(message) {
|
|
||||||
logmessages.push(message);
|
|
||||||
}
|
|
||||||
, end: function() {}
|
|
||||||
, destroySoon: function() {}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watchFile: function() {
|
|
||||||
throw new Error("watchFile should not be called if logSize is not defined");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
log4js = sandbox.require(
|
|
||||||
'../lib/log4js',
|
|
||||||
{
|
|
||||||
requires: {
|
|
||||||
'fs': fakeFS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
log4js.clearAppenders();
|
|
||||||
|
|
||||||
appender = log4js.fileAppender('./tmp-tests.log', log4js.layouts.messagePassThroughLayout);
|
|
||||||
log4js.addAppender(appender, 'file-test');
|
|
||||||
|
|
||||||
var logger = log4js.getLogger('file-test');
|
|
||||||
logger.debug("this is a test");
|
|
||||||
|
|
||||||
return logmessages;
|
|
||||||
},
|
|
||||||
'should write log messages to file': function(logmessages) {
|
|
||||||
assert.length(logmessages, 1);
|
|
||||||
assert.equal(logmessages, "this is a test\n");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'fileAppender - with rolling based on size and number of files to keep': {
|
'configuration when passed as object': {
|
||||||
topic: function() {
|
topic: function() {
|
||||||
var watchCb,
|
var appenderConfig
|
||||||
filesOpened = [],
|
, log4js = sandbox.require(
|
||||||
filesEnded = [],
|
'../lib/log4js'
|
||||||
filesRenamed = [],
|
, { requires:
|
||||||
newFilenames = [],
|
{ './appenders/file.js':
|
||||||
existingFiles = ['tests.log'],
|
{
|
||||||
log4js = sandbox.require(
|
name: "file"
|
||||||
'../lib/log4js'
|
, appender: function() {}
|
||||||
, {
|
, configure: function(configuration) {
|
||||||
requires: {
|
appenderConfig = configuration;
|
||||||
'fs': {
|
return function() {};
|
||||||
watchFile: function(file, options, callback) {
|
|
||||||
assert.equal(file, 'tests.log');
|
|
||||||
assert.equal(options.persistent, false);
|
|
||||||
assert.equal(options.interval, 30000);
|
|
||||||
assert.isFunction(callback);
|
|
||||||
watchCb = callback;
|
|
||||||
},
|
|
||||||
createWriteStream: function(file) {
|
|
||||||
assert.equal(file, 'tests.log');
|
|
||||||
filesOpened.push(file);
|
|
||||||
return {
|
|
||||||
end: function() {
|
|
||||||
filesEnded.push(file);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
statSync: function(file) {
|
|
||||||
if (existingFiles.indexOf(file) < 0) {
|
|
||||||
throw new Error("this file doesn't exist");
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
renameSync: function(oldFile, newFile) {
|
|
||||||
filesRenamed.push(oldFile);
|
|
||||||
existingFiles.push(newFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
|
||||||
var appender = log4js.fileAppender('tests.log', log4js.messagePassThroughLayout, 1024, 2, 30);
|
|
||||||
return [watchCb, filesOpened, filesEnded, filesRenamed, existingFiles];
|
|
||||||
},
|
|
||||||
|
|
||||||
'should close current log file, rename all old ones, open new one on rollover': function(args) {
|
|
||||||
var watchCb = args[0]
|
|
||||||
, filesOpened = args[1]
|
|
||||||
, filesEnded = args[2]
|
|
||||||
, filesRenamed = args[3]
|
|
||||||
, existingFiles = args[4];
|
|
||||||
assert.isFunction(watchCb);
|
|
||||||
//tell the watchCb that the file is below the threshold
|
|
||||||
watchCb({ size: 891 }, { size: 0 });
|
|
||||||
//filesOpened should still be the first one.
|
|
||||||
assert.length(filesOpened, 1);
|
|
||||||
//tell the watchCb that the file is now over the threshold
|
|
||||||
watchCb({ size: 1053 }, { size: 891 });
|
|
||||||
//it should have closed the first log file.
|
|
||||||
assert.length(filesEnded, 1);
|
|
||||||
//it should have renamed the previous log file
|
|
||||||
assert.length(filesRenamed, 1);
|
|
||||||
//and we should have two files now
|
|
||||||
assert.length(existingFiles, 2);
|
|
||||||
assert.deepEqual(existingFiles, ['tests.log', 'tests.log.1']);
|
|
||||||
//and opened a new log file.
|
|
||||||
assert.length(filesOpened, 2);
|
|
||||||
|
|
||||||
//now tell the watchCb that we've flipped over the threshold again
|
|
||||||
watchCb({ size: 1025 }, { size: 123 });
|
|
||||||
//it should have closed the old file
|
|
||||||
assert.length(filesEnded, 2);
|
|
||||||
//it should have renamed both the old log file, and the previous '.1' file
|
|
||||||
assert.length(filesRenamed, 3);
|
|
||||||
assert.deepEqual(filesRenamed, ['tests.log', 'tests.log.1', 'tests.log' ]);
|
|
||||||
//it should have renamed 2 more file
|
|
||||||
assert.length(existingFiles, 4);
|
|
||||||
assert.deepEqual(existingFiles, ['tests.log', 'tests.log.1', 'tests.log.2', 'tests.log.1']);
|
|
||||||
//and opened a new log file
|
|
||||||
assert.length(filesOpened, 3);
|
|
||||||
|
|
||||||
//tell the watchCb we've flipped again.
|
|
||||||
watchCb({ size: 1024 }, { size: 234 });
|
|
||||||
//close the old one again.
|
|
||||||
assert.length(filesEnded, 3);
|
|
||||||
//it should have renamed the old log file and the 2 backups, with the last one being overwritten.
|
|
||||||
assert.length(filesRenamed, 5);
|
|
||||||
assert.deepEqual(filesRenamed, ['tests.log', 'tests.log.1', 'tests.log', 'tests.log.1', 'tests.log' ]);
|
|
||||||
//it should have renamed 2 more files
|
|
||||||
assert.length(existingFiles, 6);
|
|
||||||
assert.deepEqual(existingFiles, ['tests.log', 'tests.log.1', 'tests.log.2', 'tests.log.1', 'tests.log.2', 'tests.log.1']);
|
|
||||||
//and opened a new log file
|
|
||||||
assert.length(filesOpened, 4);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'configure' : {
|
|
||||||
topic: function() {
|
|
||||||
var messages = {}, fakeFS = {
|
|
||||||
createWriteStream: function(file) {
|
|
||||||
return {
|
|
||||||
write: function(message) {
|
|
||||||
if (!messages.hasOwnProperty(file)) {
|
|
||||||
messages[file] = [];
|
|
||||||
}
|
|
||||||
messages[file].push(message);
|
|
||||||
}
|
|
||||||
, end: function() {}
|
|
||||||
, destroySoon: function() {}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
readFileSync: function(file, encoding) {
|
|
||||||
return require('fs').readFileSync(file, encoding);
|
|
||||||
},
|
|
||||||
watchFile: function(file) {
|
|
||||||
messages.watchedFile = file;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
log4js = sandbox.require(
|
|
||||||
'../lib/log4js'
|
|
||||||
, {
|
|
||||||
requires: {
|
|
||||||
'fs': fakeFS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
return [ log4js, messages ];
|
, config = {
|
||||||
},
|
|
||||||
'should load appender configuration from a json file': function(args) {
|
|
||||||
var log4js = args[0], messages = args[1];
|
|
||||||
delete messages['tmp-tests.log'];
|
|
||||||
log4js.clearAppenders();
|
|
||||||
//this config file defines one file appender (to ./tmp-tests.log)
|
|
||||||
//and sets the log level for "tests" to WARN
|
|
||||||
log4js.configure('test/log4js.json');
|
|
||||||
var logger = log4js.getLogger("tests");
|
|
||||||
logger.info('this should not be written to the file');
|
|
||||||
logger.warn('this should be written to the file');
|
|
||||||
assert.length(messages['tmp-tests.log'], 1);
|
|
||||||
assert.equal(messages['tmp-tests.log'][0], 'this should be written to the file\n');
|
|
||||||
},
|
|
||||||
'should handle logLevelFilter configuration': function(args) {
|
|
||||||
var log4js = args[0], messages = args[1];
|
|
||||||
delete messages['tmp-tests.log'];
|
|
||||||
delete messages['tmp-tests-warnings.log'];
|
|
||||||
log4js.clearAppenders();
|
|
||||||
log4js.configure('test/with-logLevelFilter.json');
|
|
||||||
var logger = log4js.getLogger("tests");
|
|
||||||
logger.info('main');
|
|
||||||
logger.error('both');
|
|
||||||
logger.warn('both');
|
|
||||||
logger.debug('main');
|
|
||||||
|
|
||||||
assert.length(messages['tmp-tests.log'], 4);
|
|
||||||
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-warnings.log'], ['both\n','both\n']);
|
|
||||||
},
|
|
||||||
'should handle fileAppender with log rolling' : function(args) {
|
|
||||||
var log4js = args[0], messages = args[1];
|
|
||||||
delete messages['tmp-test.log'];
|
|
||||||
log4js.configure('test/with-log-rolling.json');
|
|
||||||
assert.equal(messages.watchedFile, 'tmp-test.log');
|
|
||||||
},
|
|
||||||
'should handle an object or a file name': function(args) {
|
|
||||||
var log4js = args[0],
|
|
||||||
messages = args[1],
|
|
||||||
config = {
|
|
||||||
"appenders": [
|
"appenders": [
|
||||||
{
|
{
|
||||||
"type" : "file",
|
"type" : "file",
|
||||||
@@ -284,34 +92,88 @@ vows.describe('log4js').addBatch({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
delete messages['cheesy-wotsits.log'];
|
|
||||||
log4js.configure(config);
|
log4js.configure(config);
|
||||||
assert.equal(messages.watchedFile, 'cheesy-wotsits.log');
|
return appenderConfig;
|
||||||
|
},
|
||||||
|
'should be passed to appender config': function(configuration) {
|
||||||
|
assert.equal(configuration.filename, 'cheesy-wotsits.log');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'configuration when passed as filename': {
|
||||||
|
topic: function() {
|
||||||
|
var appenderConfig
|
||||||
|
, configFilename
|
||||||
|
, log4js = sandbox.require(
|
||||||
|
'../lib/log4js'
|
||||||
|
, { requires:
|
||||||
|
{ 'fs':
|
||||||
|
{
|
||||||
|
readFileSync: function(filename) {
|
||||||
|
configFilename = filename;
|
||||||
|
return JSON.stringify({
|
||||||
|
appenders: [
|
||||||
|
{ type: "file"
|
||||||
|
, filename: "whatever.log"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
readdirSync: function() {
|
||||||
|
return ['file.js'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, './appenders/file.js':
|
||||||
|
{
|
||||||
|
name: "file"
|
||||||
|
, appender: function() {}
|
||||||
|
, configure: function(configuration) {
|
||||||
|
appenderConfig = configuration;
|
||||||
|
return function() {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
log4js.configure("/path/to/cheese.json");
|
||||||
|
return [ configFilename, appenderConfig ];
|
||||||
|
},
|
||||||
|
'should read the config from a file': function(args) {
|
||||||
|
assert.equal(args[0], '/path/to/cheese.json');
|
||||||
|
},
|
||||||
|
'should pass config to appender': function(args) {
|
||||||
|
assert.equal(args[1].filename, "whatever.log");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'with no appenders defined' : {
|
'with no appenders defined' : {
|
||||||
topic: function() {
|
topic: function() {
|
||||||
var logger
|
var logger
|
||||||
, message
|
, that = this
|
||||||
|
, fakeConsoleAppender = {
|
||||||
|
name: "console"
|
||||||
|
, appender: function() {
|
||||||
|
return function(evt) {
|
||||||
|
that.callback(null, evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, configure: function() {
|
||||||
|
return fakeConsoleAppender.appender();
|
||||||
|
}
|
||||||
|
}
|
||||||
, log4js = sandbox.require(
|
, log4js = sandbox.require(
|
||||||
'../lib/log4js'
|
'../lib/log4js'
|
||||||
, {
|
, {
|
||||||
globals: {
|
requires: {
|
||||||
console: {
|
'./appenders/console.js': fakeConsoleAppender
|
||||||
log: function(msg) {
|
}
|
||||||
message = msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
);
|
||||||
logger = log4js.getLogger("some-logger");
|
logger = log4js.getLogger("some-logger");
|
||||||
logger.debug("This is a test");
|
logger.debug("This is a test");
|
||||||
return message;
|
|
||||||
},
|
},
|
||||||
'should default to the console appender': function(message) {
|
'should default to the console appender': function(evt) {
|
||||||
assert.isTrue(/This is a test$/.test(message));
|
assert.equal(evt.data[0], "This is a test");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -403,10 +265,13 @@ vows.describe('log4js').addBatch({
|
|||||||
'default setup': {
|
'default setup': {
|
||||||
topic: function() {
|
topic: function() {
|
||||||
var pathsChecked = [],
|
var pathsChecked = [],
|
||||||
message,
|
appenderEvent,
|
||||||
logger,
|
logger,
|
||||||
modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
|
modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
|
||||||
fakeFS = {
|
fakeFS = {
|
||||||
|
readdirSync: function(dir) {
|
||||||
|
return require('fs').readdirSync(dir);
|
||||||
|
},
|
||||||
readFileSync: function (file, encoding) {
|
readFileSync: function (file, encoding) {
|
||||||
assert.equal(file, modulePath);
|
assert.equal(file, modulePath);
|
||||||
assert.equal(encoding, 'utf8');
|
assert.equal(encoding, 'utf8');
|
||||||
@@ -422,28 +287,27 @@ vows.describe('log4js').addBatch({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
fakeConsole = {
|
fakeConsole = {
|
||||||
log : function (msg) { message = msg; },
|
'name': 'console'
|
||||||
info: this.log,
|
, 'appender': function () {
|
||||||
warn: this.log,
|
return function(evt) { appenderEvent = evt; }
|
||||||
debug: this.log,
|
}
|
||||||
error: this.log
|
, 'configure': function (config) {
|
||||||
|
return fakeConsole.appender();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
log4js = sandbox.require(
|
log4js = sandbox.require(
|
||||||
'../lib/log4js',
|
'../lib/log4js',
|
||||||
{
|
{
|
||||||
requires: {
|
requires: {
|
||||||
'fs': fakeFS
|
'fs': fakeFS
|
||||||
},
|
, './appenders/console.js': fakeConsole
|
||||||
globals: {
|
|
||||||
'console': fakeConsole
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
logger = log4js.getLogger('a-test');
|
logger = log4js.getLogger('a-test');
|
||||||
logger.debug("this is a test");
|
logger.debug("this is a test");
|
||||||
|
return [ pathsChecked, appenderEvent, modulePath ];
|
||||||
return [ pathsChecked, message, modulePath ];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
'should check current directory, require paths, and finally the module dir for log4js.json': function(args) {
|
'should check current directory, require paths, and finally the module dir for log4js.json': function(args) {
|
||||||
@@ -458,27 +322,8 @@ vows.describe('log4js').addBatch({
|
|||||||
},
|
},
|
||||||
|
|
||||||
'should configure log4js from first log4js.json found': function(args) {
|
'should configure log4js from first log4js.json found': function(args) {
|
||||||
var message = args[1];
|
var appenderEvent = args[1];
|
||||||
assert.equal(message, 'this is a test');
|
assert.equal(appenderEvent.data[0], 'this is a test');
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'logLevelFilter': {
|
|
||||||
topic: function() {
|
|
||||||
var log4js = require('../lib/log4js'), logEvents = [], logger;
|
|
||||||
log4js.clearAppenders();
|
|
||||||
log4js.addAppender(log4js.logLevelFilter('ERROR', function(evt) { logEvents.push(evt); }), "logLevelTest");
|
|
||||||
logger = log4js.getLogger("logLevelTest");
|
|
||||||
logger.debug('this should not trigger an event');
|
|
||||||
logger.warn('neither should this');
|
|
||||||
logger.error('this should, though');
|
|
||||||
logger.fatal('so should this');
|
|
||||||
return logEvents;
|
|
||||||
},
|
|
||||||
'should only pass log events greater than or equal to its own level' : function(logEvents) {
|
|
||||||
assert.length(logEvents, 2);
|
|
||||||
assert.equal(logEvents[0].data[0], 'this should, though');
|
|
||||||
assert.equal(logEvents[1].data[0], 'so should this');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -549,12 +394,15 @@ vows.describe('log4js').addBatch({
|
|||||||
'configuration reload' : {
|
'configuration reload' : {
|
||||||
topic: function() {
|
topic: function() {
|
||||||
var pathsChecked = [],
|
var pathsChecked = [],
|
||||||
messages = [],
|
logEvents = [],
|
||||||
logger,
|
logger,
|
||||||
modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
|
modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
|
||||||
fakeFS = {
|
fakeFS = {
|
||||||
config: { appenders: [ { type: 'console', layout: { type: 'messagePassThrough' } } ],
|
config: { appenders: [ { type: 'console', layout: { type: 'messagePassThrough' } } ],
|
||||||
levels: { 'a-test' : 'INFO' } },
|
levels: { 'a-test' : 'INFO' } },
|
||||||
|
readdirSync: function(dir) {
|
||||||
|
return require('fs').readdirSync(dir);
|
||||||
|
},
|
||||||
readFileSync: function (file, encoding) {
|
readFileSync: function (file, encoding) {
|
||||||
assert.equal(file, modulePath);
|
assert.equal(file, modulePath);
|
||||||
assert.equal(encoding, 'utf8');
|
assert.equal(encoding, 'utf8');
|
||||||
@@ -570,11 +418,13 @@ vows.describe('log4js').addBatch({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
fakeConsole = {
|
fakeConsole = {
|
||||||
log : function (msg) { messages.push(msg); },
|
'name': 'console',
|
||||||
info: this.log,
|
'appender': function () {
|
||||||
warn: this.log,
|
return function(evt) { logEvents.push(evt); };
|
||||||
debug: this.log,
|
},
|
||||||
error: this.log
|
'configure': function (config) {
|
||||||
|
return fakeConsole.appender();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setIntervalCallback,
|
setIntervalCallback,
|
||||||
fakeSetInterval = function(cb, timeout) {
|
fakeSetInterval = function(cb, timeout) {
|
||||||
@@ -584,7 +434,8 @@ vows.describe('log4js').addBatch({
|
|||||||
'../lib/log4js',
|
'../lib/log4js',
|
||||||
{
|
{
|
||||||
requires: {
|
requires: {
|
||||||
'fs': fakeFS
|
'fs': fakeFS,
|
||||||
|
'./appenders/console.js': fakeConsole
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
'console': fakeConsole,
|
'console': fakeConsole,
|
||||||
@@ -601,14 +452,14 @@ vows.describe('log4js').addBatch({
|
|||||||
logger.info("info3");
|
logger.info("info3");
|
||||||
logger.debug("debug4");
|
logger.debug("debug4");
|
||||||
|
|
||||||
return [ pathsChecked, messages, modulePath ];
|
return [ pathsChecked, logEvents, modulePath ];
|
||||||
},
|
},
|
||||||
'should configure log4js from first log4js.json found': function(args) {
|
'should configure log4js from first log4js.json found': function(args) {
|
||||||
var messages = args[1];
|
var logEvents = args[1];
|
||||||
assert.length(messages, 3);
|
assert.length(logEvents, 3);
|
||||||
assert.equal(messages[0], 'info1');
|
assert.equal(logEvents[0].data[0], 'info1');
|
||||||
assert.equal(messages[1], 'info3');
|
assert.equal(logEvents[1].data[0], 'info3');
|
||||||
assert.equal(messages[2], 'debug4');
|
assert.equal(logEvents[2].data[0], 'debug4');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"level": "WARN",
|
"level": "WARN",
|
||||||
"appender": {
|
"appender": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"filename": "tmp-tests-warnings.log",
|
"filename": "test/logLevelFilter-warnings.log",
|
||||||
"layout": {
|
"layout": {
|
||||||
"type": "messagePassThrough"
|
"type": "messagePassThrough"
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
{
|
{
|
||||||
"category": "tests",
|
"category": "tests",
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"filename": "tmp-tests.log",
|
"filename": "test/logLevelFilter.log",
|
||||||
"layout": {
|
"layout": {
|
||||||
"type": "messagePassThrough"
|
"type": "messagePassThrough"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user