Skip to content

Commit

Permalink
fix(tests): tests failing - config listeners not working in sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
Gareth Jones committed Jan 16, 2018
1 parent da703cd commit 8084e80
Show file tree
Hide file tree
Showing 17 changed files with 1,013 additions and 930 deletions.
13 changes: 13 additions & 0 deletions examples/layouts.js
@@ -0,0 +1,13 @@
const log4js = require('../lib/log4js');

log4js.configure({
appenders: {
out: { type: 'stdout', layout: { type: 'messagePassThrough' } }
},
categories: {
default: { appenders: ['out'], level: 'info' }
}
});

const logger = log4js.getLogger('thing');
logger.info('This should not have a timestamp');
141 changes: 70 additions & 71 deletions lib/LoggingEvent.js
@@ -1,81 +1,80 @@
const CircularJSON = require('circular-json');
const levels = require('./levels');

module.exports = (levels) => {
/**
* @name LoggingEvent
* @namespace Log4js
*/
class LoggingEvent {
/**
* @name LoggingEvent
* @namespace Log4js
* Models a logging event.
* @constructor
* @param {String} categoryName name of category
* @param {Log4js.Level} level level of message
* @param {Array} data objects to log
* @author Seth Chisamore
*/
class LoggingEvent {
/**
* Models a logging event.
* @constructor
* @param {String} categoryName name of category
* @param {Log4js.Level} level level of message
* @param {Array} data objects to log
* @author Seth Chisamore
*/
constructor(categoryName, level, data, context) {
this.startTime = new Date();
this.categoryName = categoryName;
this.data = data;
this.level = level;
this.context = Object.assign({}, context);
this.pid = process.pid;
// if (cluster && cluster.isWorker) {
// this.cluster = {
// workerId: cluster.worker.id,
// worker: process.pid
// };
// }
}
constructor(categoryName, level, data, context) {
this.startTime = new Date();
this.categoryName = categoryName;
this.data = data;
this.level = level;
this.context = Object.assign({}, context);
this.pid = process.pid;
// if (cluster && cluster.isWorker) {
// this.cluster = {
// workerId: cluster.worker.id,
// worker: process.pid
// };
// }
}

serialise() {
// JSON.stringify(new Error('test')) returns {}, which is not really useful for us.
// The following allows us to serialize errors correctly.
// Validate that we really are in this case
try {
const logData = this.data.map((e) => {
if (e && e.stack && CircularJSON.stringify(e) === '{}') {
e = { message: e.message, stack: e.stack };
}
return e;
});
this.data = logData;
return CircularJSON.stringify(this);
} catch (e) {
return new LoggingEvent(
'log4js',
levels.ERROR,
['Unable to serialise log event due to :', e]
).serialise();
}
serialise() {
// JSON.stringify(new Error('test')) returns {}, which is not really useful for us.
// The following allows us to serialize errors correctly.
// Validate that we really are in this case
try {
const logData = this.data.map((e) => {
if (e && e.stack && CircularJSON.stringify(e) === '{}') {
e = { message: e.message, stack: e.stack };
}
return e;
});
this.data = logData;
return CircularJSON.stringify(this);
} catch (e) {
return new LoggingEvent(
'log4js',
levels.ERROR,
['Unable to serialise log event due to :', e]
).serialise();
}
}

static deserialise(serialised) {
let event;
try {
event = CircularJSON.parse(serialised);
event.startTime = new Date(event.startTime);
event.level = levels.getLevel(event.level.levelStr);
event.data = event.data.map((e) => {
if (e && e.stack) {
const fakeError = new Error(e.message);
fakeError.stack = e.stack;
e = fakeError;
}
return e;
});
} catch (e) {
event = new LoggingEvent(
'log4js',
levels.ERROR,
['Unable to parse log:', serialised, 'because: ', e]
);
}

return event;
static deserialise(serialised) {
let event;
try {
event = CircularJSON.parse(serialised);
event.startTime = new Date(event.startTime);
event.level = levels.getLevel(event.level.levelStr);
event.data = event.data.map((e) => {
if (e && e.stack) {
const fakeError = new Error(e.message);
fakeError.stack = e.stack;
e = fakeError;
}
return e;
});
} catch (e) {
event = new LoggingEvent(
'log4js',
levels.ERROR,
['Unable to parse log:', serialised, 'because: ', e]
);
}

return event;
}
}

return LoggingEvent;
};
module.exports = LoggingEvent;
4 changes: 4 additions & 0 deletions lib/appenders/categoryFilter.js
@@ -1,9 +1,13 @@
'use strict';

const debug = require('debug')('log4js:categoryFilter');

function categoryFilter(excludes, appender) {
if (typeof excludes === 'string') excludes = [excludes];
return (logEvent) => {
debug(`Checking ${logEvent.categoryName} against ${excludes}`);
if (excludes.indexOf(logEvent.categoryName) === -1) {
debug('Not excluded, sending to appender');
appender(logEvent);
}
};
Expand Down
97 changes: 97 additions & 0 deletions lib/appenders/index.js
@@ -0,0 +1,97 @@
const path = require('path');
const debug = require('debug')('log4js:appenders');
const configuration = require('../configuration');
const clustering = require('../clustering');
const levels = require('../levels');
const layouts = require('../layouts');

const appenders = new Map();

const tryLoading = (modulePath, config) => {
debug('Loading module from ', modulePath);
try {
return require(modulePath); //eslint-disable-line
} catch (e) {
// if the module was found, and we still got an error, then raise it
configuration.throwExceptionIf(
config,
e.code !== 'MODULE_NOT_FOUND',
`appender "${modulePath}" could not be loaded (error was: ${e})`
);
return undefined;
}
};

const loadAppenderModule = (type, config) => tryLoading(`./${type}`, config) ||
tryLoading(type, config) ||
tryLoading(path.join(path.dirname(require.main.filename), type), config) ||
tryLoading(path.join(process.cwd(), type), config);

const createAppender = (name, config) => {
const appenderConfig = config.appenders[name];
const appenderModule = loadAppenderModule(appenderConfig.type, config);
configuration.throwExceptionIf(
config,
configuration.not(appenderModule),
`appender "${name}" is not valid (type "${appenderConfig.type}" could not be found)`
);
if (appenderModule.appender) {
debug(`DEPRECATION: Appender ${appenderConfig.type} exports an appender function.`);
}
if (appenderModule.shutdown) {
debug(`DEPRECATION: Appender ${appenderConfig.type} exports a shutdown function.`);
}

debug(`${name}: clustering.isMaster ? ${clustering.isMaster()}`);
debug(`${name}: appenderModule is ${require('util').inspect(appenderModule)}`); // eslint-disable-line
return clustering.onlyOnMaster(() => {
debug(`calling appenderModule.configure for ${name} / ${appenderConfig.type}`);
return appenderModule.configure(
appenderConfig,
layouts,
appender => appenders.get(appender),
levels
);
}, () => {});
};

const setup = (config) => {
appenders.clear();

Object.keys(config.appenders).forEach((name) => {
debug(`Creating appender ${name}`);
appenders.set(name, createAppender(name, config));
});
};

// setup({
// appenders: {
// stdout: { type: 'stdout' }
// }
// });

configuration.addListener((config) => {
configuration.throwExceptionIf(
config,
configuration.not(configuration.anObject(config.appenders)),
'must have a property "appenders" of type object.'
);
const appenderNames = Object.keys(config.appenders);
configuration.throwExceptionIf(
config,
configuration.not(appenderNames.length),
'must define at least one appender.'
);

appenderNames.forEach((name) => {
configuration.throwExceptionIf(
config,
configuration.not(config.appenders[name].type),
`appender "${name}" is not valid (must be an object with property "type")`
);
});
});

configuration.addListener(setup);

module.exports = appenders;

0 comments on commit 8084e80

Please sign in to comment.