333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
'use strict';
 
const assert = require('assert');
const fs = require('mz/fs');
const debug = require('debug')('egg-logrotator:rotator');
 
 
class Rotator {
 
  constructor(options) {
    this.options = options || {};
    assert(this.options.app, 'options.app is required');
    this.app = this.options.app;
    this.logger = this.app.coreLogger;
  }
 
  getRotateFiles() {
    throw new Error('not implement');
  }
 
  async rotate() {
    const files = await this.getRotateFiles();
    assert(files instanceof Map, 'getRotateFiles should return a Map');
    const rotatedFile = [];
    for (const file of files.values()) {
      try {
        debug('rename from %s to %s', file.srcPath, file.targetPath);
        await renameOrDelete(file.srcPath, file.targetPath);
        rotatedFile.push(`${file.srcPath} -> ${file.targetPath}`);
      } catch (err) {
        err.message = `[egg-logrotator] rename ${file.srcPath}, found exception: ` + err.message;
        this.logger.error(err);
      }
    }
 
    if (rotatedFile.length) {
      // tell every one to reload logger
      this.logger.info('[egg-logrotator] broadcast log-reload');
      this.app.messenger.sendToApp('log-reload');
      this.app.messenger.sendToAgent('log-reload');
    }
 
    this.logger.info('[egg-logrotator] rotate files success by %s, files %j',
      this.constructor.name, rotatedFile);
  }
}
 
module.exports = Rotator;
 
// rename from srcPath to targetPath, for example foo.log.1 > foo.log.2
async function renameOrDelete(srcPath, targetPath) {
  if (srcPath === targetPath) {
    return;
  }
  const srcExists = await fs.exists(srcPath);
  if (!srcExists) {
    return;
  }
  const targetExists = await fs.exists(targetPath);
  // if target file exists, then throw
  // because the target file always be renamed first.
  if (targetExists) {
    const err = new Error(`targetFile ${targetPath} exists!!!`);
    throw err;
  }
  await fs.rename(srcPath, targetPath);
}