multiFile.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. const debug = require('debug')('log4js:multiFile');
  2. const path = require('path');
  3. const fileAppender = require('./file');
  4. const findFileKey = (property, event) => event[property] || event.context[property];
  5. module.exports.configure = (config, layouts) => {
  6. debug('Creating a multi-file appender');
  7. const files = new Map();
  8. const timers = new Map();
  9. function checkForTimeout(fileKey) {
  10. const timer = timers.get(fileKey);
  11. const app = files.get(fileKey);
  12. if (timer && app) {
  13. if (Date.now() - timer.lastUsed > timer.timeout) {
  14. debug('%s not used for > %d ms => close', fileKey, timer.timeout);
  15. clearInterval(timer.interval);
  16. timers.delete(fileKey);
  17. files.delete(fileKey);
  18. app.shutdown((err) => {
  19. if (err) {
  20. debug('ignore error on file shutdown: %s', err.message);
  21. }
  22. });
  23. }
  24. }
  25. }
  26. const appender = (logEvent) => {
  27. const fileKey = findFileKey(config.property, logEvent);
  28. debug('fileKey for property ', config.property, ' is ', fileKey);
  29. if (fileKey) {
  30. let file = files.get(fileKey);
  31. debug('existing file appender is ', file);
  32. if (!file) {
  33. debug('creating new file appender');
  34. config.filename = path.join(config.base, fileKey + config.extension);
  35. file = fileAppender.configure(config, layouts);
  36. files.set(fileKey, file);
  37. if (config.timeout) {
  38. debug('creating new timer');
  39. timers.set(fileKey, {
  40. timeout: config.timeout,
  41. lastUsed: Date.now(),
  42. interval: setInterval(checkForTimeout.bind(null, fileKey), config.timeout)
  43. });
  44. }
  45. } else if (config.timeout) {
  46. timers.get(fileKey).lastUsed = Date.now();
  47. }
  48. file(logEvent);
  49. } else {
  50. debug('No fileKey for logEvent, quietly ignoring this log event');
  51. }
  52. };
  53. appender.shutdown = (cb) => {
  54. let shutdownFunctions = files.size;
  55. if (shutdownFunctions <= 0) {
  56. cb();
  57. }
  58. let error;
  59. timers.forEach((timer) => {
  60. clearInterval(timer.interval);
  61. });
  62. files.forEach((app, fileKey) => {
  63. debug('calling shutdown for ', fileKey);
  64. app.shutdown((err) => {
  65. error = error || err;
  66. shutdownFunctions -= 1;
  67. if (shutdownFunctions <= 0) {
  68. cb(error);
  69. }
  70. });
  71. });
  72. };
  73. return appender;
  74. };