loggers.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. 'use strict';
  2. const assert = require('assert');
  3. const debug = require('debug')('egg:logger');
  4. const utils = require('../utils');
  5. const Logger = require('./logger');
  6. const ErrorLogger = require('./error_logger');
  7. const CustomLogger = require('./custom_logger');
  8. const defaults = {
  9. env: 'default',
  10. type: '',
  11. dir: '',
  12. encoding: 'utf8',
  13. level: 'INFO',
  14. consoleLevel: 'NONE',
  15. outputJSON: false,
  16. outputJSONOnly: false,
  17. buffer: true,
  18. appLogName: '',
  19. coreLogName: '',
  20. agentLogName: '',
  21. errorLogName: '',
  22. concentrateError: 'duplicate',
  23. concentrateErrorLoggerName: 'errorLogger',
  24. };
  25. /**
  26. * Logger Manager, accord config to create multi loggers.
  27. */
  28. class Loggers extends Map {
  29. /**
  30. * @class
  31. * @param {Object} config - egg app config
  32. * - logger
  33. * - {String} env - egg app runtime env string, detail please see `app.config.env`
  34. * - {String} type - current process type, `application` or `agent`
  35. * - {String} dir - log file dir
  36. * - {String} [encoding = utf8] - log string encoding
  37. * - {String} [level = INFO] - file log level
  38. * - {String} [consoleLevel = NONE] - console log level
  39. * - {Boolean} [outputJSON = false] - send JSON log or not
  40. * - {Boolean} [outputJSONOnly = false] - only send JSON log
  41. * - {Boolean} [buffer = true] - use {@link FileBufferTransport} or not
  42. * - {String} appLogName - egg app file logger name
  43. * - {String} coreLogName - egg core file logger name
  44. * - {String} agentLogName - egg agent file logger name
  45. * - {String} errorLogName - err common error logger name
  46. * - {String} eol - end of line char
  47. * - {String} [concentrateError = duplicate] - whether write error logger to `concentrateErrorLoggerName` logger, `duplicate` / `redirect` / `ignore`
  48. * - {String} [concentrateErrorLoggerName = errorLogger] - concentrate logger name
  49. * - customLogger
  50. */
  51. constructor(config) {
  52. super();
  53. const loggerConfig = utils.assign({}, defaults, config.logger);
  54. const customLoggerConfig = config.customLogger;
  55. debug('Init loggers with options %j', loggerConfig);
  56. assert(loggerConfig.type, 'should pass config.logger.type');
  57. assert(loggerConfig.dir, 'should pass config.logger.dir');
  58. assert(loggerConfig.appLogName, 'should pass config.logger.appLogName');
  59. assert(loggerConfig.coreLogName, 'should pass config.logger.coreLogName');
  60. assert(loggerConfig.agentLogName, 'should pass config.logger.agentLogName');
  61. assert(loggerConfig.errorLogName, 'should pass config.logger.errorLogName');
  62. const errorLogger = new ErrorLogger(utils.assign({}, loggerConfig, {
  63. file: loggerConfig.errorLogName,
  64. }));
  65. this.set('errorLogger', errorLogger);
  66. let coreLogger;
  67. let logger;
  68. if (loggerConfig.type === 'agent') {
  69. logger = new Logger(utils.assign({}, loggerConfig, {
  70. file: loggerConfig.agentLogName,
  71. }));
  72. coreLogger = new Logger(utils.assign({}, loggerConfig, loggerConfig.coreLogger, {
  73. file: loggerConfig.agentLogName,
  74. }));
  75. } else {
  76. logger = new Logger(utils.assign({}, loggerConfig, {
  77. file: loggerConfig.appLogName,
  78. }));
  79. coreLogger = new Logger(utils.assign({}, loggerConfig, loggerConfig.coreLogger, {
  80. file: loggerConfig.coreLogName,
  81. }));
  82. }
  83. this.set('logger', logger);
  84. this.set('coreLogger', coreLogger);
  85. for (const name in customLoggerConfig) {
  86. const logger = new CustomLogger(utils.assign({}, loggerConfig, customLoggerConfig[name]));
  87. this.set(name, logger);
  88. }
  89. // setConcentrateError at the end
  90. this.setConcentrateError('logger', logger);
  91. this.setConcentrateError('coreLogger', coreLogger);
  92. for (const name in customLoggerConfig) {
  93. this.setConcentrateError(name, this.get(name));
  94. }
  95. }
  96. /**
  97. * Disable console logger
  98. */
  99. disableConsole() {
  100. for (const logger of this.values()) {
  101. logger.disable('console');
  102. }
  103. }
  104. reload() {
  105. for (const logger of this.values()) {
  106. logger.reload();
  107. }
  108. }
  109. /**
  110. * Add a logger
  111. * @param {String} name - logger name
  112. * @param {Logger} logger - Logger instance
  113. */
  114. set(name, logger) {
  115. if (this.has(name)) {
  116. return;
  117. }
  118. this[name] = logger;
  119. super.set(name, logger);
  120. }
  121. setConcentrateError(name, logger) {
  122. // redirect ERROR log to errorLogger, except errorLogger itself
  123. if (name !== 'errorLogger') {
  124. const concentrateLogger = this.get(logger.options.concentrateErrorLoggerName);
  125. if (!concentrateLogger) return;
  126. switch (logger.options.concentrateError) {
  127. case 'duplicate':
  128. logger.duplicate('error', concentrateLogger, { excludes: [ 'console' ] });
  129. break;
  130. case 'redirect':
  131. logger.redirect('error', concentrateLogger);
  132. break;
  133. case 'ignore':
  134. break;
  135. default:
  136. break;
  137. }
  138. }
  139. }
  140. }
  141. module.exports = Loggers;