fixed all lint errors except ones which require refactoring of code

This commit is contained in:
Gareth Jones 2013-06-04 08:17:36 +10:00
parent f998d7e81a
commit 5d6f00eda4
12 changed files with 792 additions and 698 deletions

View File

@ -1,15 +1,16 @@
var streams = require('../streams'), "use strict";
layouts = require('../layouts'), var streams = require('../streams')
path = require('path'), , layouts = require('../layouts')
os = require('os'), , path = require('path')
eol = os.EOL || '\n', , os = require('os')
openFiles = []; , eol = os.EOL || '\n'
, openFiles = [];
//close open files on process exit. //close open files on process exit.
process.on('exit', function() { process.on('exit', function() {
openFiles.forEach(function (file) { openFiles.forEach(function (file) {
file.end(); file.end();
}); });
}); });
/** /**
@ -20,33 +21,37 @@ process.on('exit', function() {
* @layout layout function for log messages - defaults to basicLayout * @layout layout function for log messages - defaults to basicLayout
*/ */
function appender(filename, pattern, alwaysIncludePattern, layout) { function appender(filename, pattern, alwaysIncludePattern, layout) {
layout = layout || layouts.basicLayout; layout = layout || layouts.basicLayout;
var logFile = new streams.DateRollingFileStream(filename, pattern, { alwaysIncludePattern: alwaysIncludePattern }); var logFile = new streams.DateRollingFileStream(
openFiles.push(logFile); filename,
pattern,
return function(logEvent) { { alwaysIncludePattern: alwaysIncludePattern }
logFile.write(layout(logEvent) + eol, "utf8"); );
}; openFiles.push(logFile);
return function(logEvent) {
logFile.write(layout(logEvent) + eol, "utf8");
};
} }
function configure(config, options) { function configure(config, options) {
var layout; var layout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
if (!config.alwaysIncludePattern) {
config.alwaysIncludePattern = false;
}
if (options && options.cwd && !config.absolute) {
config.filename = path.join(options.cwd, config.filename);
}
if (config.layout) { return appender(config.filename, config.pattern, config.alwaysIncludePattern, layout);
layout = layouts.layout(config.layout.type, config.layout);
}
if (!config.alwaysIncludePattern) {
config.alwaysIncludePattern = false;
}
if (options && options.cwd && !config.absolute) {
config.filename = path.join(options.cwd, config.filename);
}
return appender(config.filename, config.pattern, config.alwaysIncludePattern, layout);
} }
exports.appender = appender; exports.appender = appender;

View File

@ -1,25 +1,29 @@
"use strict";
var layouts = require('../layouts') var layouts = require('../layouts')
, path = require('path') , path = require('path')
, fs = require('fs') , fs = require('fs')
, streams = require('../streams') , streams = require('../streams')
, os = require('os') , os = require('os')
, eol = os.EOL || '\n' , eol = os.EOL || '\n'
, openFiles = []; , openFiles = [];
//close open files on process exit. //close open files on process exit.
process.on('exit', function() { process.on('exit', function() {
openFiles.forEach(function (file) { openFiles.forEach(function (file) {
file.end(); file.end();
}); });
}); });
/** /**
* File Appender writing the logs to a text file. Supports rolling of logs by size. * 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 file file log messages will be written to
* @param layout a function that takes a logevent and returns a string (defaults to basicLayout). * @param layout a function that takes a logevent and returns a string
* @param logSize - the maximum size (in bytes) for a log file, if not provided then logs won't be rotated. * (defaults to basicLayout).
* @param numBackups - the number of log files to keep after logSize has been reached (default 5) * @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)
*/ */
function fileAppender (file, layout, logSize, numBackups) { function fileAppender (file, layout, logSize, numBackups) {
var bytesWritten = 0; var bytesWritten = 0;
@ -38,7 +42,12 @@ function fileAppender (file, layout, logSize, numBackups) {
numFiles numFiles
); );
} else { } else {
stream = fs.createWriteStream(file, { encoding: "utf8", mode: 0644, flags: 'a' }); stream = fs.createWriteStream(
file,
{ encoding: "utf8",
mode: parseInt('0644', 8),
flags: 'a' }
);
} }
stream.on("error", function (err) { stream.on("error", function (err) {
console.error("log4js.fileAppender - Writing to file %s, error happened ", file, err); console.error("log4js.fileAppender - Writing to file %s, error happened ", file, err);

View File

@ -1,3 +1,4 @@
"use strict";
var zlib = require('zlib'); var zlib = require('zlib');
var layouts = require('../layouts'); var layouts = require('../layouts');
var levels = require('../levels'); var levels = require('../levels');
@ -23,6 +24,13 @@ levelMapping[levels.WARN] = LOG_WARNING;
levelMapping[levels.ERROR] = LOG_ERR; levelMapping[levels.ERROR] = LOG_ERR;
levelMapping[levels.FATAL] = LOG_CRIT; levelMapping[levels.FATAL] = LOG_CRIT;
var debug;
if (process.env.NODE_DEBUG && /\blog4js\b/.test(process.env.NODE_DEBUG)) {
debug = function(message) { console.error('LOG4JS: (GELF Appender) %s', message); };
} else {
debug = function() { };
}
/** /**
* GELF appender that supports sending UDP packets to a GELF compatible server such as Graylog * GELF appender that supports sending UDP packets to a GELF compatible server such as Graylog
* *
@ -33,60 +41,60 @@ levelMapping[levels.FATAL] = LOG_CRIT;
* @param facility - facility to log to (default:nodejs-server) * @param facility - facility to log to (default:nodejs-server)
*/ */
function gelfAppender (layout, host, port, hostname, facility) { function gelfAppender (layout, host, port, hostname, facility) {
host = host || 'localhost';
port = port || 12201;
hostname = hostname || require('os').hostname();
facility = facility || 'nodejs-server';
layout = layout || layouts.messagePassThroughLayout;
var client = dgram.createSocket("udp4");
process.on('exit', function() {
if (client) client.close();
});
function preparePacket(loggingEvent) {
var msg = {};
msg.full_message = layout(loggingEvent);
msg.short_message = msg.full_message;
msg.version="1.0";
msg.timestamp = msg.timestamp || new Date().getTime() / 1000 >> 0;
msg.host = hostname;
msg.level = levelMapping[loggingEvent.level || levels.DEBUG];
msg.facility = facility;
return msg;
}
function sendPacket(packet) {
try {
client.send(packet, 0, packet.length, port, host);
} catch(e) {}
}
host = host || 'localhost'; return function(loggingEvent) {
port = port || 12201; var message = preparePacket(loggingEvent);
hostname = hostname || require('os').hostname(); zlib.gzip(new Buffer(JSON.stringify(message)), function(err, packet) {
facility = facility || 'nodejs-server'; if (err) {
layout = layout || layouts.messagePassThroughLayout; console.error(err.stack);
} else {
var client = dgram.createSocket("udp4"); if (packet.length > 8192) {
debug("Message packet length (" + packet.length + ") is larger than 8k. Not sending");
process.on('exit', function() { } else {
if (client) client.close(); sendPacket(packet);
}
}
}); });
};
function preparePacket(loggingEvent) {
var msg = {};
msg.full_message = layout(loggingEvent);
msg.short_message = msg.full_message;
msg.version="1.0";
msg.timestamp = msg.timestamp || new Date().getTime() / 1000 >> 0;
msg.host = hostname;
msg.level = levelMapping[loggingEvent.level || levels.DEBUG];
msg.facility = facility;
return msg;
}
function sendPacket(packet) {
try {
client.send(packet, 0, packet.length, port, host);
} catch(e) {}
}
return function(loggingEvent) {
var message = preparePacket(loggingEvent);
zlib.gzip(new Buffer(JSON.stringify(message)), function(err, packet) {
if (err) {
console.error(err.stack);
} else {
if (packet.length > 8192) {
util.debug("Message packet length (" + packet.length + ") is larger than 8k. Not sending");
} else {
sendPacket(packet);
}
}
});
};
} }
function configure(config) { function configure(config) {
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 gelfAppender(layout, config.host, config.port, config.hostname, config.facility); return gelfAppender(layout, config.host, config.port, config.hostname, config.facility);
} }
exports.appender = gelfAppender; exports.appender = gelfAppender;

View File

@ -1,7 +1,8 @@
var log4js = require('../log4js'); "use strict";
var layouts = require('../layouts'); var log4js = require('../log4js')
var Hook = require('hook.io').Hook; , layouts = require('../layouts')
var util = require('util'); , Hook = require('hook.io').Hook
, util = require('util');
var Logger = function createLogger(options) { var Logger = function createLogger(options) {
var self = this; var self = this;
@ -13,7 +14,7 @@ var Logger = function createLogger(options) {
actualAppender(loggingEvent); actualAppender(loggingEvent);
}); });
}); });
} };
util.inherits(Logger, Hook); util.inherits(Logger, Hook);
function deserializeLoggingEvent(loggingEvent) { function deserializeLoggingEvent(loggingEvent) {
@ -42,7 +43,7 @@ function getBufferedHook(hook, eventName) {
hook.on('hook::ready', function emptyBuffer() { hook.on('hook::ready', function emptyBuffer() {
hookBuffer.forEach(function logBufferItem(loggingEvent) { hookBuffer.forEach(function logBufferItem(loggingEvent) {
hook.emit(eventName, loggingEvent); hook.emit(eventName, loggingEvent);
}) });
hookReady = true; hookReady = true;
}); });
@ -52,7 +53,7 @@ function getBufferedHook(hook, eventName) {
} else { } else {
hookBuffer.push(loggingEvent); hookBuffer.push(loggingEvent);
} }
} };
} }
function createAppender(hookioOptions) { function createAppender(hookioOptions) {

View File

@ -1,19 +1,20 @@
var levels = require('../levels'); "use strict";
var log4js = require('../log4js'); var levels = require('../levels')
, log4js = require('../log4js');
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);
}
} }
};
} }
function configure(config) { function configure(config) {
log4js.loadAppender(config.appender.type); log4js.loadAppender(config.appender.type);
var appender = log4js.appenderMakers[config.appender.type](config.appender); var appender = log4js.appenderMakers[config.appender.type](config.appender);
return logLevelFilter(config.level, appender); return logLevelFilter(config.level, appender);
} }
exports.appender = logLevelFilter; exports.appender = logLevelFilter;

