multiFile.js 2.3 KB

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