clean_log.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. 'use strict';
  2. const path = require('path');
  3. const fs = require('mz/fs');
  4. const moment = require('moment');
  5. const utils = require('../../utils');
  6. // clean all xxx.log.YYYY-MM-DD beofre expried date.
  7. module.exports = app => ({
  8. schedule: {
  9. type: 'worker', // only one worker run this task
  10. cron: '0 0 * * *', // run every day at 00:00
  11. },
  12. async task() {
  13. const logger = app.coreLogger;
  14. const logDirs = new Set();
  15. const loggerFiles = utils.walkLoggerFile(app.loggers);
  16. loggerFiles.forEach(file => {
  17. const logDir = path.dirname(file);
  18. logDirs.add(logDir);
  19. });
  20. const maxDays = app.config.logrotator.maxDays;
  21. if (maxDays && maxDays > 0) {
  22. try {
  23. const tasks = Array.from(logDirs, logdir => removeExpiredLogFiles(logdir, maxDays, logger));
  24. await Promise.all(tasks);
  25. } catch (err) {
  26. logger.error(err);
  27. }
  28. }
  29. logger.info('[egg-logrotator] clean all log before %s days', maxDays);
  30. },
  31. });
  32. // remove expired log files: xxx.log.YYYY-MM-DD
  33. async function removeExpiredLogFiles(logdir, maxDays, logger) {
  34. // ignore not exists dir
  35. const exists = await fs.exists(logdir);
  36. if (!exists) return;
  37. const files = await fs.readdir(logdir);
  38. const expriedDate = moment().subtract(maxDays, 'days').startOf('date');
  39. const names = files.filter(file => {
  40. const name = path.extname(file).substring(1);
  41. if (!/^\d{4}\-\d{2}\-\d{2}/.test(name)) {
  42. return false;
  43. }
  44. const date = moment(name, 'YYYY-MM-DD').startOf('date');
  45. if (!date.isValid()) {
  46. return false;
  47. }
  48. return date.isBefore(expriedDate);
  49. });
  50. if (names.length === 0) {
  51. return;
  52. }
  53. logger.info(`[egg-logrotator] start remove ${logdir} files: ${names.join(', ')}`);
  54. await Promise.all(names.map(name => {
  55. const logfile = path.join(logdir, name);
  56. return fs.unlink(logfile)
  57. .catch(err => {
  58. err.message = `[egg-logrotator] remove logfile ${logfile} error, ${err.message}`;
  59. logger.error(err);
  60. });
  61. }));
  62. }