index.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. // pre-load the core appenders so that webpack can find them
  9. const coreAppenders = new Map();
  10. coreAppenders.set('console', require('./console'));
  11. coreAppenders.set('stdout', require('./stdout'));
  12. coreAppenders.set('stderr', require('./stderr'));
  13. coreAppenders.set('file', require('./file'));
  14. coreAppenders.set('dateFile', require('./dateFile'));
  15. const appenders = new Map();
  16. const tryLoading = (modulePath, config) => {
  17. debug('Loading module from ', modulePath);
  18. try {
  19. return require(modulePath); //eslint-disable-line
  20. } catch (e) {
  21. // if the module was found, and we still got an error, then raise it
  22. configuration.throwExceptionIf(
  23. config,
  24. e.code !== 'MODULE_NOT_FOUND',
  25. `appender "${modulePath}" could not be loaded (error was: ${e})`
  26. );
  27. return undefined;
  28. }
  29. };
  30. const loadAppenderModule = (type, config) => coreAppenders.get(type) ||
  31. tryLoading(`./${type}`, config) ||
  32. tryLoading(type, config) ||
  33. tryLoading(path.join(path.dirname(require.main.filename), type), config) ||
  34. tryLoading(path.join(process.cwd(), type), config);
  35. const createAppender = (name, config) => {
  36. const appenderConfig = config.appenders[name];
  37. const appenderModule = loadAppenderModule(appenderConfig.type, config);
  38. configuration.throwExceptionIf(
  39. config,
  40. configuration.not(appenderModule),
  41. `appender "${name}" is not valid (type "${appenderConfig.type}" could not be found)`
  42. );
  43. if (appenderModule.appender) {
  44. debug(`DEPRECATION: Appender ${appenderConfig.type} exports an appender function.`);
  45. }
  46. if (appenderModule.shutdown) {
  47. debug(`DEPRECATION: Appender ${appenderConfig.type} exports a shutdown function.`);
  48. }
  49. debug(`${name}: clustering.isMaster ? ${clustering.isMaster()}`);
  50. debug(`${name}: appenderModule is ${require('util').inspect(appenderModule)}`); // eslint-disable-line
  51. return clustering.onlyOnMaster(() => {
  52. debug(`calling appenderModule.configure for ${name} / ${appenderConfig.type}`);
  53. return appenderModule.configure(
  54. adapters.modifyConfig(appenderConfig),
  55. layouts,
  56. appender => appenders.get(appender),
  57. levels
  58. );
  59. }, () => {});
  60. };
  61. const setup = (config) => {
  62. appenders.clear();
  63. Object.keys(config.appenders).forEach((name) => {
  64. debug(`Creating appender ${name}`);
  65. appenders.set(name, createAppender(name, config));
  66. });
  67. };
  68. setup({ appenders: { out: { type: 'stdout' } } });
  69. configuration.addListener((config) => {
  70. configuration.throwExceptionIf(
  71. config,
  72. configuration.not(configuration.anObject(config.appenders)),
  73. 'must have a property "appenders" of type object.'
  74. );
  75. const appenderNames = Object.keys(config.appenders);
  76. configuration.throwExceptionIf(
  77. config,
  78. configuration.not(appenderNames.length),
  79. 'must define at least one appender.'
  80. );
  81. appenderNames.forEach((name) => {
  82. configuration.throwExceptionIf(
  83. config,
  84. configuration.not(config.appenders[name].type),
  85. `appender "${name}" is not valid (must be an object with property "type")`
  86. );
  87. });
  88. });
  89. configuration.addListener(setup);
  90. module.exports = appenders;