View File

@ -1,6 +1,7 @@
var log4js = require('../log4js'), "use strict";
net = require('net'), var log4js = require('../log4js')
END_MSG = '__LOG4JS__'; , net = require('net')
, END_MSG = '__LOG4JS__';
/** /**
* Creates a server, listening on config.loggerPort, config.loggerHost. * Creates a server, listening on config.loggerPort, config.loggerHost.
@ -8,120 +9,120 @@ var log4js = require('../log4js'),
* set up that appender). * set up that appender).
*/ */
function logServer(config) { function logServer(config) {
/** /**
* Takes a utf-8 string, returns an object with * Takes a utf-8 string, returns an object with
* the correct log properties. * the correct log properties.
*/ */
function deserializeLoggingEvent(clientSocket, msg) { function deserializeLoggingEvent(clientSocket, msg) {
var loggingEvent; var loggingEvent;
try { try {
loggingEvent = JSON.parse(msg); loggingEvent = JSON.parse(msg);
loggingEvent.startTime = new Date(loggingEvent.startTime); loggingEvent.startTime = new Date(loggingEvent.startTime);
loggingEvent.level = log4js.levels.toLevel(loggingEvent.level.levelStr); loggingEvent.level = log4js.levels.toLevel(loggingEvent.level.levelStr);
} catch (e) { } catch (e) {
// JSON.parse failed, just log the contents probably a naughty. // JSON.parse failed, just log the contents probably a naughty.
loggingEvent = { loggingEvent = {
startTime: new Date(), startTime: new Date(),
categoryName: 'log4js', categoryName: 'log4js',
level: log4js.levels.ERROR, level: log4js.levels.ERROR,
data: [ 'Unable to parse log:', msg ] data: [ 'Unable to parse log:', msg ]
}; };
}
loggingEvent.remoteAddress = clientSocket.remoteAddress;
loggingEvent.remotePort = clientSocket.remotePort;
return loggingEvent;
} }
var actualAppender = config.actualAppender, loggingEvent.remoteAddress = clientSocket.remoteAddress;
server = net.createServer(function serverCreated(clientSocket) { loggingEvent.remotePort = clientSocket.remotePort;
clientSocket.setEncoding('utf8');
var logMessage = ''; return loggingEvent;
}
function logTheMessage(msg) {
if (logMessage.length > 0) { var actualAppender = config.actualAppender,
actualAppender(deserializeLoggingEvent(clientSocket, msg)); server = net.createServer(function serverCreated(clientSocket) {
} clientSocket.setEncoding('utf8');
} var logMessage = '';
function chunkReceived(chunk) { function logTheMessage(msg) {
var event; if (logMessage.length > 0) {
logMessage += chunk || ''; actualAppender(deserializeLoggingEvent(clientSocket, msg));
if (logMessage.indexOf(END_MSG) > -1) { }
event = logMessage.substring(0, logMessage.indexOf(END_MSG)); }
logTheMessage(event);
logMessage = logMessage.substring(event.length + END_MSG.length) || ''; function chunkReceived(chunk) {
//check for more, maybe it was a big chunk var event;
chunkReceived(); logMessage += chunk || '';
} if (logMessage.indexOf(END_MSG) > -1) {
} event = logMessage.substring(0, logMessage.indexOf(END_MSG));
logTheMessage(event);
clientSocket.on('data', chunkReceived); logMessage = logMessage.substring(event.length + END_MSG.length) || '';
clientSocket.on('end', chunkReceived); //check for more, maybe it was a big chunk
}); chunkReceived();
}
server.listen(config.loggerPort || 5000, config.loggerHost || 'localhost'); }
return actualAppender; clientSocket.on('data', chunkReceived);
clientSocket.on('end', chunkReceived);
});
server.listen(config.loggerPort || 5000, config.loggerHost || 'localhost');
return actualAppender;
} }
function workerAppender(config) { function workerAppender(config) {
var canWrite = false, var canWrite = false,
buffer = [], buffer = [],
socket; socket;
createSocket(); createSocket();
function createSocket() { function createSocket() {
socket = net.createConnection(config.loggerPort || 5000, config.loggerHost || 'localhost'); socket = net.createConnection(config.loggerPort || 5000, config.loggerHost || 'localhost');
socket.on('connect', function() { socket.on('connect', function() {
emptyBuffer(); emptyBuffer();
canWrite = true; canWrite = true;
}); });
socket.on('timeout', socket.end.bind(socket)); socket.on('timeout', socket.end.bind(socket));
//don't bother listening for 'error', 'close' gets called after that anyway //don't bother listening for 'error', 'close' gets called after that anyway
socket.on('close', createSocket); socket.on('close', createSocket);
}
function emptyBuffer() {
var evt;
while ((evt = buffer.shift())) {
write(evt);
} }
}
function emptyBuffer() {
var evt; function write(loggingEvent) {
while ((evt = buffer.shift())) { socket.write(JSON.stringify(loggingEvent), 'utf8');
write(evt); socket.write(END_MSG, 'utf8');
} }
return function log(loggingEvent) {
if (canWrite) {
write(loggingEvent);
} else {
buffer.push(loggingEvent);
} }
};
function write(loggingEvent) {
socket.write(JSON.stringify(loggingEvent), 'utf8');
socket.write(END_MSG, 'utf8');
}
return function log(loggingEvent) {
if (canWrite) {
write(loggingEvent);
} else {
buffer.push(loggingEvent);
}
};
} }
function createAppender(config) { function createAppender(config) {
if (config.mode === 'master') { if (config.mode === 'master') {
return logServer(config); return logServer(config);
} else { } else {
return workerAppender(config); return workerAppender(config);
} }
} }
function configure(config, options) { function configure(config, options) {
var actualAppender; var actualAppender;
if (config.appender && config.mode === 'master') { if (config.appender && config.mode === 'master') {
log4js.loadAppender(config.appender.type); log4js.loadAppender(config.appender.type);
actualAppender = log4js.appenderMakers[config.appender.type](config.appender, options); actualAppender = log4js.appenderMakers[config.appender.type](config.appender, options);
config.actualAppender = actualAppender; config.actualAppender = actualAppender;
} }
return createAppender(config); return createAppender(config);
} }
exports.appender = createAppender; exports.appender = createAppender;

