[6a3a178] | 1 | const path = require('path');
|
---|
| 2 | const debug = require('debug')('log4js:appenders');
|
---|
| 3 | const configuration = require('../configuration');
|
---|
| 4 | const clustering = require('../clustering');
|
---|
| 5 | const levels = require('../levels');
|
---|
| 6 | const layouts = require('../layouts');
|
---|
| 7 | const adapters = require('./adapters');
|
---|
| 8 |
|
---|
| 9 | // pre-load the core appenders so that webpack can find them
|
---|
| 10 | const coreAppenders = new Map();
|
---|
| 11 | coreAppenders.set('console', require('./console'));
|
---|
| 12 | coreAppenders.set('stdout', require('./stdout'));
|
---|
| 13 | coreAppenders.set('stderr', require('./stderr'));
|
---|
| 14 | coreAppenders.set('logLevelFilter', require('./logLevelFilter'));
|
---|
| 15 | coreAppenders.set('categoryFilter', require('./categoryFilter'));
|
---|
| 16 | coreAppenders.set('noLogFilter', require('./noLogFilter'));
|
---|
| 17 | coreAppenders.set('file', require('./file'));
|
---|
| 18 | coreAppenders.set('dateFile', require('./dateFile'));
|
---|
| 19 | coreAppenders.set('fileSync', require('./fileSync'));
|
---|
| 20 |
|
---|
| 21 | const appenders = new Map();
|
---|
| 22 |
|
---|
| 23 | const tryLoading = (modulePath, config) => {
|
---|
| 24 | debug('Loading module from ', modulePath);
|
---|
| 25 | try {
|
---|
| 26 | return require(modulePath); //eslint-disable-line
|
---|
| 27 | } catch (e) {
|
---|
| 28 | // if the module was found, and we still got an error, then raise it
|
---|
| 29 | configuration.throwExceptionIf(
|
---|
| 30 | config,
|
---|
| 31 | e.code !== 'MODULE_NOT_FOUND',
|
---|
| 32 | `appender "${modulePath}" could not be loaded (error was: ${e})`
|
---|
| 33 | );
|
---|
| 34 | return undefined;
|
---|
| 35 | }
|
---|
| 36 | };
|
---|
| 37 |
|
---|
| 38 | const loadAppenderModule = (type, config) => coreAppenders.get(type)
|
---|
| 39 | || tryLoading(`./${type}`, config)
|
---|
| 40 | || tryLoading(type, config)
|
---|
| 41 | || (require.main && tryLoading(path.join(path.dirname(require.main.filename), type), config))
|
---|
| 42 | || tryLoading(path.join(process.cwd(), type), config);
|
---|
| 43 |
|
---|
| 44 | const appendersLoading = new Set();
|
---|
| 45 |
|
---|
| 46 | const getAppender = (name, config) => {
|
---|
| 47 | if (appenders.has(name)) return appenders.get(name);
|
---|
| 48 | if (!config.appenders[name]) return false;
|
---|
| 49 | if (appendersLoading.has(name)) throw new Error(`Dependency loop detected for appender ${name}.`);
|
---|
| 50 | appendersLoading.add(name);
|
---|
| 51 |
|
---|
| 52 | debug(`Creating appender ${name}`);
|
---|
| 53 | // eslint-disable-next-line no-use-before-define
|
---|
| 54 | const appender = createAppender(name, config);
|
---|
| 55 | appendersLoading.delete(name);
|
---|
| 56 | appenders.set(name, appender);
|
---|
| 57 | return appender;
|
---|
| 58 | };
|
---|
| 59 |
|
---|
| 60 | const createAppender = (name, config) => {
|
---|
| 61 | const appenderConfig = config.appenders[name];
|
---|
| 62 | const appenderModule = appenderConfig.type.configure
|
---|
| 63 | ? appenderConfig.type : loadAppenderModule(appenderConfig.type, config);
|
---|
| 64 | configuration.throwExceptionIf(
|
---|
| 65 | config,
|
---|
| 66 | configuration.not(appenderModule),
|
---|
| 67 | `appender "${name}" is not valid (type "${appenderConfig.type}" could not be found)`
|
---|
| 68 | );
|
---|
| 69 | if (appenderModule.appender) {
|
---|
| 70 | debug(`DEPRECATION: Appender ${appenderConfig.type} exports an appender function.`);
|
---|
| 71 | }
|
---|
| 72 | if (appenderModule.shutdown) {
|
---|
| 73 | debug(`DEPRECATION: Appender ${appenderConfig.type} exports a shutdown function.`);
|
---|
| 74 | }
|
---|
| 75 |
|
---|
| 76 | debug(`${name}: clustering.isMaster ? ${clustering.isMaster()}`);
|
---|
| 77 | debug(`${name}: appenderModule is ${require('util').inspect(appenderModule)}`); // eslint-disable-line
|
---|
| 78 | return clustering.onlyOnMaster(() => {
|
---|
| 79 | debug(`calling appenderModule.configure for ${name} / ${appenderConfig.type}`);
|
---|
| 80 | return appenderModule.configure(
|
---|
| 81 | adapters.modifyConfig(appenderConfig),
|
---|
| 82 | layouts,
|
---|
| 83 | appender => getAppender(appender, config),
|
---|
| 84 | levels
|
---|
| 85 | );
|
---|
| 86 | }, () => { });
|
---|
| 87 | };
|
---|
| 88 |
|
---|
| 89 | const setup = (config) => {
|
---|
| 90 | appenders.clear();
|
---|
| 91 | appendersLoading.clear();
|
---|
| 92 | const usedAppenders = [];
|
---|
| 93 | Object.values(config.categories).forEach(category => {
|
---|
| 94 | usedAppenders.push(...category.appenders)
|
---|
| 95 | });
|
---|
| 96 | Object.keys(config.appenders).forEach((name) => {
|
---|
| 97 | // dodgy hard-coding of special case for tcp-server which may not have
|
---|
| 98 | // any categories associated with it, but needs to be started up anyway
|
---|
| 99 | if (usedAppenders.includes(name) || config.appenders[name].type === 'tcp-server') {
|
---|
| 100 | getAppender(name, config);
|
---|
| 101 | }
|
---|
| 102 | });
|
---|
| 103 | };
|
---|
| 104 |
|
---|
| 105 | setup({ appenders: { out: { type: 'stdout' } }, categories: { default: { appenders: ['out'], level: 'trace' } } });
|
---|
| 106 |
|
---|
| 107 | configuration.addListener((config) => {
|
---|
| 108 | configuration.throwExceptionIf(
|
---|
| 109 | config,
|
---|
| 110 | configuration.not(configuration.anObject(config.appenders)),
|
---|
| 111 | 'must have a property "appenders" of type object.'
|
---|
| 112 | );
|
---|
| 113 | const appenderNames = Object.keys(config.appenders);
|
---|
| 114 | configuration.throwExceptionIf(
|
---|
| 115 | config,
|
---|
| 116 | configuration.not(appenderNames.length),
|
---|
| 117 | 'must define at least one appender.'
|
---|
| 118 | );
|
---|
| 119 |
|
---|
| 120 | appenderNames.forEach((name) => {
|
---|
| 121 | configuration.throwExceptionIf(
|
---|
| 122 | config,
|
---|
| 123 | configuration.not(config.appenders[name].type),
|
---|
| 124 | `appender "${name}" is not valid (must be an object with property "type")`
|
---|
| 125 | );
|
---|
| 126 | });
|
---|
| 127 | });
|
---|
| 128 |
|
---|
| 129 | configuration.addListener(setup);
|
---|
| 130 |
|
---|
| 131 | module.exports = appenders;
|
---|