fixed all lint errors except ones which require refactoring of code
This commit is contained in:
parent
f998d7e81a
commit
5d6f00eda4
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
439
lib/layouts.js
439
lib/layouts.js
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
366
lib/log4js.js
366
lib/log4js.js
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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');
|
||||||
|
Loading…
Reference in New Issue
Block a user