View File

@ -1,14 +1,17 @@
var layouts = require("../layouts"), "use strict";
mailer = require("nodemailer"), var layouts = require("../layouts")
os = require('os'); , mailer = require("nodemailer")
, os = require('os');
/** /**
* SMTP Appender. Sends logging events using SMTP protocol. * SMTP Appender. Sends logging events using SMTP protocol.
* It can either send an email on each event or group several logging events gathered during specified interval. * It can either send an email on each event or group several
* logging events gathered during specified interval.
* *
* @param config appender configuration data * @param config appender configuration data
* config.sendInterval time between log emails (in seconds), if 0
* then every event sends an email
* @param layout a function that takes a logevent and returns a string (defaults to basicLayout). * @param layout a function that takes a logevent and returns a string (defaults to basicLayout).
* all events are buffered and sent in one email during this time; if 0 than every event sends an email
*/ */
function smtpAppender(config, layout) { function smtpAppender(config, layout) {
layout = layout || layouts.basicLayout; layout = layout || layouts.basicLayout;
@ -19,7 +22,7 @@ function smtpAppender(config, layout) {
var sendTimer; var sendTimer;
function sendBuffer() { function sendBuffer() {
if (logEventBuffer.length == 0) { if (logEventBuffer.length === 0) {
return; return;
} }
@ -31,11 +34,11 @@ function smtpAppender(config, layout) {
} }
var msg = { var msg = {
to: config.recipients, to: config.recipients,
subject: config.subject || subjectLayout(firstEvent), subject: config.subject || subjectLayout(firstEvent),
text: body, text: body,
headers: {"Hostname": os.hostname()} headers: {"Hostname": os.hostname()}
}; };
if (config.sender) { if (config.sender) {
msg.from = config.sender; msg.from = config.sender;
} }

View File

@ -1,4 +1,9 @@
"use strict";
var levels = require("./levels"); var levels = require("./levels");
var DEFAULT_FORMAT = ':remote-addr - -' +
' ":method :url HTTP/:http-version"' +
' :status :content-length ":referrer"' +
' ":user-agent"';
/** /**
* Log requests with the given `options` or a `format` string. * Log requests with the given `options` or a `format` string.
* *
@ -26,7 +31,7 @@ var levels = require("./levels");
* @api public * @api public
*/ */
function getLogger(logger4js, options) { function getLogger(logger4js, options) {
if ('object' == typeof options) { if ('object' == typeof options) {
options = options || {}; options = options || {};
} else if (options) { } else if (options) {
@ -36,20 +41,19 @@ var levels = require("./levels");
} }
var thislogger = logger4js var thislogger = logger4js
, level = levels.toLevel(options.level, levels.INFO) , level = levels.toLevel(options.level, levels.INFO)
, fmt = options.format || ':remote-addr - - ":method :url HTTP/:http-version" :status :content-length ":referrer" ":user-agent"' , fmt = options.format || DEFAULT_FORMAT
, nolog = options.nolog ? createNoLogCondition(options.nolog) : null; , nolog = options.nolog ? createNoLogCondition(options.nolog) : null;
return function (req, res, next) { return function (req, res, next) {
// mount safety
// mount safety if (req._logging) return next();
if (req._logging) return next();
// nologs // nologs
if (nolog && nolog.test(req.originalUrl)) return next(); if (nolog && nolog.test(req.originalUrl)) return next();
if (thislogger.isLevelEnabled(level) || options.level === 'auto') { if (thislogger.isLevelEnabled(level) || options.level === 'auto') {
var start = +new Date var start = new Date()
, statusCode , statusCode
, writeHead = res.writeHead , writeHead = res.writeHead
, end = res.end , end = res.end
@ -57,7 +61,7 @@ var levels = require("./levels");
// flag as logging // flag as logging
req._logging = true; req._logging = true;
// proxy for statusCode. // proxy for statusCode.
res.writeHead = function(code, headers){ res.writeHead = function(code, headers){
res.writeHead = writeHead; res.writeHead = writeHead;
@ -71,15 +75,15 @@ var levels = require("./levels");
if(code >= 300) level = levels.WARN; if(code >= 300) level = levels.WARN;
if(code >= 400) level = levels.ERROR; if(code >= 400) level = levels.ERROR;
} else { } else {
level = levels.toLevel(options.level, levels.INFO) level = levels.toLevel(options.level, levels.INFO);
} }
}; };
// proxy end to output a line to the provided logger. // proxy end to output a line to the provided logger.
res.end = function(chunk, encoding) { res.end = function(chunk, encoding) {
res.end = end; res.end = end;
res.end(chunk, encoding); res.end(chunk, encoding);
res.responseTime = +new Date - start; res.responseTime = new Date() - start;
if (thislogger.isLevelEnabled(level)) { if (thislogger.isLevelEnabled(level)) {
if (typeof fmt === 'function') { if (typeof fmt === 'function') {
var line = fmt(req, res, function(str){ return format(str, req, res); }); var line = fmt(req, res, function(str){ return format(str, req, res); });
@ -90,10 +94,10 @@ var levels = require("./levels");
} }
}; };
} }
//ensure next gets always called //ensure next gets always called
next(); next();
}; };
} }
/** /**
@ -106,25 +110,34 @@ var levels = require("./levels");
* @api private * @api private
*/ */
function format(str, req, res) { function format(str, req, res) {
return str return str
.replace(':url', req.originalUrl) .replace(':url', req.originalUrl)
.replace(':method', req.method) .replace(':method', req.method)
.replace(':status', res.__statusCode || res.statusCode) .replace(':status', res.__statusCode || res.statusCode)
.replace(':response-time', res.responseTime) .replace(':response-time', res.responseTime)
.replace(':date', new Date().toUTCString()) .replace(':date', new Date().toUTCString())
.replace(':referrer', req.headers['referer'] || req.headers['referrer'] || '') .replace(':referrer', req.headers.referer || req.headers.referrer || '')
.replace(':http-version', req.httpVersionMajor + '.' + req.httpVersionMinor) .replace(':http-version', req.httpVersionMajor + '.' + req.httpVersionMinor)
.replace(':remote-addr', req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress))) .replace(
.replace(':user-agent', req.headers['user-agent'] || '') ':remote-addr',
.replace(':content-length', (res._headers && res._headers['content-length']) || (res.__headers && res.__headers['Content-Length']) || '-') req.socket &&
.replace(/:req\[([^\]]+)\]/g, function(_, field){ return req.headers[field.toLowerCase()]; }) (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress))
.replace(/:res\[([^\]]+)\]/g, function(_, field){ )
return res._headers .replace(':user-agent', req.headers['user-agent'] || '')
? (res._headers[field.toLowerCase()] || res.__headers[field]) .replace(
: (res.__headers && res.__headers[field]); ':content-length',
}); (res._headers && res._headers['content-length']) ||
} (res.__headers && res.__headers['Content-Length']) ||
'-'
)
.replace(/:req\[([^\]]+)\]/g, function(_, field){ return req.headers[field.toLowerCase()]; })
.replace(/:res\[([^\]]+)\]/g, function(_, field){
return res._headers ?
(res._headers[field.toLowerCase()] || res.__headers[field])
: (res.__headers && res.__headers[field]);
});
}
/** /**
* Return RegExp Object about nolog * Return RegExp Object about nolog
@ -141,8 +154,10 @@ var levels = require("./levels");
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga * NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga
* LOGGING http://example.com/hoge.agif * LOGGING http://example.com/hoge.agif
* 1.2 in "\\.gif|\\.jpg$" * 1.2 in "\\.gif|\\.jpg$"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga and http://example.com/hoge.jpg?fuga * NOT LOGGING http://example.com/hoge.gif and
* LOGGING http://example.com/hoge.agif, http://example.com/hoge.ajpg and http://example.com/hoge.jpg?hoge * http://example.com/hoge.gif?fuga and http://example.com/hoge.jpg?fuga
* LOGGING http://example.com/hoge.agif,
* http://example.com/hoge.ajpg and http://example.com/hoge.jpg?hoge
* 1.3 in "\\.(gif|jpe?g|png)$" * 1.3 in "\\.(gif|jpe?g|png)$"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.jpeg * NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.jpeg
* LOGGING http://example.com/hoge.gif?uid=2 and http://example.com/hoge.jpg?pid=3 * LOGGING http://example.com/hoge.gif?uid=2 and http://example.com/hoge.jpg?pid=3
@ -153,26 +168,28 @@ var levels = require("./levels");
* 3.1 ["\\.jpg$", "\\.png", "\\.gif"] * 3.1 ["\\.jpg$", "\\.png", "\\.gif"]
* SAME AS "\\.jpg|\\.png|\\.gif" * SAME AS "\\.jpg|\\.png|\\.gif"
*/ */
function createNoLogCondition(nolog, type) { function createNoLogCondition(nolog, type) {
if(!nolog) return null; if (!nolog) return null;
type = type || ''; type = type || '';
if(nolog instanceof RegExp){ if (nolog instanceof RegExp) {
if(type === 'string') if (type === 'string') {
return nolog.source; return nolog.source;
}
return nolog; return nolog;
} else if(typeof nolog === 'string'){ } else if (typeof nolog === 'string') {
if(type === 'string') if (type === 'string') {
return nolog; return nolog;
try{ }
try {
return new RegExp(nolog); return new RegExp(nolog);
} catch (ex) { } catch (ex) {
return null; return null;
} }
} else if(nolog instanceof Array){ } else if (nolog instanceof Array) {
var regexps = nolog.map(function(o){ return createNoLogCondition(o, 'string')}); var regexps = nolog.map(function(o){ return createNoLogCondition(o, 'string'); });
return new RegExp(regexps.join('|')); return new RegExp(regexps.join('|'));
} }
} }
exports.connectLogger = getLogger; exports.connectLogger = getLogger;

