mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
refactor: fixed a few more appenders
This commit is contained in:
parent
5283782ba0
commit
1d50b82a96
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const log4js = require('../log4js');
|
||||
|
||||
function categoryFilter(excludes, appender) {
|
||||
if (typeof excludes === 'string') excludes = [excludes];
|
||||
return (logEvent) => {
|
||||
@ -11,11 +9,9 @@ function categoryFilter(excludes, appender) {
|
||||
};
|
||||
}
|
||||
|
||||
function configure(config, options) {
|
||||
log4js.loadAppender(config.appender.type);
|
||||
const appender = log4js.appenderMakers[config.appender.type](config.appender, options);
|
||||
function configure(config, layouts, findAppender) {
|
||||
const appender = findAppender(config.appender);
|
||||
return categoryFilter(config.exclude, appender);
|
||||
}
|
||||
|
||||
module.exports.appender = categoryFilter;
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -1,23 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
const layouts = require('../layouts');
|
||||
|
||||
const consoleLog = console.log.bind(console);
|
||||
|
||||
function consoleAppender(layout, timezoneOffset) {
|
||||
layout = layout || layouts.colouredLayout;
|
||||
return (loggingEvent) => {
|
||||
consoleLog(layout(loggingEvent, timezoneOffset));
|
||||
};
|
||||
}
|
||||
|
||||
function configure(config) {
|
||||
let layout;
|
||||
function configure(config, layouts) {
|
||||
let layout = layouts.colouredLayout;
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
return consoleAppender(layout, config.timezoneOffset);
|
||||
}
|
||||
|
||||
module.exports.appender = consoleAppender;
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -1,18 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const streams = require('streamroller');
|
||||
const layouts = require('../layouts');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const eol = os.EOL || '\n';
|
||||
const openFiles = [];
|
||||
const appenders = [];
|
||||
|
||||
// close open files on process exit.
|
||||
process.on('exit', () => {
|
||||
openFiles.forEach((file) => {
|
||||
file.end();
|
||||
});
|
||||
appenders.forEach((a) => { a.shutdown(); });
|
||||
});
|
||||
|
||||
/**
|
||||
@ -30,21 +26,33 @@ function appender(
|
||||
options,
|
||||
timezoneOffset
|
||||
) {
|
||||
layout = layout || layouts.basicLayout;
|
||||
const logFile = new streams.DateRollingFileStream(
|
||||
filename,
|
||||
pattern,
|
||||
options
|
||||
);
|
||||
openFiles.push(logFile);
|
||||
|
||||
return (logEvent) => {
|
||||
const app = function (logEvent) {
|
||||
logFile.write(layout(logEvent, timezoneOffset) + eol, 'utf8');
|
||||
};
|
||||
|
||||
app.shutdown = function (cb) {
|
||||
if (!logFile.write(eol, 'utf-8')) {
|
||||
logFile.once('drain', () => {
|
||||
logFile.end(cb);
|
||||
});
|
||||
} else {
|
||||
logFile.end(cb);
|
||||
}
|
||||
};
|
||||
|
||||
appenders.push(app);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
function configure(config, options) {
|
||||
let layout;
|
||||
function configure(config, layouts) {
|
||||
let layout = layouts.basicLayout;
|
||||
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
@ -54,10 +62,6 @@ function configure(config, options) {
|
||||
config.alwaysIncludePattern = false;
|
||||
}
|
||||
|
||||
if (options && options.cwd && !config.absolute) {
|
||||
config.filename = path.join(options.cwd, config.filename);
|
||||
}
|
||||
|
||||
return appender(
|
||||
config.filename,
|
||||
config.pattern,
|
||||
@ -67,31 +71,4 @@ function configure(config, options) {
|
||||
);
|
||||
}
|
||||
|
||||
function shutdown(cb) {
|
||||
let completed = 0;
|
||||
let error;
|
||||
const complete = (err) => {
|
||||
error = error || err;
|
||||
completed++; // eslint-disable-line no-plusplus
|
||||
if (completed >= openFiles.length) {
|
||||
cb(error);
|
||||
}
|
||||
};
|
||||
if (!openFiles.length) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
return openFiles.forEach((file) => {
|
||||
if (!file.write(eol, 'utf-8')) {
|
||||
file.once('drain', () => {
|
||||
file.end(complete);
|
||||
});
|
||||
} else {
|
||||
file.end(complete);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.appender = appender;
|
||||
module.exports.configure = configure;
|
||||
module.exports.shutdown = shutdown;
|
||||
|
||||
@ -1,20 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
const debug = require('debug')('log4js:file');
|
||||
const layouts = require('../layouts');
|
||||
const path = require('path');
|
||||
const streams = require('streamroller');
|
||||
const os = require('os');
|
||||
|
||||
const eol = os.EOL || '\n';
|
||||
const openFiles = [];
|
||||
const appenders = [];
|
||||
|
||||
// close open files on process exit.
|
||||
process.on('exit', () => {
|
||||
debug('Exit handler called.');
|
||||
openFiles.forEach((file) => {
|
||||
file.end();
|
||||
});
|
||||
appenders.forEach((a) => { a.shutdown(); });
|
||||
});
|
||||
|
||||
// On SIGHUP, close and reopen all files. This allows this appender to work with
|
||||
@ -22,11 +19,25 @@ process.on('exit', () => {
|
||||
// `logSize`.
|
||||
process.on('SIGHUP', () => {
|
||||
debug('SIGHUP handler called.');
|
||||
openFiles.forEach((writer) => {
|
||||
writer.closeTheStream(writer.openTheStream.bind(writer));
|
||||
appenders.forEach((a) => {
|
||||
a.reopen();
|
||||
});
|
||||
});
|
||||
|
||||
function openTheStream(file, fileSize, numFiles, options) {
|
||||
const stream = new streams.RollingFileStream(
|
||||
file,
|
||||
fileSize,
|
||||
numFiles,
|
||||
options
|
||||
);
|
||||
stream.on('error', (err) => {
|
||||
console.error('log4js.fileAppender - Writing to file %s, error happened ', file, err);
|
||||
});
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* File Appender writing the logs to a text file. Supports rolling of logs by size.
|
||||
*
|
||||
@ -42,7 +53,6 @@ process.on('SIGHUP', () => {
|
||||
*/
|
||||
function fileAppender(file, layout, logSize, numBackups, options, timezoneOffset) {
|
||||
file = path.normalize(file);
|
||||
layout = layout || layouts.basicLayout;
|
||||
numBackups = numBackups === undefined ? 5 : numBackups;
|
||||
// there has to be at least one backup if logSize has been specified
|
||||
numBackups = numBackups === 0 ? 1 : numBackups;
|
||||
@ -54,40 +64,38 @@ function fileAppender(file, layout, logSize, numBackups, options, timezoneOffset
|
||||
options, ', ',
|
||||
timezoneOffset, ')'
|
||||
);
|
||||
|
||||
const writer = openTheStream(file, logSize, numBackups, options);
|
||||
|
||||
// push file to the stack of open handlers
|
||||
openFiles.push(writer);
|
||||
|
||||
return function (loggingEvent) {
|
||||
const app = function (loggingEvent) {
|
||||
writer.write(layout(loggingEvent, timezoneOffset) + eol, 'utf8');
|
||||
};
|
||||
|
||||
app.reopen = function () {
|
||||
writer.closeTheStream(writer.openTheStream.bind(writer));
|
||||
};
|
||||
|
||||
app.shutdown = function (complete) {
|
||||
if (!writer.write(eol, 'utf-8')) {
|
||||
writer.once('drain', () => {
|
||||
writer.end(complete);
|
||||
});
|
||||
} else {
|
||||
writer.end(complete);
|
||||
}
|
||||
};
|
||||
|
||||
// push file to the stack of open handlers
|
||||
appenders.push(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
function openTheStream(file, fileSize, numFiles, options) {
|
||||
const stream = new streams.RollingFileStream(
|
||||
file,
|
||||
fileSize,
|
||||
numFiles,
|
||||
options
|
||||
);
|
||||
stream.on('error', (err) => {
|
||||
console.error('log4js.fileAppender - Writing to file %s, error happened ', file, err);
|
||||
});
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
function configure(config, options) {
|
||||
let layout;
|
||||
function configure(config, layouts) {
|
||||
let layout = layouts.basicLayout;
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
|
||||
if (options && options.cwd && !config.absolute) {
|
||||
config.filename = path.join(options.cwd, config.filename);
|
||||
}
|
||||
|
||||
return fileAppender(
|
||||
config.filename,
|
||||
layout,
|
||||
@ -98,31 +106,4 @@ function configure(config, options) {
|
||||
);
|
||||
}
|
||||
|
||||
function shutdown(cb) {
|
||||
let completed = 0;
|
||||
let error;
|
||||
const complete = (err) => {
|
||||
error = error || err;
|
||||
completed++; // eslint-disable-line no-plusplus
|
||||
if (completed >= openFiles.length) {
|
||||
cb(error);
|
||||
}
|
||||
};
|
||||
if (!openFiles.length) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
return openFiles.forEach((file) => {
|
||||
if (!file.write(eol, 'utf-8')) {
|
||||
file.once('drain', () => {
|
||||
file.end(complete);
|
||||
});
|
||||
} else {
|
||||
file.end(complete);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.appender = fileAppender;
|
||||
module.exports.configure = configure;
|
||||
module.exports.shutdown = shutdown;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const debug = require('debug')('log4js:fileSync');
|
||||
const layouts = require('../layouts');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
@ -135,7 +134,6 @@ class RollingFileSync {
|
||||
function fileAppender(file, layout, logSize, numBackups, timezoneOffset) {
|
||||
debug('fileSync appender created');
|
||||
file = path.normalize(file);
|
||||
layout = layout || layouts.basicLayout;
|
||||
numBackups = numBackups === undefined ? 5 : numBackups;
|
||||
// there has to be at least one backup if logSize has been specified
|
||||
numBackups = numBackups === 0 ? 1 : numBackups;
|
||||
@ -174,16 +172,12 @@ function fileAppender(file, layout, logSize, numBackups, timezoneOffset) {
|
||||
};
|
||||
}
|
||||
|
||||
function configure(config, options) {
|
||||
let layout;
|
||||
function configure(config, layouts) {
|
||||
let layout = layouts.basicLayout;
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
|
||||
if (options && options.cwd && !config.absolute) {
|
||||
config.filename = path.join(options.cwd, config.filename);
|
||||
}
|
||||
|
||||
return fileAppender(
|
||||
config.filename,
|
||||
layout,
|
||||
@ -193,5 +187,4 @@ function configure(config, options) {
|
||||
);
|
||||
}
|
||||
|
||||
module.exports.appender = fileAppender;
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const zlib = require('zlib');
|
||||
const layouts = require('../layouts');
|
||||
const levels = require('../levels');
|
||||
const dgram = require('dgram');
|
||||
const util = require('util');
|
||||
@ -27,8 +26,6 @@ levelMapping[levels.WARN] = LOG_WARNING;
|
||||
levelMapping[levels.ERROR] = LOG_ERROR;
|
||||
levelMapping[levels.FATAL] = LOG_CRIT;
|
||||
|
||||
let client;
|
||||
|
||||
/**
|
||||
* GELF appender that supports sending UDP packets to a GELF compatible server such as Graylog
|
||||
*
|
||||
@ -54,7 +51,6 @@ function gelfAppender(layout, host, port, hostname, facility) {
|
||||
host = host || 'localhost';
|
||||
port = port || 12201;
|
||||
hostname = hostname || OS.hostname();
|
||||
layout = layout || layouts.messagePassThroughLayout;
|
||||
|
||||
const defaultCustomFields = customFields || {};
|
||||
|
||||
@ -62,7 +58,7 @@ function gelfAppender(layout, host, port, hostname, facility) {
|
||||
defaultCustomFields._facility = facility;
|
||||
}
|
||||
|
||||
client = dgram.createSocket('udp4');
|
||||
const client = dgram.createSocket('udp4');
|
||||
|
||||
process.on('exit', () => {
|
||||
if (client) client.close();
|
||||
@ -123,7 +119,7 @@ function gelfAppender(layout, host, port, hostname, facility) {
|
||||
});
|
||||
}
|
||||
|
||||
return (loggingEvent) => {
|
||||
const app = (loggingEvent) => {
|
||||
const message = preparePacket(loggingEvent);
|
||||
zlib.gzip(new Buffer(JSON.stringify(message)), (err, packet) => {
|
||||
if (err) {
|
||||
@ -137,23 +133,21 @@ function gelfAppender(layout, host, port, hostname, facility) {
|
||||
}
|
||||
});
|
||||
};
|
||||
app.shutdown = function (cb) {
|
||||
if (client) {
|
||||
client.close(cb);
|
||||
}
|
||||
};
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
function configure(config) {
|
||||
let layout;
|
||||
function configure(config, layouts) {
|
||||
let layout = layouts.messagePassThroughLayout;
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
return gelfAppender(layout, config);
|
||||
}
|
||||
|
||||
function shutdown(cb) {
|
||||
if (client) {
|
||||
client.close(cb);
|
||||
client = null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.appender = gelfAppender;
|
||||
module.exports.configure = configure;
|
||||
module.exports.shutdown = shutdown;
|
||||
|
||||
@ -1,17 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const hipchat = require('hipchat-notifier');
|
||||
const layouts = require('../layouts');
|
||||
|
||||
module.exports.name = 'hipchat';
|
||||
module.exports.appender = hipchatAppender;
|
||||
module.exports.configure = hipchatConfigure;
|
||||
|
||||
/**
|
||||
@invoke as
|
||||
|
||||
log4js.configure({
|
||||
'appenders': [
|
||||
'appenders': { 'hipchat':
|
||||
{
|
||||
'type' : 'hipchat',
|
||||
'hipchat_token': '< User token with Notification Privileges >',
|
||||
@ -21,7 +16,8 @@ module.exports.configure = hipchatConfigure;
|
||||
'hipchat_notify': '[ notify boolean to bug people ]',
|
||||
'hipchat_host' : 'api.hipchat.com'
|
||||
}
|
||||
]
|
||||
},
|
||||
categories: { default: { appenders: ['hipchat'], level: 'debug' }}
|
||||
});
|
||||
|
||||
var logger = log4js.getLogger('hipchat');
|
||||
@ -29,17 +25,16 @@ module.exports.configure = hipchatConfigure;
|
||||
|
||||
@invoke
|
||||
*/
|
||||
/* eslint no-unused-vars:0 */
|
||||
function hipchatNotifierResponseCallback(err, response, body) {
|
||||
|
||||
function hipchatNotifierResponseCallback(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function hipchatAppender(config) {
|
||||
function hipchatAppender(config, layout) {
|
||||
const notifier = hipchat.make(config.hipchat_room, config.hipchat_token);
|
||||
|
||||
// @lint W074 This function's cyclomatic complexity is too high. (10)
|
||||
return (loggingEvent) => {
|
||||
let notifierFn;
|
||||
|
||||
@ -68,7 +63,7 @@ function hipchatAppender(config) {
|
||||
}
|
||||
|
||||
// @TODO, re-work in timezoneOffset ?
|
||||
const layoutMessage = config.layout(loggingEvent);
|
||||
const layoutMessage = layout(loggingEvent);
|
||||
|
||||
// dispatch hipchat api request, do not return anything
|
||||
// [overide hipchatNotifierResponseCallback]
|
||||
@ -77,12 +72,14 @@ function hipchatAppender(config) {
|
||||
};
|
||||
}
|
||||
|
||||
function hipchatConfigure(config) {
|
||||
let layout;
|
||||
function hipchatConfigure(config, layouts) {
|
||||
let layout = layouts.messagePassThroughLayout;
|
||||
|
||||
if (!config.layout) {
|
||||
config.layout = layouts.messagePassThroughLayout;
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
|
||||
return hipchatAppender(config, layout);
|
||||
}
|
||||
|
||||
module.exports.configure = hipchatConfigure;
|
||||
|
||||
@ -125,6 +125,5 @@ function wrapErrorsWithInspect(items) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.appender = logFacesAppender;
|
||||
module.exports.configure = configure;
|
||||
module.exports.setContext = setContext;
|
||||
|
||||
@ -2,27 +2,16 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const layouts = require('../layouts');
|
||||
const debug = require('debug')('log4js:loggly');
|
||||
const loggly = require('loggly');
|
||||
const os = require('os');
|
||||
|
||||
const passThrough = layouts.messagePassThroughLayout;
|
||||
|
||||
let openRequests = 0;
|
||||
let shutdownCB;
|
||||
|
||||
function isAnyObject(value) {
|
||||
return value !== null && (typeof value === 'object' || typeof value === 'function');
|
||||
}
|
||||
|
||||
function numKeys(obj) {
|
||||
let res = 0;
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
res++; // eslint-disable-line no-plusplus
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return Object.keys(obj).length;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,9 +53,12 @@ function processTags(msgListArgs) {
|
||||
*/
|
||||
function logglyAppender(config, layout) {
|
||||
const client = loggly.createClient(config);
|
||||
if (!layout) layout = passThrough;
|
||||
let openRequests = 0;
|
||||
let shutdownCB;
|
||||
|
||||
return (loggingEvent) => {
|
||||
debug('creating appender.');
|
||||
|
||||
function app(loggingEvent) {
|
||||
const result = processTags(loggingEvent.data);
|
||||
const deTaggedData = result.deTaggedData;
|
||||
const additionalTags = result.additionalTags;
|
||||
@ -77,45 +69,52 @@ function logglyAppender(config, layout) {
|
||||
const msg = layout(loggingEvent);
|
||||
|
||||
openRequests += 1;
|
||||
debug('sending log event to loggly');
|
||||
client.log(
|
||||
{
|
||||
msg: msg,
|
||||
level: loggingEvent.level.levelStr,
|
||||
category: loggingEvent.categoryName,
|
||||
hostname: os.hostname().toString(),
|
||||
},
|
||||
additionalTags,
|
||||
(error) => {
|
||||
if (error) {
|
||||
console.error('log4js.logglyAppender - error occurred: ', error);
|
||||
}
|
||||
|
||||
client.log({
|
||||
msg: msg,
|
||||
level: loggingEvent.level.levelStr,
|
||||
category: loggingEvent.categoryName,
|
||||
hostname: os.hostname().toString(),
|
||||
}, additionalTags, (error) => {
|
||||
if (error) {
|
||||
console.error('log4js.logglyAppender - error occurred: ', error);
|
||||
debug('log event received by loggly.');
|
||||
|
||||
openRequests -= 1;
|
||||
|
||||
if (shutdownCB && openRequests === 0) {
|
||||
shutdownCB();
|
||||
|
||||
shutdownCB = undefined;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
openRequests -= 1;
|
||||
|
||||
if (shutdownCB && openRequests === 0) {
|
||||
shutdownCB();
|
||||
|
||||
shutdownCB = undefined;
|
||||
}
|
||||
});
|
||||
app.shutdown = function (cb) {
|
||||
debug('shutdown called');
|
||||
if (openRequests === 0) {
|
||||
cb();
|
||||
} else {
|
||||
shutdownCB = cb;
|
||||
}
|
||||
};
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
function configure(config) {
|
||||
let layout;
|
||||
function configure(config, layouts) {
|
||||
let layout = layouts.messagePassThroughLayout;
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
debug('configuring new appender');
|
||||
return logglyAppender(config, layout);
|
||||
}
|
||||
|
||||
function shutdown(cb) {
|
||||
if (openRequests === 0) {
|
||||
cb();
|
||||
} else {
|
||||
shutdownCB = cb;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.name = 'loggly';
|
||||
module.exports.appender = logglyAppender;
|
||||
module.exports.configure = configure;
|
||||
module.exports.shutdown = shutdown;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const util = require('util');
|
||||
const levels = require('./levels');
|
||||
const layouts = require('./layouts');
|
||||
const debug = require('debug')('log4js:configuration');
|
||||
|
||||
function not(thing) {
|
||||
return !thing;
|
||||
@ -48,6 +49,12 @@ class Configuration {
|
||||
not(appenderModule),
|
||||
`appender "${name}" is not valid (type "${config.type}" could not be found)`
|
||||
);
|
||||
if (appenderModule.appender) {
|
||||
debug(`DEPRECATION: Appender ${config.type} exports an appender function.`);
|
||||
}
|
||||
if (appenderModule.shutdown) {
|
||||
debug(`DEPRECATION: Appender ${config.type} exports a shutdown function.`);
|
||||
}
|
||||
return appenderModule.configure(config, layouts, this.configuredAppenders.get.bind(this.configuredAppenders));
|
||||
}
|
||||
|
||||
@ -66,6 +73,7 @@ class Configuration {
|
||||
`appender "${name}" is not valid (must be an object with property "type")`
|
||||
);
|
||||
|
||||
debug(`Creating appender ${name}`);
|
||||
this.configuredAppenders.set(name, this.createAppender(name, appenderConfig[name]));
|
||||
});
|
||||
}
|
||||
@ -114,6 +122,7 @@ class Configuration {
|
||||
` valid levels are ${levels.levels.join(', ')})`
|
||||
);
|
||||
|
||||
debug(`Creating category ${name}`);
|
||||
this.configuredCategories.set(name, { appenders: appenders, level: levels.toLevel(category.level) });
|
||||
});
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
* @static
|
||||
* Website: http://log4js.berlios.de
|
||||
*/
|
||||
const debug = require('debug')('log4js:main');
|
||||
const fs = require('fs');
|
||||
const Configuration = require('./configuration');
|
||||
const levels = require('./levels');
|
||||
@ -74,11 +75,12 @@ function sendLogEventToAppender(logEvent) {
|
||||
*/
|
||||
function getLogger(category) {
|
||||
const cat = category || 'default';
|
||||
return new Logger(cat, levelForCategory(cat), sendLogEventToAppender);
|
||||
return new Logger(sendLogEventToAppender, cat, levelForCategory(cat));
|
||||
}
|
||||
|
||||
function loadConfigurationFile(filename) {
|
||||
if (filename) {
|
||||
debug(`Loading configuration from ${filename}`);
|
||||
return JSON.parse(fs.readFileSync(filename, 'utf8'));
|
||||
}
|
||||
return filename;
|
||||
@ -90,6 +92,7 @@ function configure(configurationFileOrObject) {
|
||||
if (typeof configObject === 'string') {
|
||||
configObject = loadConfigurationFile(configurationFileOrObject);
|
||||
}
|
||||
debug(`Configuration is ${configObject}`);
|
||||
config = new Configuration(configObject);
|
||||
enabled = true;
|
||||
}
|
||||
@ -103,6 +106,7 @@ function configure(configurationFileOrObject) {
|
||||
* as the first argument.
|
||||
*/
|
||||
function shutdown(cb) {
|
||||
debug('Shutdown called. Disabling all log writing.');
|
||||
// First, disable all writing to appenders. This prevents appenders from
|
||||
// not being able to be drained because of run-away log writes.
|
||||
enabled = false;
|
||||
@ -113,15 +117,19 @@ function shutdown(cb) {
|
||||
let completed = 0;
|
||||
let error;
|
||||
|
||||
debug(`Found ${shutdownFunctions} appenders with shutdown functions.`);
|
||||
function complete(err) {
|
||||
error = error || err;
|
||||
completed += 1;
|
||||
debug(`Appender shutdowns complete: ${completed} / ${shutdownFunctions}`);
|
||||
if (completed >= shutdownFunctions) {
|
||||
debug('All shutdown functions completed.');
|
||||
cb(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (shutdownFunctions === 0) {
|
||||
debug('No appenders with shutdown functions found.');
|
||||
return cb();
|
||||
}
|
||||
|
||||
|
||||
@ -2,10 +2,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const debug = require('debug')('log4js:logger');
|
||||
const levels = require('./levels');
|
||||
|
||||
// let logWritesEnabled = true;
|
||||
|
||||
/**
|
||||
* @name LoggingEvent
|
||||
* @namespace Log4js
|
||||
@ -40,10 +39,14 @@ class LoggingEvent {
|
||||
* @author Stephan Strittmatter
|
||||
*/
|
||||
class Logger {
|
||||
constructor(name, level, dispatch) {
|
||||
constructor(dispatch, name, level) {
|
||||
if (typeof dispatch !== 'function') {
|
||||
throw new Error('No dispatch function provided.');
|
||||
}
|
||||
this.category = name;
|
||||
this.level = levels.toLevel(level, levels.TRACE);
|
||||
this.dispatch = dispatch;
|
||||
debug(`Logger created (${name}, ${level})`);
|
||||
}
|
||||
|
||||
setLevel(level) {
|
||||
@ -65,6 +68,7 @@ class Logger {
|
||||
}
|
||||
|
||||
_log(level, data) {
|
||||
debug(`sending log data (${level}, ${data}) to appenders`);
|
||||
const loggingEvent = new LoggingEvent(this.category, level, data);
|
||||
this.dispatch(loggingEvent);
|
||||
}
|
||||
@ -85,7 +89,7 @@ function addLevelMethods(target) {
|
||||
/* eslint prefer-rest-params:0 */
|
||||
// todo: once node v4 support dropped, use rest parameter instead
|
||||
const args = Array.from(arguments);
|
||||
if (/* logWritesEnabled &&*/ this.isLevelEnabled(level)) {
|
||||
if (this.isLevelEnabled(level)) {
|
||||
this._log(level, args);
|
||||
}
|
||||
};
|
||||
@ -93,24 +97,5 @@ function addLevelMethods(target) {
|
||||
|
||||
levels.levels.forEach(addLevelMethods);
|
||||
|
||||
/**
|
||||
* Disable all log writes.
|
||||
* @returns {void}
|
||||
*/
|
||||
// function disableAllLogWrites() {
|
||||
// logWritesEnabled = false;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Enable log writes.
|
||||
* @returns {void}
|
||||
*/
|
||||
// function enableAllLogWrites() {
|
||||
// logWritesEnabled = true;
|
||||
// }
|
||||
|
||||
module.exports.LoggingEvent = LoggingEvent;
|
||||
module.exports.Logger = Logger;
|
||||
// module.exports.disableAllLogWrites = disableAllLogWrites;
|
||||
// module.exports.enableAllLogWrites = enableAllLogWrites;
|
||||
// module.exports.addLevelMethods = addLevelMethods;
|
||||
|
||||
@ -1,78 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('tap').test;
|
||||
const fs = require('fs');
|
||||
const EOL = require('os').EOL || '\n';
|
||||
const log4js = require('../../lib/log4js');
|
||||
|
||||
function remove(filename) {
|
||||
try {
|
||||
fs.unlinkSync(filename);
|
||||
} catch (e) {
|
||||
// doesn't really matter if it failed
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup(done) {
|
||||
remove(`${__dirname}/categoryFilter-web.log`);
|
||||
remove(`${__dirname}/categoryFilter-noweb.log`);
|
||||
done();
|
||||
}
|
||||
const recording = require('../../lib/appenders/recording');
|
||||
|
||||
test('log4js categoryFilter', (batch) => {
|
||||
batch.beforeEach(cleanup);
|
||||
batch.beforeEach((done) => { recording.reset(); done(); });
|
||||
|
||||
batch.test('appender should exclude categories', (t) => {
|
||||
const logEvents = [];
|
||||
const appender = require(
|
||||
'../../lib/appenders/categoryFilter'
|
||||
).appender(
|
||||
['app'],
|
||||
(evt) => {
|
||||
logEvents.push(evt);
|
||||
}
|
||||
);
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(appender, ['app', 'web']);
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
recorder: { type: 'recording' },
|
||||
filtered: {
|
||||
type: 'categoryFilter',
|
||||
exclude: 'web',
|
||||
appender: 'recorder'
|
||||
}
|
||||
},
|
||||
categories: { default: { appenders: ['filtered'], level: 'DEBUG' } }
|
||||
});
|
||||
|
||||
const webLogger = log4js.getLogger('web');
|
||||
const appLogger = log4js.getLogger('app');
|
||||
|
||||
webLogger.debug('This should get logged');
|
||||
appLogger.debug('This should not');
|
||||
webLogger.debug('This should not get logged');
|
||||
appLogger.debug('This should get logged');
|
||||
webLogger.debug('Hello again');
|
||||
log4js.getLogger('db').debug('This shouldn\'t be included by the appender anyway');
|
||||
log4js.getLogger('db').debug('This should be included by the appender anyway');
|
||||
|
||||
const logEvents = recording.replay();
|
||||
t.equal(logEvents.length, 2);
|
||||
t.equal(logEvents[0].data[0], 'This should get logged');
|
||||
t.equal(logEvents[1].data[0], 'Hello again');
|
||||
t.equal(logEvents[1].data[0], 'This should be included by the appender anyway');
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('should work with configuration file', (t) => {
|
||||
log4js.configure('test/tap/with-categoryFilter.json');
|
||||
const logger = log4js.getLogger('app');
|
||||
const weblogger = log4js.getLogger('web');
|
||||
batch.test('should not really need a category filter any more', (t) => {
|
||||
log4js.configure({
|
||||
appenders: { recorder: { type: 'recording' } },
|
||||
categories: {
|
||||
default: { appenders: ['recorder'], level: 'DEBUG' },
|
||||
web: { appenders: ['recorder'], level: 'OFF' }
|
||||
}
|
||||
});
|
||||
const appLogger = log4js.getLogger('app');
|
||||
const webLogger = log4js.getLogger('web');
|
||||
|
||||
logger.info('Loading app');
|
||||
logger.info('Initialising indexes');
|
||||
weblogger.info('00:00:00 GET / 200');
|
||||
weblogger.warn('00:00:00 GET / 500');
|
||||
webLogger.debug('This should not get logged');
|
||||
appLogger.debug('This should get logged');
|
||||
webLogger.debug('Hello again');
|
||||
log4js.getLogger('db').debug('This should be included by the appender anyway');
|
||||
|
||||
setTimeout(() => {
|
||||
fs.readFile(`${__dirname}/categoryFilter-noweb.log`, 'utf8', (err, contents) => {
|
||||
const noWebMessages = contents.trim().split(EOL);
|
||||
t.same(noWebMessages, ['Loading app', 'Initialising indexes']);
|
||||
|
||||
fs.readFile(`${__dirname}/categoryFilter-web.log`, 'utf8', (e, c) => {
|
||||
const messages = c.trim().split(EOL);
|
||||
t.same(messages, ['00:00:00 GET / 200', '00:00:00 GET / 500']);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
}, 500);
|
||||
const logEvents = recording.replay();
|
||||
t.equal(logEvents.length, 2);
|
||||
t.equal(logEvents[0].data[0], 'This should get logged');
|
||||
t.equal(logEvents[1].data[0], 'This should be included by the appender anyway');
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.afterEach(cleanup);
|
||||
batch.end();
|
||||
});
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// 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>)
|
||||
// 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.
|
||||
//
|
||||
const test = require('tap').test;
|
||||
|
||||
// setup the configurations we want to test
|
||||
const configs = [
|
||||
undefined,
|
||||
null,
|
||||
{},
|
||||
{ foo: 'bar' },
|
||||
{ levels: null },
|
||||
{ levels: {} },
|
||||
{ levels: { foo: 'bar' } },
|
||||
{ levels: { A: 'INFO' } }
|
||||
];
|
||||
|
||||
test('log4js dodgy config', (batch) => {
|
||||
const log4js = require('../../lib/log4js');
|
||||
const logger = log4js.getLogger('test-logger');
|
||||
const error = log4js.levels.ERROR;
|
||||
logger.setLevel('ERROR');
|
||||
|
||||
configs.forEach((config) => {
|
||||
batch.test(`config of ${config} should not change logger level`, (t) => {
|
||||
log4js.configure(config);
|
||||
t.equal(logger.level, error);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
batch.end();
|
||||
});
|
||||
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('tap').test;
|
||||
const layouts = require('../../lib/layouts');
|
||||
const sandbox = require('sandboxed-module');
|
||||
|
||||
test('log4js console appender', (batch) => {
|
||||
@ -12,17 +11,20 @@ test('log4js console appender', (batch) => {
|
||||
messages.push(msg);
|
||||
}
|
||||
};
|
||||
const appenderModule = sandbox.require(
|
||||
'../../lib/appenders/console',
|
||||
const log4js = sandbox.require(
|
||||
'../../lib/log4js',
|
||||
{
|
||||
globals: {
|
||||
console: fakeConsole
|
||||
}
|
||||
}
|
||||
);
|
||||
log4js.configure({
|
||||
appenders: { console: { type: 'console', layout: { type: 'messagePassThrough' } } },
|
||||
categories: { default: { appenders: ['console'], level: 'DEBUG' } }
|
||||
});
|
||||
|
||||
const appender = appenderModule.appender(layouts.messagePassThroughLayout);
|
||||
appender({ data: ['blah'] });
|
||||
log4js.getLogger().info('blah');
|
||||
|
||||
t.equal(messages[0], 'blah');
|
||||
t.end();
|
||||
|
||||
@ -10,20 +10,25 @@ const EOL = require('os').EOL || '\n';
|
||||
function removeFile(filename) {
|
||||
try {
|
||||
fs.unlinkSync(path.join(__dirname, filename));
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// doesn't matter
|
||||
}
|
||||
}
|
||||
|
||||
test('../../lib/appenders/dateFile', (batch) => {
|
||||
batch.test('adding multiple dateFileAppenders', (t) => {
|
||||
const listenersCount = process.listeners('exit').length;
|
||||
const dateFileAppender = require('../../lib/appenders/dateFile');
|
||||
let count = 5;
|
||||
let logfile;
|
||||
|
||||
while (count--) {
|
||||
logfile = path.join(__dirname, `datefa-default-test${count}.log`);
|
||||
log4js.addAppender(dateFileAppender.appender(logfile));
|
||||
}
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
date0: { type: 'dateFile', filename: 'datefa-default-test0.log' },
|
||||
date1: { type: 'dateFile', filename: 'datefa-default-test1.log' },
|
||||
date2: { type: 'dateFile', filename: 'datefa-default-test2.log' },
|
||||
date3: { type: 'dateFile', filename: 'datefa-default-test3.log' },
|
||||
date4: { type: 'dateFile', filename: 'datefa-default-test4.log' }
|
||||
},
|
||||
categories: { default: { appenders: ['date0', 'date1', 'date2', 'date3', 'date4'], level: 'debug' } }
|
||||
});
|
||||
|
||||
t.teardown(() => {
|
||||
removeFile('datefa-default-test0.log');
|
||||
@ -59,6 +64,10 @@ test('../../lib/appenders/dateFile', (batch) => {
|
||||
this.end = function () {
|
||||
openedFiles.shift();
|
||||
};
|
||||
|
||||
this.write = function () {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,7 +75,7 @@ test('../../lib/appenders/dateFile', (batch) => {
|
||||
);
|
||||
|
||||
for (let i = 0; i < 5; i += 1) {
|
||||
dateFileAppender.appender(`test${i}`);
|
||||
dateFileAppender.configure({ filename: `test${i}` }, { basicLayout: function () {} });
|
||||
}
|
||||
t.equal(openedFiles.length, 5);
|
||||
exitListener();
|
||||
@ -76,10 +85,12 @@ test('../../lib/appenders/dateFile', (batch) => {
|
||||
|
||||
batch.test('with default settings', (t) => {
|
||||
const testFile = path.join(__dirname, 'date-appender-default.log');
|
||||
const appender = require('../../lib/appenders/dateFile').appender(testFile);
|
||||
log4js.configure({
|
||||
appenders: { date: { type: 'dateFile', filename: testFile } },
|
||||
categories: { default: { appenders: ['date'], level: 'DEBUG' } }
|
||||
});
|
||||
|
||||
const logger = log4js.getLogger('default-settings');
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(appender, 'default-settings');
|
||||
|
||||
logger.info('This should be in the file.');
|
||||
t.teardown(() => { removeFile('date-appender-default.log'); });
|
||||
@ -97,9 +108,17 @@ test('../../lib/appenders/dateFile', (batch) => {
|
||||
});
|
||||
|
||||
batch.test('configure with dateFileAppender', (t) => {
|
||||
// this config file defines one file appender (to ./date-file-test.log)
|
||||
// and sets the log level for "tests" to WARN
|
||||
log4js.configure('test/tap/with-dateFile.json');
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
date: {
|
||||
type: 'dateFile',
|
||||
filename: 'test/tap/date-file-test.log',
|
||||
pattern: '-from-MM-dd',
|
||||
layout: { type: 'messagePassThrough' }
|
||||
}
|
||||
},
|
||||
categories: { default: { appenders: ['date'], level: 'WARN' } }
|
||||
});
|
||||
const logger = log4js.getLogger('tests');
|
||||
logger.info('this should not be written to the file');
|
||||
logger.warn('this should be written to the file');
|
||||
@ -117,8 +136,8 @@ test('../../lib/appenders/dateFile', (batch) => {
|
||||
const format = require('date-format');
|
||||
|
||||
const options = {
|
||||
appenders: [
|
||||
{
|
||||
appenders: {
|
||||
date: {
|
||||
category: 'tests',
|
||||
type: 'dateFile',
|
||||
filename: 'test/tap/date-file-test',
|
||||
@ -128,16 +147,16 @@ test('../../lib/appenders/dateFile', (batch) => {
|
||||
type: 'messagePassThrough'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
categories: { default: { appenders: ['date'], level: 'debug' } }
|
||||
};
|
||||
|
||||
const thisTime = format.asString(options.appenders[0].pattern, new Date());
|
||||
const thisTime = format.asString(options.appenders.date.pattern, new Date());
|
||||
fs.writeFileSync(
|
||||
path.join(__dirname, `date-file-test${thisTime}`),
|
||||
`this is existing data${EOL}`,
|
||||
'utf8'
|
||||
);
|
||||
log4js.clearAppenders();
|
||||
log4js.configure(options);
|
||||
const logger = log4js.getLogger('tests');
|
||||
logger.warn('this should be written to the file with the appended date');
|
||||
@ -154,40 +173,5 @@ test('../../lib/appenders/dateFile', (batch) => {
|
||||
}, 100);
|
||||
});
|
||||
|
||||
batch.test('configure with cwd option', (t) => {
|
||||
let fileOpened;
|
||||
|
||||
const appender = sandbox.require(
|
||||
'../../lib/appenders/dateFile',
|
||||
{
|
||||
requires: {
|
||||
streamroller: {
|
||||
DateRollingFileStream: function (file) {
|
||||
fileOpened = file;
|
||||
return {
|
||||
on: function () {
|
||||
},
|
||||
end: function () {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
appender.configure(
|
||||
{
|
||||
filename: 'whatever.log',
|
||||
maxLogSize: 10
|
||||
},
|
||||
{ cwd: '/absolute/path/to' }
|
||||
);
|
||||
|
||||
const expected = path.sep + path.join('absolute', 'path', 'to', 'whatever.log');
|
||||
t.equal(fileOpened, expected, 'should prepend options.cwd to config.filename');
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.end();
|
||||
});
|
||||
|
||||
@ -29,11 +29,15 @@ test('file appender SIGHUP', (t) => {
|
||||
|
||||
this.end = function () {
|
||||
};
|
||||
|
||||
this.write = function () {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
).appender('sighup-test-file');
|
||||
).configure({ type: 'file', filename: 'sighup-test-file' }, { basicLayout: function () {} });
|
||||
|
||||
process.kill(process.pid, 'SIGHUP');
|
||||
t.plan(2);
|
||||
|
||||
@ -8,9 +8,7 @@ const log4js = require('../../lib/log4js');
|
||||
const zlib = require('zlib');
|
||||
const EOL = require('os').EOL || '\n';
|
||||
|
||||
log4js.clearAppenders();
|
||||
|
||||
function remove(filename) {
|
||||
function removeFile(filename) {
|
||||
try {
|
||||
fs.unlinkSync(filename);
|
||||
} catch (e) {
|
||||
@ -21,16 +19,24 @@ function remove(filename) {
|
||||
test('log4js fileAppender', (batch) => {
|
||||
batch.test('adding multiple fileAppenders', (t) => {
|
||||
const initialCount = process.listeners('exit').length;
|
||||
let count = 5;
|
||||
let logfile;
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
file0: { type: 'file', filename: 'fa-default-test0.log' },
|
||||
file1: { type: 'file', filename: 'fa-default-test1.log' },
|
||||
file2: { type: 'file', filename: 'fa-default-test2.log' },
|
||||
file3: { type: 'file', filename: 'fa-default-test3.log' },
|
||||
file4: { type: 'file', filename: 'fa-default-test4.log' },
|
||||
},
|
||||
categories: { default: { appenders: ['file0', 'file1', 'file2', 'file3', 'file4'], level: 'debug' } }
|
||||
});
|
||||
|
||||
while (count--) {
|
||||
logfile = path.join(__dirname, `fa-default-test${count}.log`);
|
||||
log4js.addAppender(
|
||||
require('../../lib/appenders/file').appender(logfile),
|
||||
'default-settings'
|
||||
);
|
||||
}
|
||||
t.tearDown(() => {
|
||||
removeFile('fa-default-test0.log');
|
||||
removeFile('fa-default-test1.log');
|
||||
removeFile('fa-default-test2.log');
|
||||
removeFile('fa-default-test3.log');
|
||||
removeFile('fa-default-test4.log');
|
||||
});
|
||||
|
||||
t.equal(initialCount + 1, process.listeners('exit').length, 'should not add more than one exit listener');
|
||||
t.end();
|
||||
@ -62,6 +68,10 @@ test('log4js fileAppender', (batch) => {
|
||||
openedFiles.shift();
|
||||
};
|
||||
|
||||
this.write = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
this.on = function () {
|
||||
};
|
||||
}
|
||||
@ -71,9 +81,9 @@ test('log4js fileAppender', (batch) => {
|
||||
);
|
||||
|
||||
for (let i = 0; i < 5; i += 1) {
|
||||
fileAppender.appender(`test${i}`, null, 100);
|
||||
fileAppender.configure({ filename: `test${i}` }, { basicLayout: function () {} });
|
||||
}
|
||||
t.ok(openedFiles);
|
||||
t.equal(openedFiles.length, 5);
|
||||
exitListener();
|
||||
t.equal(openedFiles.length, 0, 'should close all open files');
|
||||
t.end();
|
||||
@ -82,13 +92,14 @@ test('log4js fileAppender', (batch) => {
|
||||
batch.test('with default fileAppender settings', (t) => {
|
||||
const testFile = path.join(__dirname, 'fa-default-test.log');
|
||||
const logger = log4js.getLogger('default-settings');
|
||||
remove(testFile);
|
||||
removeFile(testFile);
|
||||
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(
|
||||
require('../../lib/appenders/file').appender(testFile),
|
||||
'default-settings'
|
||||
);
|
||||
t.tearDown(() => { removeFile(testFile); });
|
||||
|
||||
log4js.configure({
|
||||
appenders: { file: { type: 'file', filename: testFile } },
|
||||
categories: { default: { appenders: ['file'], level: 'debug' } }
|
||||
});
|
||||
|
||||
logger.info('This should be in the file.');
|
||||
|
||||
@ -104,86 +115,25 @@ test('log4js fileAppender', (batch) => {
|
||||
}, 100);
|
||||
});
|
||||
|
||||
batch.test('fileAppender subcategories', (t) => {
|
||||
log4js.clearAppenders();
|
||||
|
||||
function addAppender(cat) {
|
||||
const testFile = path.join(
|
||||
__dirname,
|
||||
`fa-subcategories-test-${cat.join('-').replace(/\./g, '_')}.log`
|
||||
);
|
||||
remove(testFile);
|
||||
log4js.addAppender(require('../../lib/appenders/file').appender(testFile), cat);
|
||||
return testFile;
|
||||
}
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
const file_sub1 = addAppender(['sub1']);
|
||||
const file_sub1_sub12$sub1_sub13 = addAppender(['sub1.sub12', 'sub1.sub13']);
|
||||
const file_sub1_sub12 = addAppender(['sub1.sub12']);
|
||||
const logger_sub1_sub12_sub123 = log4js.getLogger('sub1.sub12.sub123');
|
||||
const logger_sub1_sub13_sub133 = log4js.getLogger('sub1.sub13.sub133');
|
||||
const logger_sub1_sub14 = log4js.getLogger('sub1.sub14');
|
||||
const logger_sub2 = log4js.getLogger('sub2');
|
||||
|
||||
logger_sub1_sub12_sub123.info('sub1_sub12_sub123');
|
||||
logger_sub1_sub13_sub133.info('sub1_sub13_sub133');
|
||||
logger_sub1_sub14.info('sub1_sub14');
|
||||
logger_sub2.info('sub2');
|
||||
|
||||
setTimeout(() => {
|
||||
t.test('file contents', (assert) => {
|
||||
const fileContents = {
|
||||
file_sub1: fs.readFileSync(file_sub1).toString(),
|
||||
file_sub1_sub12$sub1_sub13: fs.readFileSync(file_sub1_sub12$sub1_sub13).toString(),
|
||||
file_sub1_sub12: fs.readFileSync(file_sub1_sub12).toString()
|
||||
};
|
||||
// everything but category 'sub2'
|
||||
assert.match(
|
||||
fileContents.file_sub1,
|
||||
/^(\[\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{3}] \[INFO] (sub1.sub12.sub123 - sub1_sub12_sub123|sub1.sub13.sub133 - sub1_sub13_sub133|sub1.sub14 - sub1_sub14)[\s\S]){3}$/ // eslint-disable-line
|
||||
);
|
||||
assert.ok(
|
||||
fileContents.file_sub1.match(/sub123/) &&
|
||||
fileContents.file_sub1.match(/sub133/) &&
|
||||
fileContents.file_sub1.match(/sub14/)
|
||||
);
|
||||
assert.ok(!fileContents.file_sub1.match(/sub2/));
|
||||
|
||||
// only catgories starting with 'sub1.sub12' and 'sub1.sub13'
|
||||
assert.match(
|
||||
fileContents.file_sub1_sub12$sub1_sub13,
|
||||
/^(\[\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{3}] \[INFO] (sub1.sub12.sub123 - sub1_sub12_sub123|sub1.sub13.sub133 - sub1_sub13_sub133)[\s\S]){2}$/ // eslint-disable-line
|
||||
);
|
||||
assert.ok(
|
||||
fileContents.file_sub1_sub12$sub1_sub13.match(/sub123/) &&
|
||||
fileContents.file_sub1_sub12$sub1_sub13.match(/sub133/)
|
||||
);
|
||||
assert.ok(!fileContents.file_sub1_sub12$sub1_sub13.match(/sub14|sub2/));
|
||||
|
||||
// only catgories starting with 'sub1.sub12'
|
||||
assert.match(
|
||||
fileContents.file_sub1_sub12,
|
||||
/^(\[\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{3}] \[INFO] (sub1.sub12.sub123 - sub1_sub12_sub123)[\s\S]){1}$/ // eslint-disable-line
|
||||
);
|
||||
assert.ok(!fileContents.file_sub1_sub12.match(/sub14|sub2|sub13/));
|
||||
assert.end();
|
||||
});
|
||||
t.end();
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
batch.test('with a max file size and no backups', (t) => {
|
||||
const testFile = path.join(__dirname, 'fa-maxFileSize-test.log');
|
||||
const logger = log4js.getLogger('max-file-size');
|
||||
remove(testFile);
|
||||
remove(`${testFile}.1`);
|
||||
|
||||
t.tearDown(() => {
|
||||
removeFile(testFile);
|
||||
removeFile(`${testFile}.1`);
|
||||
});
|
||||
removeFile(testFile);
|
||||
removeFile(`${testFile}.1`);
|
||||
|
||||
// log file of 100 bytes maximum, no backups
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(
|
||||
require('../../lib/appenders/file').appender(testFile, log4js.layouts.basicLayout, 100, 0),
|
||||
'max-file-size'
|
||||
);
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
file: { type: 'file', filename: testFile, maxLogSize: 100, backups: 0 }
|
||||
},
|
||||
categories: { default: { appenders: ['file'], level: 'debug' } }
|
||||
});
|
||||
|
||||
logger.info('This is the first log message.');
|
||||
logger.info('This is an intermediate log message.');
|
||||
logger.info('This is the second log message.');
|
||||
@ -206,16 +156,24 @@ test('log4js fileAppender', (batch) => {
|
||||
batch.test('with a max file size and 2 backups', (t) => {
|
||||
const testFile = path.join(__dirname, 'fa-maxFileSize-with-backups-test.log');
|
||||
const logger = log4js.getLogger('max-file-size-backups');
|
||||
remove(testFile);
|
||||
remove(`${testFile}.1`);
|
||||
remove(`${testFile}.2`);
|
||||
removeFile(testFile);
|
||||
removeFile(`${testFile}.1`);
|
||||
removeFile(`${testFile}.2`);
|
||||
|
||||
t.tearDown(() => {
|
||||
removeFile(testFile);
|
||||
removeFile(`${testFile}.1`);
|
||||
removeFile(`${testFile}.2`);
|
||||
});
|
||||
|
||||
// log file of 50 bytes maximum, 2 backups
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(
|
||||
require('../../lib/appenders/file').appender(testFile, log4js.layouts.basicLayout, 50, 2),
|
||||
'max-file-size-backups'
|
||||
);
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
file: { type: 'file', filename: testFile, maxLogSize: 50, backups: 2 }
|
||||
},
|
||||
categories: { default: { appenders: ['file'], level: 'debug' } }
|
||||
});
|
||||
|
||||
logger.info('This is the first log message.');
|
||||
logger.info('This is the second log message.');
|
||||
logger.info('This is the third log message.');
|
||||
@ -258,18 +216,23 @@ test('log4js fileAppender', (batch) => {
|
||||
batch.test('with a max file size and 2 compressed backups', (t) => {
|
||||
const testFile = path.join(__dirname, 'fa-maxFileSize-with-backups-compressed-test.log');
|
||||
const logger = log4js.getLogger('max-file-size-backups');
|
||||
remove(testFile);
|
||||
remove(`${testFile}.1.gz`);
|
||||
remove(`${testFile}.2.gz`);
|
||||
removeFile(testFile);
|
||||
removeFile(`${testFile}.1.gz`);
|
||||
removeFile(`${testFile}.2.gz`);
|
||||
|
||||
t.tearDown(() => {
|
||||
removeFile(testFile);
|
||||
removeFile(`${testFile}.1.gz`);
|
||||
removeFile(`${testFile}.2.gz`);
|
||||
});
|
||||
|
||||
// log file of 50 bytes maximum, 2 backups
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(
|
||||
require('../../lib/appenders/file').appender(
|
||||
testFile, log4js.layouts.basicLayout, 50, 2, { compress: true }
|
||||
),
|
||||
'max-file-size-backups'
|
||||
);
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
file: { type: 'file', filename: testFile, maxLogSize: 50, backups: 2, compress: true }
|
||||
},
|
||||
categories: { default: { appenders: ['file'], level: 'debug' } }
|
||||
});
|
||||
logger.info('This is the first log message.');
|
||||
logger.info('This is the second log message.');
|
||||
logger.info('This is the third log message.');
|
||||
@ -309,24 +272,6 @@ test('log4js fileAppender', (batch) => {
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
batch.test('configure with fileAppender', (t) => {
|
||||
// this config file defines one file appender (to ./tmp-tests.log)
|
||||
// and sets the log level for "tests" to WARN
|
||||
log4js.configure('./test/tap/log4js.json');
|
||||
const logger = log4js.getLogger('tests');
|
||||
logger.info('this should not be written to the file');
|
||||
logger.warn('this should be written to the file');
|
||||
|
||||
// wait for the file system to catch up
|
||||
setTimeout(() => {
|
||||
fs.readFile('tmp-tests.log', 'utf8', (err, contents) => {
|
||||
t.include(contents, `this should be written to the file${EOL}`);
|
||||
t.equal(contents.indexOf('this should not be written to the file'), -1);
|
||||
t.end();
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
|
||||
batch.test('when underlying stream errors', (t) => {
|
||||
let consoleArgs;
|
||||
let errorHandler;
|
||||
@ -351,13 +296,16 @@ test('log4js fileAppender', (batch) => {
|
||||
errorHandler = cb;
|
||||
}
|
||||
};
|
||||
this.write = function () {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
fileAppender.appender('test1.log', null, 100);
|
||||
fileAppender.configure({ filename: 'test1.log', maxLogSize: 100 }, { basicLayout: function () {} });
|
||||
errorHandler({ error: 'aargh' });
|
||||
|
||||
t.test('should log the error to console.error', (assert) => {
|
||||
|
||||
@ -6,8 +6,6 @@ const path = require('path');
|
||||
const log4js = require('../../lib/log4js');
|
||||
const EOL = require('os').EOL || '\n';
|
||||
|
||||
log4js.clearAppenders();
|
||||
|
||||
function remove(filename) {
|
||||
try {
|
||||
fs.unlinkSync(filename);
|
||||
@ -22,11 +20,14 @@ test('log4js fileSyncAppender', (batch) => {
|
||||
const logger = log4js.getLogger('default-settings');
|
||||
remove(testFile);
|
||||
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(
|
||||
require('../../lib/appenders/fileSync').appender(testFile),
|
||||
'default-settings'
|
||||
);
|
||||
t.tearDown(() => {
|
||||
remove(testFile);
|
||||
});
|
||||
|
||||
log4js.configure({
|
||||
appenders: { sync: { type: 'fileSync', filename: testFile } },
|
||||
categories: { default: { appenders: ['sync'], level: 'debug' } }
|
||||
});
|
||||
|
||||
logger.info('This should be in the file.');
|
||||
|
||||
@ -43,21 +44,20 @@ test('log4js fileSyncAppender', (batch) => {
|
||||
batch.test('with a max file size and no backups', (t) => {
|
||||
const testFile = path.join(__dirname, '/fa-maxFileSize-sync-test.log');
|
||||
const logger = log4js.getLogger('max-file-size');
|
||||
|
||||
remove(testFile);
|
||||
remove(`${testFile}.1`);
|
||||
|
||||
t.tearDown(() => {
|
||||
remove(testFile);
|
||||
remove(`${testFile}.1`);
|
||||
});
|
||||
|
||||
// log file of 100 bytes maximum, no backups
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(
|
||||
require(
|
||||
'../../lib/appenders/fileSync'
|
||||
).appender(
|
||||
testFile,
|
||||
log4js.layouts.basicLayout,
|
||||
100,
|
||||
0
|
||||
),
|
||||
'max-file-size'
|
||||
);
|
||||
log4js.configure({
|
||||
appenders: { sync: { type: 'fileSync', filename: testFile, maxLogSize: 100, backups: 0 } },
|
||||
categories: { default: { appenders: ['sync'], level: 'debug' } }
|
||||
});
|
||||
logger.info('This is the first log message.');
|
||||
logger.info('This is an intermediate log message.');
|
||||
logger.info('This is the second log message.');
|
||||
@ -89,17 +89,17 @@ test('log4js fileSyncAppender', (batch) => {
|
||||
remove(`${testFile}.1`);
|
||||
remove(`${testFile}.2`);
|
||||
|
||||
t.tearDown(() => {
|
||||
remove(testFile);
|
||||
remove(`${testFile}.1`);
|
||||
remove(`${testFile}.2`);
|
||||
});
|
||||
|
||||
// log file of 50 bytes maximum, 2 backups
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(
|
||||
require('../../lib/appenders/fileSync').appender(
|
||||
testFile,
|
||||
log4js.layouts.basicLayout,
|
||||
50,
|
||||
2
|
||||
),
|
||||
'max-file-size-backups'
|
||||
);
|
||||
log4js.configure({
|
||||
appenders: { sync: { type: 'fileSync', filename: testFile, maxLogSize: 50, backups: 2 } },
|
||||
categories: { default: { appenders: ['sync'], level: 'debug' } }
|
||||
});
|
||||
logger.info('This is the first log message.');
|
||||
logger.info('This is the second log message.');
|
||||
logger.info('This is the third log message.');
|
||||
@ -136,16 +136,16 @@ test('log4js fileSyncAppender', (batch) => {
|
||||
// this config defines one file appender (to ./tmp-sync-tests.log)
|
||||
// and sets the log level for "tests" to WARN
|
||||
log4js.configure({
|
||||
appenders: [
|
||||
{
|
||||
category: 'tests',
|
||||
type: 'file',
|
||||
filename: 'tmp-sync-tests.log',
|
||||
layout: { type: 'messagePassThrough' }
|
||||
}
|
||||
],
|
||||
|
||||
levels: { tests: 'WARN' }
|
||||
appenders: { sync: {
|
||||
type: 'fileSync',
|
||||
filename: 'tmp-sync-tests.log',
|
||||
layout: { type: 'messagePassThrough' }
|
||||
}
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ['sync'], level: 'debug' },
|
||||
tests: { appenders: ['sync'], level: 'warn' }
|
||||
}
|
||||
});
|
||||
const logger = log4js.getLogger('tests');
|
||||
logger.info('this should not be written to the file');
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
const test = require('tap').test;
|
||||
const sandbox = require('sandboxed-module');
|
||||
const log4js = require('../../lib/log4js');
|
||||
const realLayouts = require('../../lib/layouts');
|
||||
|
||||
const setupLogging = function (options, category, compressedLength) {
|
||||
@ -11,8 +10,9 @@ const setupLogging = function (options, category, compressedLength) {
|
||||
socket: {
|
||||
packetLength: 0,
|
||||
closed: false,
|
||||
close: function () {
|
||||
close: function (cb) {
|
||||
this.closed = true;
|
||||
if (cb) cb();
|
||||
},
|
||||
send: function (pkt, offset, pktLength, port, host) {
|
||||
fakeDgram.sent = true;
|
||||
@ -62,12 +62,12 @@ const setupLogging = function (options, category, compressedLength) {
|
||||
messagePassThroughLayout: realLayouts.messagePassThroughLayout
|
||||
};
|
||||
|
||||
const appender = sandbox.require('../../lib/appenders/gelf', {
|
||||
singleOnly: true,
|
||||
const log4js = sandbox.require('../../lib/log4js', {
|
||||
// singleOnly: true,
|
||||
requires: {
|
||||
dgram: fakeDgram,
|
||||
zlib: fakeZlib,
|
||||
'../layouts': fakeLayouts
|
||||
'./layouts': fakeLayouts
|
||||
},
|
||||
globals: {
|
||||
process: {
|
||||
@ -75,21 +75,29 @@ const setupLogging = function (options, category, compressedLength) {
|
||||
if (evt === 'exit') {
|
||||
exitHandler = handler;
|
||||
}
|
||||
}
|
||||
},
|
||||
env: {}
|
||||
},
|
||||
console: fakeConsole
|
||||
}
|
||||
});
|
||||
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(appender.configure(options || {}), category || 'gelf-test');
|
||||
options = options || {};
|
||||
options.type = 'gelf';
|
||||
|
||||
log4js.configure({
|
||||
appenders: { gelf: options },
|
||||
categories: { default: { appenders: ['gelf'], level: 'debug' } }
|
||||
});
|
||||
|
||||
return {
|
||||
dgram: fakeDgram,
|
||||
compress: fakeZlib,
|
||||
exitHandler: exitHandler,
|
||||
console: fakeConsole,
|
||||
layouts: fakeLayouts,
|
||||
logger: log4js.getLogger(category || 'gelf-test')
|
||||
logger: log4js.getLogger(category || 'gelf-test'),
|
||||
log4js: log4js
|
||||
};
|
||||
};
|
||||
|
||||
@ -163,6 +171,14 @@ test('log4js gelfAppender', (batch) => {
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('on shutdown should close open sockets', (t) => {
|
||||
const setup = setupLogging();
|
||||
setup.log4js.shutdown(() => {
|
||||
t.ok(setup.dgram.socket.closed);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
batch.test('on zlib error should output to console.error', (t) => {
|
||||
const setup = setupLogging();
|
||||
setup.compress.shouldError = true;
|
||||
|
||||
@ -1,126 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('tap').test;
|
||||
|
||||
test('log4js global loglevel', (batch) => {
|
||||
batch.test('global loglevel', (t) => {
|
||||
const log4js = require('../../lib/log4js');
|
||||
|
||||
t.test('set global loglevel on creation', (assert) => {
|
||||
const log1 = log4js.getLogger('log1');
|
||||
let level = 'OFF';
|
||||
if (log1.level.toString() === level) {
|
||||
level = 'TRACE';
|
||||
}
|
||||
assert.notEqual(log1.level.toString(), level);
|
||||
|
||||
log4js.setGlobalLogLevel(level);
|
||||
assert.equal(log1.level.toString(), level);
|
||||
|
||||
const log2 = log4js.getLogger('log2');
|
||||
assert.equal(log2.level.toString(), level);
|
||||
assert.end();
|
||||
});
|
||||
|
||||
t.test('global change loglevel', (assert) => {
|
||||
const log1 = log4js.getLogger('log1');
|
||||
const log2 = log4js.getLogger('log2');
|
||||
let level = 'OFF';
|
||||
if (log1.level.toString() === level) {
|
||||
level = 'TRACE';
|
||||
}
|
||||
assert.notEqual(log1.level.toString(), level);
|
||||
|
||||
log4js.setGlobalLogLevel(level);
|
||||
assert.equal(log1.level.toString(), level);
|
||||
assert.equal(log2.level.toString(), level);
|
||||
assert.end();
|
||||
});
|
||||
|
||||
t.test('override loglevel', (assert) => {
|
||||
const log1 = log4js.getLogger('log1');
|
||||
const log2 = log4js.getLogger('log2');
|
||||
let level = 'OFF';
|
||||
if (log1.level.toString() === level) {
|
||||
level = 'TRACE';
|
||||
}
|
||||
assert.notEqual(log1.level.toString(), level);
|
||||
|
||||
const oldLevel = log1.level.toString();
|
||||
assert.equal(log2.level.toString(), oldLevel);
|
||||
|
||||
log2.setLevel(level);
|
||||
assert.equal(log1.level.toString(), oldLevel);
|
||||
assert.equal(log2.level.toString(), level);
|
||||
assert.notEqual(oldLevel, level);
|
||||
|
||||
log2.removeLevel();
|
||||
assert.equal(log1.level.toString(), oldLevel);
|
||||
assert.equal(log2.level.toString(), oldLevel);
|
||||
assert.end();
|
||||
});
|
||||
|
||||
t.test('preload loglevel', (assert) => {
|
||||
const log1 = log4js.getLogger('log1');
|
||||
let level = 'OFF';
|
||||
if (log1.level.toString() === level) {
|
||||
level = 'TRACE';
|
||||
}
|
||||
assert.notEqual(log1.level.toString(), level);
|
||||
|
||||
const oldLevel = log1.level.toString();
|
||||
log4js.getLogger('log2').setLevel(level);
|
||||
|
||||
assert.equal(log1.level.toString(), oldLevel);
|
||||
|
||||
// get again same logger but as different variable
|
||||
const log2 = log4js.getLogger('log2');
|
||||
assert.equal(log2.level.toString(), level);
|
||||
assert.notEqual(oldLevel, level);
|
||||
|
||||
log2.removeLevel();
|
||||
assert.equal(log1.level.toString(), oldLevel);
|
||||
assert.equal(log2.level.toString(), oldLevel);
|
||||
assert.end();
|
||||
});
|
||||
|
||||
t.test('set level on all categories', (assert) => {
|
||||
// Get 2 loggers
|
||||
const log1 = log4js.getLogger('log1');
|
||||
const log2 = log4js.getLogger('log2');
|
||||
|
||||
// First a test with 2 categories with different levels
|
||||
const config = {
|
||||
levels: {
|
||||
log1: 'ERROR',
|
||||
log2: 'WARN'
|
||||
}
|
||||
};
|
||||
log4js.configure(config);
|
||||
|
||||
// Check if the levels are set correctly
|
||||
assert.equal('ERROR', log1.level.toString());
|
||||
assert.equal('WARN', log2.level.toString());
|
||||
|
||||
log1.removeLevel();
|
||||
log2.removeLevel();
|
||||
|
||||
// Almost identical test, but now we set
|
||||
// level on all categories
|
||||
const config2 = {
|
||||
levels: {
|
||||
'[all]': 'DEBUG'
|
||||
}
|
||||
};
|
||||
log4js.configure(config2);
|
||||
|
||||
// Check if the loggers got the DEBUG level
|
||||
assert.equal('DEBUG', log1.level.toString());
|
||||
assert.equal('DEBUG', log2.level.toString());
|
||||
assert.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.end();
|
||||
});
|
||||
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('tap').test;
|
||||
const log4js = require('../../lib/log4js');
|
||||
const sandbox = require('sandboxed-module');
|
||||
|
||||
function setupLogging(category, options) {
|
||||
@ -50,13 +49,19 @@ function setupLogging(category, options) {
|
||||
}
|
||||
};
|
||||
|
||||
const hipchatModule = sandbox.require('../../lib/appenders/hipchat', {
|
||||
const log4js = sandbox.require('../../lib/log4js', {
|
||||
requires: {
|
||||
'hipchat-notifier': fakeHipchatNotifier
|
||||
}
|
||||
});
|
||||
log4js.clearAppenders();
|
||||
log4js.addAppender(hipchatModule.configure(options), category);
|
||||
|
||||
options = options || {};
|
||||
options.type = 'hipchat';
|
||||
|
||||
log4js.configure({
|
||||
appenders: { hipchat: options },
|
||||
categories: { default: { appenders: ['hipchat'], level: 'debug' } }
|
||||
});
|
||||
|
||||
return {
|
||||
logger: log4js.getLogger(category),
|
||||
@ -112,7 +117,7 @@ test('HipChat appender', (batch) => {
|
||||
batch.test('when basicLayout is provided', (t) => {
|
||||
const topic = setupLogging('myLogger', {
|
||||
type: 'hipchat',
|
||||
layout: log4js.layouts.basicLayout
|
||||
layout: { type: 'basic' }
|
||||
});
|
||||
topic.logger.debug('Log event #3');
|
||||
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('tap').test;
|
||||
const path = require('path');
|
||||
const sandbox = require('sandboxed-module');
|
||||
|
||||
test('log4js-abspath', (batch) => {
|
||||
batch.test('options', (t) => {
|
||||
let appenderOptions;
|
||||
|
||||
const log4js = sandbox.require(
|
||||
'../../lib/log4js',
|
||||
{
|
||||
singleOnly: true,
|
||||
requires: {
|
||||
'./appenders/fake': {
|
||||
name: 'fake',
|
||||
appender: function () {
|
||||
},
|
||||
configure: function (configuration, options) {
|
||||
appenderOptions = options;
|
||||
return function () {
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const config = {
|
||||
appenders: [
|
||||
{
|
||||
type: 'fake',
|
||||
filename: 'cheesy-wotsits.log'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
log4js.configure(config, {
|
||||
cwd: '/absolute/path/to'
|
||||
});
|
||||
t.test('should be passed to appenders during configuration', (assert) => {
|
||||
assert.equal(appenderOptions.cwd, '/absolute/path/to');
|
||||
assert.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('file appender', (t) => {
|
||||
let fileOpened;
|
||||
|
||||
const fileAppender = sandbox.require(
|
||||
'../../lib/appenders/file',
|
||||
{
|
||||
requires: {
|
||||
streamroller: {
|
||||
RollingFileStream: function (file) {
|
||||
fileOpened = file;
|
||||
return {
|
||||
on: function () {
|
||||
},
|
||||
end: function () {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
fileAppender.configure(
|
||||
{
|
||||
filename: 'whatever.log',
|
||||
maxLogSize: 10
|
||||
},
|
||||
{ cwd: '/absolute/path/to' }
|
||||
);
|
||||
|
||||
t.test('should prepend options.cwd to config.filename', (assert) => {
|
||||
const expected = path.sep + path.join('absolute', 'path', 'to', 'whatever.log');
|
||||
assert.equal(fileOpened, expected);
|
||||
assert.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.end();
|
||||
});
|
||||
@ -5,31 +5,46 @@ const levels = require('../../lib/levels');
|
||||
const loggerModule = require('../../lib/logger');
|
||||
|
||||
const Logger = loggerModule.Logger;
|
||||
const testDispatcher = {
|
||||
events: [],
|
||||
dispatch: function (evt) {
|
||||
this.events.push(evt);
|
||||
}
|
||||
};
|
||||
const dispatch = testDispatcher.dispatch.bind(testDispatcher);
|
||||
|
||||
test('../../lib/logger', (batch) => {
|
||||
batch.test('constructor with no parameters', (t) => {
|
||||
const logger = new Logger();
|
||||
t.throws(
|
||||
() => new Logger(),
|
||||
new Error('No dispatch function provided.')
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('constructor with only dispatch', (t) => {
|
||||
const logger = new Logger(dispatch);
|
||||
t.equal(logger.category, Logger.DEFAULT_CATEGORY, 'should use default category');
|
||||
t.equal(logger.level, levels.TRACE, 'should use TRACE log level');
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('constructor with category', (t) => {
|
||||
const logger = new Logger('cheese');
|
||||
const logger = new Logger(dispatch, 'cheese');
|
||||
t.equal(logger.category, 'cheese', 'should use category');
|
||||
t.equal(logger.level, levels.TRACE, 'should use TRACE log level');
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('constructor with category and level', (t) => {
|
||||
const logger = new Logger('cheese', 'debug');
|
||||
const logger = new Logger(dispatch, 'cheese', 'debug');
|
||||
t.equal(logger.category, 'cheese', 'should use category');
|
||||
t.equal(logger.level, levels.DEBUG, 'should use level');
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('isLevelEnabled', (t) => {
|
||||
const logger = new Logger('cheese', 'info');
|
||||
const logger = new Logger(dispatch, 'cheese', 'info');
|
||||
const functions = [
|
||||
'isTraceEnabled', 'isDebugEnabled', 'isInfoEnabled',
|
||||
'isWarnEnabled', 'isErrorEnabled', 'isFatalEnabled'
|
||||
@ -52,28 +67,17 @@ test('../../lib/logger', (batch) => {
|
||||
t.end();
|
||||
});
|
||||
|
||||
batch.test('should emit log events', (t) => {
|
||||
const events = [];
|
||||
const logger = new Logger();
|
||||
logger.addListener('log', (logEvent) => {
|
||||
events.push(logEvent);
|
||||
});
|
||||
batch.test('should send log events to dispatch function', (t) => {
|
||||
const logger = new Logger(dispatch);
|
||||
logger.debug('Event 1');
|
||||
loggerModule.disableAllLogWrites();
|
||||
logger.debug('Event 2');
|
||||
loggerModule.enableAllLogWrites();
|
||||
logger.debug('Event 3');
|
||||
const events = testDispatcher.events;
|
||||
|
||||
t.test('when log writes are enabled', (assert) => {
|
||||
assert.equal(events[0].data[0], 'Event 1');
|
||||
assert.end();
|
||||
});
|
||||
|
||||
t.test('but not when log writes are disabled', (assert) => {
|
||||
assert.equal(events.length, 2);
|
||||
assert.equal(events[1].data[0], 'Event 3');
|
||||
assert.end();
|
||||
});
|
||||
t.equal(events.length, 3);
|
||||
t.equal(events[0].data[0], 'Event 1');
|
||||
t.equal(events[1].data[0], 'Event 2');
|
||||
t.equal(events[2].data[0], 'Event 3');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('tap').test;
|
||||
const log4js = require('../../lib/log4js');
|
||||
const sandbox = require('sandboxed-module');
|
||||
const layouts = require('../../lib/layouts');
|
||||
|
||||
function setupLogging(category, options) {
|
||||
const msgs = [];
|
||||
@ -26,10 +26,10 @@ function setupLogging(category, options) {
|
||||
layout: function (type, config) {
|
||||
this.type = type;
|
||||
this.config = config;
|
||||
return log4js.layouts.messagePassThroughLayout;
|
||||
return layouts.messagePassThroughLayout;
|
||||
},
|
||||
basicLayout: log4js.layouts.basicLayout,
|
||||
messagePassThroughLayout: log4js.layouts.messagePassThroughLayout
|
||||
basicLayout: layouts.basicLayout,
|
||||
messagePassThroughLayout: layouts.messagePassThroughLayout
|
||||
};
|
||||
|
||||
const fakeConsole = {
|
||||
@ -39,22 +39,26 @@ function setupLogging(category, options) {
|
||||
}
|
||||
};
|
||||
|
||||
const logglyModule = sandbox.require('../../lib/appenders/loggly', {
|
||||
const log4js = sandbox.require('../../lib/log4js', {
|
||||
requires: {
|
||||
loggly: fakeLoggly,
|
||||
'../layouts': fakeLayouts
|
||||
'./layouts': fakeLayouts
|
||||
},
|
||||
globals: {
|
||||
console: fakeConsole
|
||||
}
|
||||
});
|
||||
|
||||
log4js.addAppender(
|
||||
logglyModule.configure(options),
|
||||
logglyModule.shutdown,
|
||||
category);
|
||||
options = options || {};
|
||||
options.type = 'loggly';
|
||||
|
||||
log4js.configure({
|
||||
appenders: { loggly: options },
|
||||
categories: { default: { appenders: ['loggly'], level: 'trace' } }
|
||||
});
|
||||
|
||||
return {
|
||||
log4js: log4js,
|
||||
logger: log4js.getLogger(category),
|
||||
loggly: fakeLoggly,
|
||||
layouts: fakeLayouts,
|
||||
@ -63,8 +67,6 @@ function setupLogging(category, options) {
|
||||
};
|
||||
}
|
||||
|
||||
log4js.clearAppenders();
|
||||
|
||||
function setupTaggedLogging() {
|
||||
return setupLogging('loggly', {
|
||||
token: 'your-really-long-input-token',
|
||||
@ -105,9 +107,9 @@ test('log4js logglyAppender', (batch) => {
|
||||
tags: ['tag1', 'tag2']
|
||||
});
|
||||
|
||||
log4js.shutdown(() => { t.end(); });
|
||||
setup.log4js.shutdown(() => { t.end(); });
|
||||
|
||||
// shutdown will until after the last message has been sent to loggly
|
||||
// shutdown will wait until after the last message has been sent to loggly
|
||||
setup.results[0].cb();
|
||||
});
|
||||
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"appenders": [
|
||||
{
|
||||
"type": "categoryFilter",
|
||||
"exclude": "web",
|
||||
"appender": {
|
||||
"type": "file",
|
||||
"filename": "test/tap/categoryFilter-noweb.log",
|
||||
"layout": {
|
||||
"type": "messagePassThrough"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"category": "web",
|
||||
"type": "file",
|
||||
"filename": "test/tap/categoryFilter-web.log",
|
||||
"layout": {
|
||||
"type": "messagePassThrough"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
{
|
||||
"appenders": [
|
||||
{
|
||||
"category": "tests",
|
||||
"type": "dateFile",
|
||||
"filename": "test/tap/date-file-test.log",
|
||||
"pattern": "-from-MM-dd",
|
||||
"layout": {
|
||||
"type": "messagePassThrough"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"levels": {
|
||||
"tests": "WARN"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user