View File

@ -1,106 +1,110 @@
"use strict";
var dateFormat = require('./date_format') var dateFormat = require('./date_format')
, os = require('os') , os = require('os')
, eol = os.EOL || '\n' , eol = os.EOL || '\n'
, util = require('util') , util = require('util')
, replacementRegExp = /%[sdj]/g , replacementRegExp = /%[sdj]/g
, layoutMakers = { , layoutMakers = {
"messagePassThrough": function() { return messagePassThroughLayout; } "messagePassThrough": function() { return messagePassThroughLayout; },
, "basic": function() { return basicLayout; } "basic": function() { return basicLayout; },
, "colored": function() { return colouredLayout; } "colored": function() { return colouredLayout; },
, "coloured": function() { return colouredLayout; } "coloured": function() { return colouredLayout; },
, "pattern": function (config) { "pattern": function (config) {
var pattern = config.pattern || undefined; var pattern = config.pattern || undefined;
var tokens = config.tokens || undefined; var tokens = config.tokens || undefined;
return patternLayout(pattern, tokens); return patternLayout(pattern, tokens);
} }
} }
, colours = { , colours = {
ALL: "grey" ALL: "grey",
, TRACE: "blue" TRACE: "blue",
, DEBUG: "cyan" DEBUG: "cyan",
, INFO: "green" INFO: "green",
, WARN: "yellow" WARN: "yellow",
, ERROR: "red" ERROR: "red",
, FATAL: "magenta" FATAL: "magenta",
, OFF: "grey" OFF: "grey"
}; };
function formatLogData(logData) { function formatLogData(logData) {
var output = "" var output = ""
, data = Array.isArray(logData) ? logData.slice() : Array.prototype.slice.call(arguments) , data = Array.isArray(logData) ? logData.slice() : Array.prototype.slice.call(arguments)
, format = data.shift(); , format = data.shift();
if (typeof format === "string") { if (typeof format === "string") {
output = format.replace(replacementRegExp, function(match) { output = format.replace(replacementRegExp, function(match) {
switch (match) { switch (match) {
case "%s": return new String(data.shift()); case "%s":
case "%d": return new Number(data.shift()); return data.shift().toString();
case "%j": return JSON.stringify(data.shift()); case "%d":
default: return new Number(data.shift());
return match; case "%j":
}; return JSON.stringify(data.shift());
}); default:
} else { return match;
//put it back, it's not a format string }
data.unshift(format);
}
data.forEach(function (item) {
if (output) {
output += ' ';
}
output += util.inspect(item);
if (item && item.stack) {
output += "\n" + item.stack;
}
}); });
} else {
//put it back, it's not a format string
data.unshift(format);
}
return output; data.forEach(function (item) {
if (output) {
output += ' ';
}
output += util.inspect(item);
if (item && item.stack) {
output += "\n" + item.stack;
}
});
return output;
} }
var styles = { var styles = {
//styles //styles
'bold' : [1, 22], 'bold' : [1, 22],
'italic' : [3, 23], 'italic' : [3, 23],
'underline' : [4, 24], 'underline' : [4, 24],
'inverse' : [7, 27], 'inverse' : [7, 27],
//grayscale //grayscale
'white' : [37, 39], 'white' : [37, 39],
'grey' : [90, 39], 'grey' : [90, 39],
'black' : [90, 39], 'black' : [90, 39],
//colors //colors
'blue' : [34, 39], 'blue' : [34, 39],
'cyan' : [36, 39], 'cyan' : [36, 39],
'green' : [32, 39], 'green' : [32, 39],
'magenta' : [35, 39], 'magenta' : [35, 39],
'red' : [31, 39], 'red' : [31, 39],
'yellow' : [33, 39] 'yellow' : [33, 39]
}; };
function colorizeStart(style) { function colorizeStart(style) {
return style ? '\033[' + styles[style][0] + 'm' : ''; return style ? '\x1B[' + styles[style][0] + 'm' : '';
} }
function colorizeEnd(style) { function colorizeEnd(style) {
return style ? '\033[' + styles[style][1] + 'm' : ''; return style ? '\x1B[' + styles[style][1] + 'm' : '';
} }
/** /**
* Taken from masylum's fork (https://github.com/masylum/log4js-node) * Taken from masylum's fork (https://github.com/masylum/log4js-node)
*/ */
function colorize (str, style) { function colorize (str, style) {
return colorizeStart(style) + str + colorizeEnd(style); return colorizeStart(style) + str + colorizeEnd(style);
} }
function timestampLevelAndCategory(loggingEvent, colour) { function timestampLevelAndCategory(loggingEvent, colour) {
var output = colorize( var output = colorize(
formatLogData( formatLogData(
'[%s] [%s] %s - ' '[%s] [%s] %s - '
, dateFormat.asString(loggingEvent.startTime) , dateFormat.asString(loggingEvent.startTime)
, loggingEvent.level , loggingEvent.level
, loggingEvent.categoryName , loggingEvent.categoryName
) )
, colour , colour
); );
return output; return output;
} }
/** /**
@ -113,7 +117,7 @@ function timestampLevelAndCategory(loggingEvent, colour) {
* @author Stephan Strittmatter * @author Stephan Strittmatter
*/ */
function basicLayout (loggingEvent) { function basicLayout (loggingEvent) {
return timestampLevelAndCategory(loggingEvent) + formatLogData(loggingEvent.data); return timestampLevelAndCategory(loggingEvent) + formatLogData(loggingEvent.data);
} }
/** /**
@ -121,11 +125,14 @@ function basicLayout (loggingEvent) {
* same as basicLayout, but with colours. * same as basicLayout, but with colours.
*/ */
function colouredLayout (loggingEvent) { function colouredLayout (loggingEvent) {
return timestampLevelAndCategory(loggingEvent, colours[loggingEvent.level.toString()]) + formatLogData(loggingEvent.data); return timestampLevelAndCategory(
loggingEvent,
colours[loggingEvent.level.toString()]
) + formatLogData(loggingEvent.data);
} }
function messagePassThroughLayout (loggingEvent) { function messagePassThroughLayout (loggingEvent) {
return formatLogData(loggingEvent.data); return formatLogData(loggingEvent.data);
} }
/** /**
@ -158,140 +165,140 @@ function messagePassThroughLayout (loggingEvent) {
* @author Jan Schmidle * @author Jan Schmidle
*/ */
function patternLayout (pattern, tokens) { function patternLayout (pattern, tokens) {
var TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n"; var TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n";
var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([\[\]cdmnprx%])(\{([^\}]+)\})?|([^%]+)/; var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([\[\]cdmnprx%])(\{([^\}]+)\})?|([^%]+)/;
pattern = pattern || TTCC_CONVERSION_PATTERN;
return function(loggingEvent) {
var formattedString = "";
var result;
var searchString = pattern;
while ((result = regex.exec(searchString))) {
var matchedString = result[0];
var padding = result[1];
var truncation = result[2];
var conversionCharacter = result[3];
var specifier = result[5];
var text = result[6];
// Check if the pattern matched was just normal text
if (text) {
formattedString += "" + text;
} else {
// Create a raw replacement string based on the conversion
// character and specifier
var replacement = "";
switch(conversionCharacter) {
case "c":
var loggerName = loggingEvent.categoryName;
if (specifier) {
var precision = parseInt(specifier, 10);
var loggerNameBits = loggingEvent.categoryName.split(".");
if (precision >= loggerNameBits.length) {
replacement = loggerName;
} else {
replacement = loggerNameBits.slice(loggerNameBits.length - precision).join(".");
}
} else {
replacement = loggerName;
}
break;
case "d":
var format = dateFormat.ISO8601_FORMAT;
if (specifier) {
format = specifier;
// Pick up special cases
if (format == "ISO8601") {
format = dateFormat.ISO8601_FORMAT;
} else if (format == "ABSOLUTE") {
format = dateFormat.ABSOLUTETIME_FORMAT;
} else if (format == "DATE") {
format = dateFormat.DATETIME_FORMAT;
}
}
// Format the date
replacement = dateFormat.asString(format, loggingEvent.startTime);
break;
case "m":
replacement = formatLogData(loggingEvent.data);
break;
case "n":
replacement = eol;
break;
case "p":
replacement = loggingEvent.level.toString();
break;
case "r":
replacement = "" + loggingEvent.startTime.toLocaleTimeString();
break;
case "[":
replacement = colorizeStart(colours[loggingEvent.level.toString()]);
break;
case "]":
replacement = colorizeEnd(colours[loggingEvent.level.toString()]);
break;
case "%":
replacement = "%";
break;
case "x":
if(typeof(tokens[specifier]) !== 'undefined') {
if(typeof(tokens[specifier]) === 'function') {
replacement = tokens[specifier]();
} else {
replacement = tokens[specifier];
}
} else {
replacement = matchedString;
}
break;
default:
replacement = matchedString;
break;
}
// Format the replacement according to any padding or
// truncation specified
var len;
// First, truncation
if (truncation) {
len = parseInt(truncation.substr(1), 10);
replacement = replacement.substring(0, len);
}
// Next, padding
if (padding) {
if (padding.charAt(0) == "-") {
len = parseInt(padding.substr(1), 10);
// Right pad with spaces
while (replacement.length < len) {
replacement += " ";
}
} else {
len = parseInt(padding, 10);
// Left pad with spaces
while (replacement.length < len) {
replacement = " " + replacement;
}
}
}
formattedString += replacement;
}
searchString = searchString.substr(result.index + result[0].length);
}
return formattedString;
};
pattern = pattern || TTCC_CONVERSION_PATTERN; }
return function(loggingEvent) {
var formattedString = "";
var result;
var searchString = pattern;
while ((result = regex.exec(searchString))) {
var matchedString = result[0];
var padding = result[1];
var truncation = result[2];
var conversionCharacter = result[3];
var specifier = result[5];
var text = result[6];
// Check if the pattern matched was just normal text
if (text) {
formattedString += "" + text;
} else {
// Create a raw replacement string based on the conversion
// character and specifier
var replacement = "";
switch(conversionCharacter) {
case "c":
var loggerName = loggingEvent.categoryName;
if (specifier) {
var precision = parseInt(specifier, 10);
var loggerNameBits = loggingEvent.categoryName.split(".");
if (precision >= loggerNameBits.length) {
replacement = loggerName;
} else {
replacement = loggerNameBits.slice(loggerNameBits.length - precision).join(".");
}
} else {
replacement = loggerName;
}
break;
case "d":
var format = dateFormat.ISO8601_FORMAT;
if (specifier) {
format = specifier;
// Pick up special cases
if (format == "ISO8601") {
format = dateFormat.ISO8601_FORMAT;
} else if (format == "ABSOLUTE") {
format = dateFormat.ABSOLUTETIME_FORMAT;
} else if (format == "DATE") {
format = dateFormat.DATETIME_FORMAT;
}
}
// Format the date
replacement = dateFormat.asString(format, loggingEvent.startTime);
break;
case "m":
replacement = formatLogData(loggingEvent.data);
break;
case "n":
replacement = eol;
break;
case "p":
replacement = loggingEvent.level.toString();
break;
case "r":
replacement = "" + loggingEvent.startTime.toLocaleTimeString();
break;
case "[":
replacement = colorizeStart(colours[loggingEvent.level.toString()]);
break;
case "]":
replacement = colorizeEnd(colours[loggingEvent.level.toString()]);
break;
case "%":
replacement = "%";
break;
case "x":
if(typeof(tokens[specifier]) !== 'undefined') {
if(typeof(tokens[specifier]) === 'function') {
replacement = tokens[specifier]();
} else {
replacement = tokens[specifier];
}
} else {
replacement = matchedString;
}
break;
default:
replacement = matchedString;
break;
}
// Format the replacement according to any padding or
// truncation specified
var len;
// First, truncation
if (truncation) {
len = parseInt(truncation.substr(1), 10);
replacement = replacement.substring(0, len);
}
// Next, padding
if (padding) {
if (padding.charAt(0) == "-") {
len = parseInt(padding.substr(1), 10);
// Right pad with spaces
while (replacement.length < len) {
replacement += " ";
}
} else {
len = parseInt(padding, 10);
// Left pad with spaces
while (replacement.length < len) {
replacement = " " + replacement;
}
}
}
formattedString += replacement;
}
searchString = searchString.substr(result.index + result[0].length);
}
return formattedString;
};
};
module.exports = { module.exports = {
basicLayout: basicLayout basicLayout: basicLayout,
, messagePassThroughLayout: messagePassThroughLayout messagePassThroughLayout: messagePassThroughLayout,
, patternLayout: patternLayout patternLayout: patternLayout,
, colouredLayout: colouredLayout colouredLayout: colouredLayout,
, coloredLayout: colouredLayout coloredLayout: colouredLayout,
, layout: function(name, config) { layout: function(name, config) {
return layoutMakers[name] && layoutMakers[name](config); return layoutMakers[name] && layoutMakers[name](config);
} }
}; };

View File

@ -1,3 +1,4 @@
"use strict";
/* /*
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -12,8 +13,6 @@
* limitations under the License. * limitations under the License.
*/ */
/*jsl:option explicit*/
/** /**
* @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.
@ -57,10 +56,10 @@ var events = require('events')
, loggers = {} , loggers = {}
, appenderMakers = {} , appenderMakers = {}
, defaultConfig = { , defaultConfig = {
appenders: [ appenders: [
{ type: "console" } { type: "console" }
], ],
replaceConsole: false replaceConsole: false
}; };
/** /**
@ -71,102 +70,102 @@ var events = require('events')
*/ */
function getLogger (categoryName) { 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 = Logger.DEFAULT_CATEGORY; categoryName = Logger.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]) {
appenderList = appenders[ALL_CATEGORIES];
appenderList.forEach(function(appender) {
loggers[categoryName].addListener("log", appender);
});
}
} }
if (appenders[ALL_CATEGORIES]) {
return loggers[categoryName]; appenderList = appenders[ALL_CATEGORIES];
appenderList.forEach(function(appender) {
loggers[categoryName].addListener("log", appender);
});
}
}
return loggers[categoryName];
} }
/** /**
* args are appender, then zero or more categories * args are appender, then zero or more categories
*/ */
function addAppender () { 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
if (Array.isArray(args[0])) {
args = args[0];
}
args.forEach(function(category) {
if (!appenders[category]) {
appenders[category] = [];
} }
//argument may already be an array appenders[category].push(appender);
if (Array.isArray(args[0])) {
args = args[0]; if (category === ALL_CATEGORIES) {
for (var logger in loggers) {
if (loggers.hasOwnProperty(logger)) {
loggers[logger].addListener("log", appender);
}
}
} else if (loggers[category]) {
loggers[category].addListener("log", appender);
} }
});
args.forEach(function(category) {
if (!appenders[category]) {
appenders[category] = [];
}
appenders[category].push(appender);
if (category === ALL_CATEGORIES) {
for (var logger in loggers) {
if (loggers.hasOwnProperty(logger)) {
loggers[logger].addListener("log", appender);
}
}
} else if (loggers[category]) {
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, options) { function configureAppenders(appenderList, options) {
clearAppenders(); clearAppenders();
if (appenderList) { if (appenderList) {
appenderList.forEach(function(appenderConfig) { appenderList.forEach(function(appenderConfig) {
loadAppender(appenderConfig.type); loadAppender(appenderConfig.type);
var appender; var appender;
appenderConfig.makers = appenderMakers; appenderConfig.makers = appenderMakers;
appender = appenderMakers[appenderConfig.type](appenderConfig, options); appender = appenderMakers[appenderConfig.type](appenderConfig, options);
if (appender) { if (appender) {
addAppender(appender, appenderConfig.category); addAppender(appender, appenderConfig.category);
} else { } else {
throw new Error("log4js configuration problem for "+util.inspect(appenderConfig)); throw new Error("log4js configuration problem for "+util.inspect(appenderConfig));
} }
}); });
} }
} }
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]);
} }
}
} }
}
} }
function setGlobalLogLevel(level) { function setGlobalLogLevel(level) {
Logger.prototype.level = levels.toLevel(level, levels.TRACE); Logger.prototype.level = levels.toLevel(level, levels.TRACE);
} }
/** /**
@ -175,143 +174,152 @@ function setGlobalLogLevel(level) {
* @static * @static
*/ */
function getDefaultLogger () { function getDefaultLogger () {
return getLogger(Logger.DEFAULT_CATEGORY); return getLogger(Logger.DEFAULT_CATEGORY);
} }
var configState = {}; var configState = {};
function loadConfigurationFile(filename) { function loadConfigurationFile(filename) {
if (filename && (!configState.lastFilename || filename !== configState.lastFilename || if (filename &&
!configState.lastMTime || fs.statSync(filename).mtime !== configState.lastMTime)) { (!configState.lastFilename ||
configState.lastFilename = filename; filename !== configState.lastFilename ||
configState.lastMTime = fs.statSync(filename).mtime; !configState.lastMTime ||
return JSON.parse(fs.readFileSync(filename, "utf8")); fs.statSync(filename).mtime !== configState.lastMTime)
} ) {
return undefined; configState.lastFilename = filename;
configState.lastMTime = fs.statSync(filename).mtime;
return JSON.parse(fs.readFileSync(filename, "utf8"));
}
return undefined;
} }
function configureOnceOff(config, options) { function configureOnceOff(config, options) {
if (config) { if (config) {
try { try {
configureAppenders(config.appenders, options); configureAppenders(config.appenders, options);
configureLevels(config.levels); configureLevels(config.levels);
if (config.replaceConsole) { if (config.replaceConsole) {
replaceConsole(); replaceConsole();
} else { } else {
restoreConsole(); restoreConsole();
} }
} catch (e) { } catch (e) {
throw new Error("Problem reading log4js config " + util.inspect(config) + ". Error was \"" + e.message + "\" ("+e.stack+")"); throw new Error(
} "Problem reading log4js config " + util.inspect(config) +
". Error was \"" + e.message + "\" (" + e.stack + ")"
);
} }
}
} }
function reloadConfiguration() { function reloadConfiguration() {
var filename = configState.filename, var filename = configState.filename,
mtime; mtime;
if (!filename) { if (!filename) {
// can't find anything to reload // can't find anything to reload
return; return;
} }
try { try {
mtime = fs.statSync(filename).mtime; mtime = fs.statSync(filename).mtime;
} catch (e) { } catch (e) {
getLogger('log4js').warn('Failed to load configuration file ' + filename); getLogger('log4js').warn('Failed to load configuration file ' + filename);
return; return;
} }
if (configState.lastFilename && configState.lastFilename === filename) { if (configState.lastFilename && configState.lastFilename === filename) {
if (mtime.getTime() > configState.lastMTime.getTime()) { if (mtime.getTime() > configState.lastMTime.getTime()) {
configureOnceOff(loadConfigurationFile(filename)); configureOnceOff(loadConfigurationFile(filename));
}
} else {
configureOnceOff(loadConfigurationFile(filename));
} }
} else {
configureOnceOff(loadConfigurationFile(filename));
}
} }
function initReloadConfiguration(filename, options) { function initReloadConfiguration(filename, options) {
if (configState.timerId) { if (configState.timerId) {
clearInterval(configState.timerId); clearInterval(configState.timerId);
delete configState.timerId; delete configState.timerId;
} }
configState.filename = filename; configState.filename = filename;
configState.timerId = setInterval(reloadConfiguration, options.reloadSecs*1000); configState.timerId = setInterval(reloadConfiguration, options.reloadSecs*1000);
} }
function configure(configurationFileOrObject, options) { function configure(configurationFileOrObject, options) {
var config = configurationFileOrObject; var config = configurationFileOrObject;
config = config || process.env.LOG4JS_CONFIG; config = config || process.env.LOG4JS_CONFIG;
options = options || {}; options = options || {};
if (config === undefined || config === null || typeof(config) === 'string') { if (config === undefined || config === null || typeof(config) === 'string') {
if (options.reloadSecs) { if (options.reloadSecs) {
initReloadConfiguration(config, options); initReloadConfiguration(config, options);
}
config = loadConfigurationFile(config) || defaultConfig;
} else {
if (options.reloadSecs) {
getLogger('log4js').warn('Ignoring configuration reload parameter for "object" configuration.');
}
} }
configureOnceOff(config, options); config = loadConfigurationFile(config) || defaultConfig;
} else {
if (options.reloadSecs) {
getLogger('log4js').warn(
'Ignoring configuration reload parameter for "object" configuration.'
);
}
}
configureOnceOff(config, options);
} }
var originalConsoleFunctions = { var originalConsoleFunctions = {
log: console.log, log: console.log,
debug: console.debug, debug: console.debug,
info: console.info, info: console.info,
warn: console.warn, warn: console.warn,
error: console.error error: console.error
}; };
function replaceConsole(logger) { function replaceConsole(logger) {
function replaceWith(fn) { function replaceWith(fn) {
return function() { return function() {
fn.apply(logger, arguments); fn.apply(logger, arguments);
} };
} }
logger = logger || getLogger("console"); logger = logger || getLogger("console");
['log','debug','info','warn','error'].forEach(function (item) { ['log','debug','info','warn','error'].forEach(function (item) {
console[item] = replaceWith(item === 'log' ? logger.info : logger[item]); console[item] = replaceWith(item === 'log' ? logger.info : logger[item]);
}); });
} }
function restoreConsole() { function restoreConsole() {
['log', 'debug', 'info', 'warn', 'error'].forEach(function (item) { ['log', 'debug', 'info', 'warn', 'error'].forEach(function (item) {
console[item] = originalConsoleFunctions[item]; console[item] = originalConsoleFunctions[item];
}); });
} }
function loadAppender(appender) { function loadAppender(appender) {
var appenderModule; var appenderModule;
try { try {
appenderModule = require('./appenders/' + appender); appenderModule = require('./appenders/' + appender);
} catch (e) { } catch (e) {
appenderModule = require(appender); appenderModule = require(appender);
} }
module.exports.appenders[appender] = appenderModule.appender.bind(appenderModule); module.exports.appenders[appender] = appenderModule.appender.bind(appenderModule);
appenderMakers[appender] = appenderModule.configure.bind(appenderModule); appenderMakers[appender] = appenderModule.configure.bind(appenderModule);
} }
module.exports = { module.exports = {
getLogger: getLogger, getLogger: getLogger,
getDefaultLogger: getDefaultLogger, getDefaultLogger: getDefaultLogger,
addAppender: addAppender, addAppender: addAppender,
loadAppender: loadAppender, loadAppender: loadAppender,
clearAppenders: clearAppenders, clearAppenders: clearAppenders,
configure: configure, configure: configure,
replaceConsole: replaceConsole, replaceConsole: replaceConsole,
restoreConsole: restoreConsole, restoreConsole: restoreConsole,
levels: levels, levels: levels,
setGlobalLogLevel: setGlobalLogLevel, setGlobalLogLevel: setGlobalLogLevel,
layouts: layouts, layouts: layouts,
appenders: {}, appenders: {},
appenderMakers: appenderMakers, appenderMakers: appenderMakers,
connectLogger: require('./connect-logger').connectLogger connectLogger: require('./connect-logger').connectLogger
}; };
//set ourselves up //set ourselves up

View File

@ -1,7 +1,10 @@
"use strict";
// This test shows unexpected behaviour for log4js.configure() in log4js-node@0.4.3 and earlier: // This test shows unexpected behaviour for log4js.configure() in log4js-node@0.4.3 and earlier:
// 1) log4js.configure(), log4js.configure(null), log4js.configure({}), log4js.configure(<some object with no levels prop>) // 1) log4js.configure(), log4js.configure(null),
// log4js.configure({}), log4js.configure(<some object with no levels prop>)
// all set all loggers levels to trace, even if they were previously set to something else. // all set all loggers levels to trace, even if they were previously set to something else.
// 2) log4js.configure({levels:{}}), log4js.configure({levels: {foo: bar}}) leaves previously set logger levels intact. // 2) log4js.configure({levels:{}}), log4js.configure({levels: {foo:
// bar}}) leaves previously set logger levels intact.
// //
// Basic set up // Basic set up
@ -28,7 +31,7 @@ var configs = {
'has empty levels': {levels: {}}, 'has empty levels': {levels: {}},
'has random levels': {levels: {foo: 'bar'}}, 'has random levels': {levels: {foo: 'bar'}},
'has some valid levels': {levels: {A: 'INFO'}} 'has some valid levels': {levels: {A: 'INFO'}}
} };
// Set up the basic vows batches for this test // Set up the basic vows batches for this test
var batches = []; var batches = [];
@ -60,13 +63,14 @@ function getTopLevelContext(nop, configToTest, name) {
} }
return log4js; return log4js;
} }
} };
}; }
showProgress('Populating batch object...'); showProgress('Populating batch object...');
// Populating the batches programmatically, // Populating the batches programmatically, as there are
// as there are (configs.length x strLevels.length x strLevels.length) = 324 possible test combinations // (configs.length x strLevels.length x strLevels.length) = 324
// possible test combinations
for (var cfg in configs) { for (var cfg in configs) {
var configToTest = configs[cfg]; var configToTest = configs[cfg];
var nop = configToTest === 'nop'; var nop = configToTest === 'nop';
@ -84,43 +88,73 @@ for (var cfg in configs) {
batch[context]= getTopLevelContext(nop, configToTest, context); batch[context]= getTopLevelContext(nop, configToTest, context);
batches.push(batch); batches.push(batch);
// each top-level context has strLevels sub-contexts, one per logger which has set to a specific level in the top-level context's topic // each top-level context has strLevels sub-contexts, one per logger
// which has set to a specific level in the top-level context's topic
strLevels.forEach(function (baseLevel) { strLevels.forEach(function (baseLevel) {
var baseLevelSubContext = 'and checking the logger whose level was set to '+baseLevel ; var baseLevelSubContext = 'and checking the logger whose level was set to '+baseLevel ;
batch[context][baseLevelSubContext] = {topic: baseLevel}; var subContext = { topic: baseLevel };
batch[context][baseLevelSubContext] = subContext;
// each logging level has strLevels sub-contexts, // each logging level has strLevels sub-contexts,
// to exhaustively test all the combinations of setLevel(baseLevel) and isLevelEnabled(comparisonLevel) per config // to exhaustively test all the combinations of
// setLevel(baseLevel) and isLevelEnabled(comparisonLevel) per config
strLevels.forEach(function (comparisonLevel) { strLevels.forEach(function (comparisonLevel) {
var comparisonLevelSubContext = 'with isLevelEnabled('+comparisonLevel+')'; var comparisonLevelSubContext = 'with isLevelEnabled('+comparisonLevel+')';
// calculate this independently of log4js, but we'll add a vow later on to check that we're not mismatched with log4js // calculate this independently of log4js, but we'll add a vow
// later on to check that we're not mismatched with log4js
var expectedResult = strLevels.indexOf(baseLevel) <= strLevels.indexOf(comparisonLevel); var expectedResult = strLevels.indexOf(baseLevel) <= strLevels.indexOf(comparisonLevel);
// the topic simply gathers all the parameters for the vow into an object, to simplify the vow's work. // the topic simply gathers all the parameters for the vow
batch[context][baseLevelSubContext][comparisonLevelSubContext] = {topic: function(baseLevel, log4js){ // into an object, to simplify the vow's work.
return {comparisonLevel: comparisonLevel, baseLevel: baseLevel, log4js: log4js, expectedResult: expectedResult}; subContext[comparisonLevelSubContext] = {
}}; topic: function(baseLevel, log4js) {
return {
var vow = 'should return '+expectedResult; comparisonLevel: comparisonLevel,
batch[context][baseLevelSubContext][comparisonLevelSubContext][vow] = function(topic){ baseLevel: baseLevel,
var result = topic.log4js.getLogger(getLoggerName(topic.baseLevel)).isLevelEnabled(topic.log4js.levels.toLevel(topic.comparisonLevel)); log4js: log4js,
assert.equal(result, topic.expectedResult, 'Failed: '+getLoggerName(topic.baseLevel)+'.isLevelEnabled( '+topic.comparisonLevel+' ) returned '+result); expectedResult: expectedResult
};
}
}; };
// the extra vow to check the comparison between baseLevel and comparisonLevel we performed earlier matches log4js' comparison too var vow = 'should return '+expectedResult;
batch[context][baseLevelSubContext][comparisonLevelSubContext]['finally checking for comparison mismatch with log4js'] = function(topic){ subContext[comparisonLevelSubContext][vow] = function(topic) {
var er = topic.log4js.levels.toLevel(topic.baseLevel).isLessThanOrEqualTo(topic.log4js.levels.toLevel(topic.comparisonLevel)); var result = topic.log4js
assert.equal(er, topic.expectedResult, 'Mismatch: for setLevel('+topic.baseLevel+') was expecting a comparison with '+topic.comparisonLevel+' to be '+topic.expectedResult); .getLogger(getLoggerName(topic.baseLevel))
.isLevelEnabled(topic.log4js.levels.toLevel(topic.comparisonLevel));
assert.equal(
result,
topic.expectedResult,
'Failed: ' + getLoggerName(topic.baseLevel) +
'.isLevelEnabled( ' + topic.comparisonLevel + ' ) returned ' + result
);
};
// the extra vow to check the comparison between baseLevel and
// comparisonLevel we performed earlier matches log4js'
// comparison too
var subSubContext = subContext[comparisonLevelSubContext];
subSubContext['finally checking for comparison mismatch with log4js'] = function(topic) {
var er = topic.log4js.levels.toLevel(topic.baseLevel)
.isLessThanOrEqualTo(topic.log4js.levels.toLevel(topic.comparisonLevel));
assert.equal(
er,
topic.expectedResult,
'Mismatch: for setLevel(' + topic.baseLevel +
') was expecting a comparison with ' + topic.comparisonLevel +
' to be ' + topic.expectedResult
);
}; };
}); });
}); });
}; }
showProgress('Running tests'); showProgress('Running tests');
var v = vows.describe('log4js.configure(), with or without a "levels" property'); var v = vows.describe('log4js.configure(), with or without a "levels" property');
batches.forEach(function(batch) {v=v.addBatch(batch)}); batches.forEach(function(batch) {v=v.addBatch(batch);});
v.export(module); v.export(module);

View File

@ -26,7 +26,7 @@ vows.describe('log4js layouts').addBatch({
toString: function() { return "ERROR"; } toString: function() { return "ERROR"; }
} }
}); });
assert.equal(output, '\0x1B[31m[2010-12-05 14:18:30.045] [ERROR] cheese - \0x1B[39mnonsense'); assert.equal(output, '\x1B[31m[2010-12-05 14:18:30.045] [ERROR] cheese - \x1B[39mnonsense');
}, },
'should support the console.log format for the message': function(layout) { 'should support the console.log format for the message': function(layout) {
@ -38,7 +38,7 @@ vows.describe('log4js layouts').addBatch({
toString: function() { return "ERROR"; } toString: function() { return "ERROR"; }
} }
}); });
assert.equal(output, '\0x1B[31m[2010-12-05 14:18:30.045] [ERROR] cheese - \0x1B[39mthing 2'); assert.equal(output, '\x1B[31m[2010-12-05 14:18:30.045] [ERROR] cheese - \x1B[39mthing 2');
} }
}, },
@ -258,7 +258,7 @@ vows.describe('log4js layouts').addBatch({
test(args, '%-10p', 'DEBUG '); test(args, '%-10p', 'DEBUG ');
}, },
'%[%r%] should output colored time': function(args) { '%[%r%] should output colored time': function(args) {
test(args, '%[%r%]', '\0x1B[36m14:18:30\0x1B[39m'); test(args, '%[%r%]', '\x1B[36m14:18:30\x1B[39m');
}, },
'%x{testString} should output the string stored in tokens': function(args) { '%x{testString} should output the string stored in tokens': function(args) {
test(args, '%x{testString}', 'testStringToken'); test(args, '%x{testString}', 'testStringToken');