@eggjs/logrotator 4.0.0 → 5.0.0-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -12
- package/README.zh-CN.md +11 -13
- package/dist/agent.d.ts +2 -0
- package/dist/agent.js +7 -0
- package/dist/app/extend/agent.d.ts +13 -0
- package/dist/app/extend/agent.js +7 -0
- package/dist/app/extend/application.d.ts +13 -0
- package/dist/app/extend/application.js +7 -0
- package/dist/app/schedule/clean_log.d.ts +12 -0
- package/dist/app/schedule/clean_log.js +60 -0
- package/dist/app/schedule/rotate_by_file.d.ts +13 -0
- package/dist/app/schedule/rotate_by_file.js +19 -0
- package/dist/app/schedule/rotate_by_hour.d.ts +13 -0
- package/dist/app/schedule/rotate_by_hour.js +19 -0
- package/dist/app/schedule/rotate_by_size.d.ts +13 -0
- package/dist/app/schedule/rotate_by_size.js +19 -0
- package/dist/app.d.ts +2 -0
- package/dist/app.js +7 -0
- package/dist/boot.d.ts +10 -0
- package/dist/boot.js +16 -0
- package/{src/config/config.default.ts → dist/config/config.default.d.ts} +11 -14
- package/dist/config/config.default.js +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/lib/day_rotator.d.ts +12 -0
- package/dist/lib/day_rotator.js +64 -0
- package/dist/lib/hour_rotator.d.ts +10 -0
- package/dist/lib/hour_rotator.js +38 -0
- package/dist/lib/rotator.d.ts +20 -0
- package/dist/lib/rotator.js +56 -0
- package/dist/lib/size_rotator.d.ts +9 -0
- package/dist/lib/size_rotator.js +61 -0
- package/dist/lib/utils.d.ts +12 -0
- package/dist/lib/utils.js +15 -0
- package/package.json +52 -68
- package/dist/commonjs/agent.d.ts +0 -2
- package/dist/commonjs/agent.js +0 -5
- package/dist/commonjs/app/extend/agent.d.ts +0 -5
- package/dist/commonjs/app/extend/agent.js +0 -8
- package/dist/commonjs/app/extend/application.d.ts +0 -5
- package/dist/commonjs/app/extend/application.js +0 -7
- package/dist/commonjs/app/schedule/clean_log.d.ts +0 -9
- package/dist/commonjs/app/schedule/clean_log.js +0 -74
- package/dist/commonjs/app/schedule/rotate_by_file.d.ts +0 -10
- package/dist/commonjs/app/schedule/rotate_by_file.js +0 -17
- package/dist/commonjs/app/schedule/rotate_by_hour.d.ts +0 -10
- package/dist/commonjs/app/schedule/rotate_by_hour.js +0 -17
- package/dist/commonjs/app/schedule/rotate_by_size.d.ts +0 -10
- package/dist/commonjs/app/schedule/rotate_by_size.js +0 -17
- package/dist/commonjs/app.d.ts +0 -2
- package/dist/commonjs/app.js +0 -5
- package/dist/commonjs/boot.d.ts +0 -6
- package/dist/commonjs/boot.js +0 -18
- package/dist/commonjs/config/config.default.d.ts +0 -64
- package/dist/commonjs/config/config.default.js +0 -16
- package/dist/commonjs/index.d.ts +0 -2
- package/dist/commonjs/index.js +0 -19
- package/dist/commonjs/lib/day_rotator.d.ts +0 -8
- package/dist/commonjs/lib/day_rotator.js +0 -89
- package/dist/commonjs/lib/hour_rotator.d.ts +0 -6
- package/dist/commonjs/lib/hour_rotator.js +0 -46
- package/dist/commonjs/lib/rotator.d.ts +0 -16
- package/dist/commonjs/lib/rotator.js +0 -78
- package/dist/commonjs/lib/size_rotator.d.ts +0 -5
- package/dist/commonjs/lib/size_rotator.js +0 -73
- package/dist/commonjs/lib/utils.d.ts +0 -11
- package/dist/commonjs/lib/utils.js +0 -24
- package/dist/commonjs/package.json +0 -3
- package/dist/commonjs/types.d.ts +0 -11
- package/dist/commonjs/types.js +0 -3
- package/dist/esm/agent.d.ts +0 -2
- package/dist/esm/agent.js +0 -3
- package/dist/esm/app/extend/agent.d.ts +0 -5
- package/dist/esm/app/extend/agent.js +0 -6
- package/dist/esm/app/extend/application.d.ts +0 -5
- package/dist/esm/app/extend/application.js +0 -5
- package/dist/esm/app/schedule/clean_log.d.ts +0 -9
- package/dist/esm/app/schedule/clean_log.js +0 -69
- package/dist/esm/app/schedule/rotate_by_file.d.ts +0 -10
- package/dist/esm/app/schedule/rotate_by_file.js +0 -15
- package/dist/esm/app/schedule/rotate_by_hour.d.ts +0 -10
- package/dist/esm/app/schedule/rotate_by_hour.js +0 -15
- package/dist/esm/app/schedule/rotate_by_size.d.ts +0 -10
- package/dist/esm/app/schedule/rotate_by_size.js +0 -15
- package/dist/esm/app.d.ts +0 -2
- package/dist/esm/app.js +0 -3
- package/dist/esm/boot.d.ts +0 -6
- package/dist/esm/boot.js +0 -14
- package/dist/esm/config/config.default.d.ts +0 -64
- package/dist/esm/config/config.default.js +0 -14
- package/dist/esm/index.d.ts +0 -2
- package/dist/esm/index.js +0 -3
- package/dist/esm/lib/day_rotator.d.ts +0 -8
- package/dist/esm/lib/day_rotator.js +0 -82
- package/dist/esm/lib/hour_rotator.d.ts +0 -6
- package/dist/esm/lib/hour_rotator.js +0 -39
- package/dist/esm/lib/rotator.d.ts +0 -16
- package/dist/esm/lib/rotator.js +0 -71
- package/dist/esm/lib/size_rotator.d.ts +0 -5
- package/dist/esm/lib/size_rotator.js +0 -66
- package/dist/esm/lib/utils.d.ts +0 -11
- package/dist/esm/lib/utils.js +0 -21
- package/dist/esm/package.json +0 -3
- package/dist/esm/types.d.ts +0 -11
- package/dist/esm/types.js +0 -2
- package/dist/package.json +0 -4
- package/src/agent.ts +0 -3
- package/src/app/extend/agent.ts +0 -6
- package/src/app/extend/application.ts +0 -5
- package/src/app/schedule/clean_log.ts +0 -74
- package/src/app/schedule/rotate_by_file.ts +0 -18
- package/src/app/schedule/rotate_by_hour.ts +0 -19
- package/src/app/schedule/rotate_by_size.ts +0 -18
- package/src/app.ts +0 -3
- package/src/boot.ts +0 -13
- package/src/index.ts +0 -3
- package/src/lib/day_rotator.ts +0 -91
- package/src/lib/hour_rotator.ts +0 -44
- package/src/lib/rotator.ts +0 -88
- package/src/lib/size_rotator.ts +0 -67
- package/src/lib/utils.ts +0 -26
- package/src/types.ts +0 -15
- package/src/typings/index.d.ts +0 -4
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# @eggjs/logrotator
|
|
2
2
|
|
|
3
3
|
[![NPM version][npm-image]][npm-url]
|
|
4
|
-
[](https://github.com/eggjs/logrotator/actions/workflows/nodejs.yml)
|
|
5
|
-
[](https://codecov.io/gh/eggjs/logrotator)
|
|
6
4
|
[![npm download][download-image]][download-url]
|
|
7
5
|
[](https://nodejs.org/en/download/)
|
|
8
6
|
[](https://makeapullrequest.com)
|
|
@@ -37,14 +35,14 @@ exports.logrotator = {
|
|
|
37
35
|
```js
|
|
38
36
|
// if any files need rotate by file size, config here
|
|
39
37
|
exports.logrotator = {
|
|
40
|
-
filesRotateByHour: [],
|
|
41
|
-
hourDelimiter: '-',
|
|
42
|
-
filesRotateBySize: [],
|
|
43
|
-
maxFileSize: 50 * 1024 * 1024,
|
|
44
|
-
maxFiles: 10,
|
|
45
|
-
rotateDuration: 60000,
|
|
46
|
-
maxDays: 31,
|
|
47
|
-
gzip:false,
|
|
38
|
+
filesRotateByHour: [], // list of files that will be rotated by hour
|
|
39
|
+
hourDelimiter: '-', // rotate the file by hour use specified delimiter
|
|
40
|
+
filesRotateBySize: [], // list of files that will be rotated by size
|
|
41
|
+
maxFileSize: 50 * 1024 * 1024, // Max file size to judge if any file need rotate
|
|
42
|
+
maxFiles: 10, // pieces rotate by size
|
|
43
|
+
rotateDuration: 60000, // time interval to judge if any file need rotate
|
|
44
|
+
maxDays: 31, // keep max days log files, default is `31`. Set `0` to keep all logs
|
|
45
|
+
gzip: false, // use gzip compress logger on rotate file, default is `false`. Set `true` to enable
|
|
48
46
|
};
|
|
49
47
|
```
|
|
50
48
|
|
|
@@ -86,7 +84,7 @@ module.exports = app => {
|
|
|
86
84
|
},
|
|
87
85
|
async task() {
|
|
88
86
|
await rotator.rotate();
|
|
89
|
-
}
|
|
87
|
+
},
|
|
90
88
|
};
|
|
91
89
|
};
|
|
92
90
|
|
|
@@ -118,6 +116,6 @@ Please open an issue [here](https://github.com/eggjs/egg/issues).
|
|
|
118
116
|
|
|
119
117
|
## Contributors
|
|
120
118
|
|
|
121
|
-
[](https://github.com/eggjs/egg/graphs/contributors)
|
|
122
120
|
|
|
123
121
|
Made with [contributors-img](https://contrib.rocks).
|
package/README.zh-CN.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# @eggjs/logrotator
|
|
2
2
|
|
|
3
3
|
[![NPM version][npm-image]][npm-url]
|
|
4
|
-
[](https://github.com/eggjs/logrotator/actions/workflows/nodejs.yml)
|
|
5
|
-
[](https://codecov.io/gh/eggjs/logrotator)
|
|
6
4
|
[![npm download][download-image]][download-url]
|
|
7
5
|
[](https://nodejs.org/en/download/)
|
|
8
6
|
[](https://makeapullrequest.com)
|
|
@@ -28,13 +26,13 @@ exports.logrotator = true;
|
|
|
28
26
|
```js
|
|
29
27
|
// 如果有需要按照文件大小切割的日志,在这里配置
|
|
30
28
|
exports.logrotator = {
|
|
31
|
-
filesRotateByHour: [],
|
|
32
|
-
hourDelimiter: '-',
|
|
33
|
-
filesRotateBySize: [],
|
|
34
|
-
maxFileSize: 50 * 1024 * 1024,
|
|
35
|
-
maxFiles: 10,
|
|
36
|
-
rotateDuration: 60000,
|
|
37
|
-
maxDays: 31,
|
|
29
|
+
filesRotateByHour: [], // 需要按小时切割的文件
|
|
30
|
+
hourDelimiter: '-', // 按照小时切割的文件, 小时部分的分隔符.
|
|
31
|
+
filesRotateBySize: [], // 需要按大小切割的文件,其他日志文件仍按照通常方式切割
|
|
32
|
+
maxFileSize: 50 * 1024 * 1024, // 最大文件大小,默认为50m
|
|
33
|
+
maxFiles: 10, // 按大小切割时,文件最大切割的份数
|
|
34
|
+
rotateDuration: 60000, // 按大小切割时,文件扫描的间隔时间
|
|
35
|
+
maxDays: 31, // 日志保留最久天数
|
|
38
36
|
};
|
|
39
37
|
```
|
|
40
38
|
|
|
@@ -74,9 +72,9 @@ module.exports = app => {
|
|
|
74
72
|
type: 'worker', // only one worker run this task
|
|
75
73
|
cron: '10 * * * *', // custom cron, or use interval
|
|
76
74
|
},
|
|
77
|
-
*
|
|
75
|
+
*task() {
|
|
78
76
|
yield rotator.rotate();
|
|
79
|
-
}
|
|
77
|
+
},
|
|
80
78
|
};
|
|
81
79
|
};
|
|
82
80
|
|
|
@@ -86,7 +84,7 @@ function getRotator(app) {
|
|
|
86
84
|
// LogRotator will rename srcPath to targetPath
|
|
87
85
|
// 返回一个 map,其中包含 srcPath 和 targetPath,
|
|
88
86
|
// LogRotator 会将 srcPath 重命名成 targetPath
|
|
89
|
-
*
|
|
87
|
+
*getRotateFiles() {
|
|
90
88
|
const files = new Map();
|
|
91
89
|
const srcPath = '/home/admin/foo.log';
|
|
92
90
|
const targetPath = '/home/admin/foo.log.2016.09.30';
|
|
@@ -110,6 +108,6 @@ Please open an issue [here](https://github.com/eggjs/egg/issues).
|
|
|
110
108
|
|
|
111
109
|
## Contributors
|
|
112
110
|
|
|
113
|
-
[](https://github.com/eggjs/egg/graphs/contributors)
|
|
114
112
|
|
|
115
113
|
Made with [contributors-img](https://contrib.rocks).
|
package/dist/agent.d.ts
ADDED
package/dist/agent.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LogRotator } from "../../lib/rotator.js";
|
|
2
|
+
|
|
3
|
+
//#region src/app/extend/agent.d.ts
|
|
4
|
+
declare const _default: {
|
|
5
|
+
LogRotator: typeof LogRotator;
|
|
6
|
+
};
|
|
7
|
+
declare module 'egg' {
|
|
8
|
+
interface Agent {
|
|
9
|
+
LogRotator: typeof LogRotator;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { _default as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LogRotator } from "../../lib/rotator.js";
|
|
2
|
+
|
|
3
|
+
//#region src/app/extend/application.d.ts
|
|
4
|
+
declare const _default: {
|
|
5
|
+
LogRotator: typeof LogRotator;
|
|
6
|
+
};
|
|
7
|
+
declare module 'egg' {
|
|
8
|
+
interface Application {
|
|
9
|
+
LogRotator: typeof LogRotator;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { _default as default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Application } from "egg";
|
|
2
|
+
|
|
3
|
+
//#region src/app/schedule/clean_log.d.ts
|
|
4
|
+
declare const _default: (app: Application) => {
|
|
5
|
+
schedule: {
|
|
6
|
+
type: string;
|
|
7
|
+
cron: string;
|
|
8
|
+
};
|
|
9
|
+
task(): Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { _default as default };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { walkLoggerFile } from "../../lib/utils.js";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { exists } from "utility";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import moment from "moment";
|
|
6
|
+
|
|
7
|
+
//#region src/app/schedule/clean_log.ts
|
|
8
|
+
var clean_log_default = (app) => ({
|
|
9
|
+
schedule: {
|
|
10
|
+
type: "worker",
|
|
11
|
+
cron: "0 0 * * *"
|
|
12
|
+
},
|
|
13
|
+
async task() {
|
|
14
|
+
const logger = app.coreLogger;
|
|
15
|
+
const logDirs = /* @__PURE__ */ new Set();
|
|
16
|
+
const loggerFiles = walkLoggerFile(app.loggers);
|
|
17
|
+
for (const file of loggerFiles) {
|
|
18
|
+
const logDir = path.dirname(file);
|
|
19
|
+
logDirs.add(logDir);
|
|
20
|
+
}
|
|
21
|
+
const maxDays = app.config.logrotator.maxDays;
|
|
22
|
+
if (maxDays && maxDays > 0) 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
|
+
logger.info("[@eggjs/logrotator] clean all log before %s days", maxDays);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
async function removeExpiredLogFiles(logDir, maxDays, logger) {
|
|
32
|
+
if (!await exists(logDir)) {
|
|
33
|
+
logger.warn(`[@eggjs/logrotator] logDir ${logDir} not exists`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const files = await fs.readdir(logDir);
|
|
37
|
+
const expiredDate = moment().subtract(maxDays, "days").startOf("date");
|
|
38
|
+
const names = files.filter((file) => {
|
|
39
|
+
const name = path.extname(file).slice(1);
|
|
40
|
+
if (!/^\d{4}-\d{2}-\d{2}/.test(name)) return false;
|
|
41
|
+
const date = moment(name, "YYYY-MM-DD").startOf("date");
|
|
42
|
+
if (!date.isValid()) return false;
|
|
43
|
+
return date.isBefore(expiredDate);
|
|
44
|
+
});
|
|
45
|
+
if (names.length === 0) return;
|
|
46
|
+
logger.info(`[@eggjs/logrotator] start remove ${logDir} files: ${names.join(", ")}`);
|
|
47
|
+
await Promise.all(names.map(async (name) => {
|
|
48
|
+
const logFile = path.join(logDir, name);
|
|
49
|
+
try {
|
|
50
|
+
await fs.unlink(logFile);
|
|
51
|
+
} catch (e) {
|
|
52
|
+
const err = e;
|
|
53
|
+
err.message = `[@eggjs/logrotator] remove logFile ${logFile} error, ${err.message}`;
|
|
54
|
+
logger.error(err);
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
export { clean_log_default as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Application } from "egg";
|
|
2
|
+
|
|
3
|
+
//#region src/app/schedule/rotate_by_file.d.ts
|
|
4
|
+
declare const _default: (app: Application) => {
|
|
5
|
+
schedule: {
|
|
6
|
+
type: string;
|
|
7
|
+
cron: string;
|
|
8
|
+
disable: boolean;
|
|
9
|
+
};
|
|
10
|
+
task(): Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { _default as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DayRotator } from "../../lib/day_rotator.js";
|
|
2
|
+
|
|
3
|
+
//#region src/app/schedule/rotate_by_file.ts
|
|
4
|
+
var rotate_by_file_default = (app) => {
|
|
5
|
+
const rotator = new DayRotator({ app });
|
|
6
|
+
return {
|
|
7
|
+
schedule: {
|
|
8
|
+
type: "worker",
|
|
9
|
+
cron: "1 0 0 * * *",
|
|
10
|
+
disable: app.config.logrotator.disableRotateByDay
|
|
11
|
+
},
|
|
12
|
+
async task() {
|
|
13
|
+
await rotator.rotate();
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { rotate_by_file_default as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Application } from "egg";
|
|
2
|
+
|
|
3
|
+
//#region src/app/schedule/rotate_by_hour.d.ts
|
|
4
|
+
declare const _default: (app: Application) => {
|
|
5
|
+
schedule: {
|
|
6
|
+
type: string;
|
|
7
|
+
cron: string;
|
|
8
|
+
disable: boolean;
|
|
9
|
+
};
|
|
10
|
+
task(): Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { _default as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HourRotator } from "../../lib/hour_rotator.js";
|
|
2
|
+
|
|
3
|
+
//#region src/app/schedule/rotate_by_hour.ts
|
|
4
|
+
var rotate_by_hour_default = (app) => {
|
|
5
|
+
const rotator = new HourRotator({ app });
|
|
6
|
+
return {
|
|
7
|
+
schedule: {
|
|
8
|
+
type: "worker",
|
|
9
|
+
cron: "1 * * * *",
|
|
10
|
+
disable: (app.config.logrotator.filesRotateByHour || []).length === 0
|
|
11
|
+
},
|
|
12
|
+
async task() {
|
|
13
|
+
await rotator.rotate();
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { rotate_by_hour_default as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Application } from "egg";
|
|
2
|
+
|
|
3
|
+
//#region src/app/schedule/rotate_by_size.d.ts
|
|
4
|
+
declare const _default: (app: Application) => {
|
|
5
|
+
schedule: {
|
|
6
|
+
type: string;
|
|
7
|
+
interval: number;
|
|
8
|
+
disable: boolean;
|
|
9
|
+
};
|
|
10
|
+
task(): Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { _default as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SizeRotator } from "../../lib/size_rotator.js";
|
|
2
|
+
|
|
3
|
+
//#region src/app/schedule/rotate_by_size.ts
|
|
4
|
+
var rotate_by_size_default = (app) => {
|
|
5
|
+
const rotator = new SizeRotator({ app });
|
|
6
|
+
return {
|
|
7
|
+
schedule: {
|
|
8
|
+
type: "worker",
|
|
9
|
+
interval: app.config.logrotator.rotateDuration,
|
|
10
|
+
disable: (app.config.logrotator.filesRotateBySize || []).length === 0
|
|
11
|
+
},
|
|
12
|
+
async task() {
|
|
13
|
+
await rotator.rotate();
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { rotate_by_size_default as default };
|
package/dist/app.d.ts
ADDED
package/dist/app.js
ADDED
package/dist/boot.d.ts
ADDED
package/dist/boot.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/boot.ts
|
|
2
|
+
var Boot = class {
|
|
3
|
+
app;
|
|
4
|
+
constructor(app) {
|
|
5
|
+
this.app = app;
|
|
6
|
+
}
|
|
7
|
+
async didLoad() {
|
|
8
|
+
this.app.messenger.on("log-reload", () => {
|
|
9
|
+
this.app.loggers.reload();
|
|
10
|
+
this.app.coreLogger.info("[@eggjs/logrotator] %s logger reload: got log-reload message", this.app.type);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { Boot };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
//#region src/config/config.default.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* logrotator options
|
|
3
4
|
* @member Config#logrotator
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
|
+
interface LogrotatorConfig {
|
|
6
7
|
/**
|
|
7
8
|
* Disable rotate by day
|
|
8
9
|
*
|
|
@@ -58,17 +59,13 @@ export interface LogrotatorConfig {
|
|
|
58
59
|
*/
|
|
59
60
|
gzip: boolean;
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
logrotator: {
|
|
64
|
-
disableRotateByDay: false,
|
|
65
|
-
filesRotateByHour: null,
|
|
66
|
-
hourDelimiter: '-',
|
|
67
|
-
filesRotateBySize: null,
|
|
68
|
-
maxFileSize: 50 * 1024 * 1024,
|
|
69
|
-
maxFiles: 10,
|
|
70
|
-
rotateDuration: 60000,
|
|
71
|
-
maxDays: 31,
|
|
72
|
-
gzip: false,
|
|
73
|
-
} as LogrotatorConfig,
|
|
62
|
+
declare const _default: {
|
|
63
|
+
logrotator: LogrotatorConfig;
|
|
74
64
|
};
|
|
65
|
+
declare module 'egg' {
|
|
66
|
+
interface EggAppConfig {
|
|
67
|
+
logrotator: LogrotatorConfig;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { LogrotatorConfig, _default as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/config/config.default.ts
|
|
2
|
+
var config_default_default = { logrotator: {
|
|
3
|
+
disableRotateByDay: false,
|
|
4
|
+
filesRotateByHour: null,
|
|
5
|
+
hourDelimiter: "-",
|
|
6
|
+
filesRotateBySize: null,
|
|
7
|
+
maxFileSize: 50 * 1024 * 1024,
|
|
8
|
+
maxFiles: 10,
|
|
9
|
+
rotateDuration: 6e4,
|
|
10
|
+
maxDays: 31,
|
|
11
|
+
gzip: false
|
|
12
|
+
} };
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { config_default_default as default };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LogRotator, RotateFile, RotatorOptions } from "./rotator.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/day_rotator.d.ts
|
|
4
|
+
declare class DayRotator extends LogRotator {
|
|
5
|
+
private filesRotateBySize;
|
|
6
|
+
private filesRotateByHour;
|
|
7
|
+
constructor(options: RotatorOptions);
|
|
8
|
+
getRotateFiles(): Promise<Map<string, RotateFile>>;
|
|
9
|
+
_setFile(srcPath: string, files: Map<string, RotateFile>): void;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { DayRotator };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { LogRotator } from "./rotator.js";
|
|
2
|
+
import { walkLoggerFile } from "./utils.js";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import { debuglog } from "node:util";
|
|
5
|
+
import { exists } from "utility";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import moment from "moment";
|
|
8
|
+
|
|
9
|
+
//#region src/lib/day_rotator.ts
|
|
10
|
+
const debug = debuglog("egg/logrotator/lib/day_rotator");
|
|
11
|
+
var DayRotator = class extends LogRotator {
|
|
12
|
+
filesRotateBySize;
|
|
13
|
+
filesRotateByHour;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super(options);
|
|
16
|
+
this.filesRotateBySize = this.app.config.logrotator.filesRotateBySize ?? [];
|
|
17
|
+
this.filesRotateByHour = this.app.config.logrotator.filesRotateByHour ?? [];
|
|
18
|
+
}
|
|
19
|
+
async getRotateFiles() {
|
|
20
|
+
const files = /* @__PURE__ */ new Map();
|
|
21
|
+
const logDir = this.app.config.logger.dir;
|
|
22
|
+
const loggers = this.app.loggers;
|
|
23
|
+
const loggerFiles = walkLoggerFile(loggers);
|
|
24
|
+
for (let file of loggerFiles) {
|
|
25
|
+
if (!path.isAbsolute(file)) file = path.join(logDir, file);
|
|
26
|
+
this._setFile(file, files);
|
|
27
|
+
}
|
|
28
|
+
const agentLogName = this.app.config.logger.agentLogName;
|
|
29
|
+
this._setFile(path.join(logDir, agentLogName), files);
|
|
30
|
+
const rotateLogDirs = this.app.config.logger.rotateLogDirs;
|
|
31
|
+
if (rotateLogDirs && rotateLogDirs.length > 0) {
|
|
32
|
+
this.app.deprecate("[@eggjs/logrotator] Do not use app.config.logger.rotateLogDirs, only rotate core loggers and custom loggers");
|
|
33
|
+
for (const dir of rotateLogDirs) {
|
|
34
|
+
if (!await exists(dir)) continue;
|
|
35
|
+
try {
|
|
36
|
+
const names = await fs.readdir(dir);
|
|
37
|
+
for (const name of names) {
|
|
38
|
+
if (!name.endsWith(".log")) continue;
|
|
39
|
+
this._setFile(path.join(dir, name), files);
|
|
40
|
+
}
|
|
41
|
+
} catch (err) {
|
|
42
|
+
this.logger.error(err);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return files;
|
|
47
|
+
}
|
|
48
|
+
_setFile(srcPath, files) {
|
|
49
|
+
if (this.filesRotateBySize.includes(srcPath)) return;
|
|
50
|
+
if (this.filesRotateByHour.includes(srcPath)) return;
|
|
51
|
+
if (!files.has(srcPath)) {
|
|
52
|
+
const ext = this.app.config.logrotator.gzip === true ? ".gz" : "";
|
|
53
|
+
const targetPath = srcPath + moment().subtract(23, "hours").subtract(58, "minutes").format(".YYYY-MM-DD") + ext;
|
|
54
|
+
debug("set file %s => %s", srcPath, targetPath);
|
|
55
|
+
files.set(srcPath, {
|
|
56
|
+
srcPath,
|
|
57
|
+
targetPath
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { DayRotator };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LogRotator, RotateFile } from "./rotator.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/hour_rotator.d.ts
|
|
4
|
+
declare class HourRotator extends LogRotator {
|
|
5
|
+
getRotateFiles(): Promise<Map<string, RotateFile>>;
|
|
6
|
+
get hourDelimiter(): string;
|
|
7
|
+
_setFile(srcPath: string, files: Map<string, RotateFile>): void;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { HourRotator };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LogRotator } from "./rotator.js";
|
|
2
|
+
import { debuglog } from "node:util";
|
|
3
|
+
import { exists } from "utility";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import moment from "moment";
|
|
6
|
+
|
|
7
|
+
//#region src/lib/hour_rotator.ts
|
|
8
|
+
const debug = debuglog("egg/logrotator/lib/hour_rotator");
|
|
9
|
+
var HourRotator = class extends LogRotator {
|
|
10
|
+
async getRotateFiles() {
|
|
11
|
+
const files = /* @__PURE__ */ new Map();
|
|
12
|
+
const logDir = this.app.config.logger.dir;
|
|
13
|
+
const filesRotateByHour = this.app.config.logrotator.filesRotateByHour ?? [];
|
|
14
|
+
for (let logPath of filesRotateByHour) {
|
|
15
|
+
if (!path.isAbsolute(logPath)) logPath = path.join(logDir, logPath);
|
|
16
|
+
if (!await exists(logPath)) continue;
|
|
17
|
+
this._setFile(logPath, files);
|
|
18
|
+
}
|
|
19
|
+
return files;
|
|
20
|
+
}
|
|
21
|
+
get hourDelimiter() {
|
|
22
|
+
return this.app.config.logrotator.hourDelimiter;
|
|
23
|
+
}
|
|
24
|
+
_setFile(srcPath, files) {
|
|
25
|
+
if (!files.has(srcPath)) {
|
|
26
|
+
const ext = this.app.config.logrotator.gzip === true ? ".gz" : "";
|
|
27
|
+
const targetPath = srcPath + moment().subtract(1, "hours").format(`.YYYY-MM-DD${this.hourDelimiter}HH`) + ext;
|
|
28
|
+
debug("set file %s => %s", srcPath, targetPath);
|
|
29
|
+
files.set(srcPath, {
|
|
30
|
+
srcPath,
|
|
31
|
+
targetPath
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { HourRotator };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Application } from "egg";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/rotator.d.ts
|
|
4
|
+
interface RotatorOptions {
|
|
5
|
+
app: Application;
|
|
6
|
+
}
|
|
7
|
+
interface RotateFile {
|
|
8
|
+
srcPath: string;
|
|
9
|
+
targetPath: string;
|
|
10
|
+
}
|
|
11
|
+
declare abstract class LogRotator {
|
|
12
|
+
protected readonly options: RotatorOptions;
|
|
13
|
+
protected readonly app: Application;
|
|
14
|
+
protected readonly logger: Application['coreLogger'];
|
|
15
|
+
constructor(options: RotatorOptions);
|
|
16
|
+
abstract getRotateFiles(): Promise<Map<string, RotateFile>>;
|
|
17
|
+
rotate(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { LogRotator, RotateFile, RotatorOptions };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { createReadStream, createWriteStream } from "node:fs";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import { pipeline } from "node:stream/promises";
|
|
5
|
+
import { createGzip } from "node:zlib";
|
|
6
|
+
import { debuglog } from "node:util";
|
|
7
|
+
import { exists } from "utility";
|
|
8
|
+
|
|
9
|
+
//#region src/lib/rotator.ts
|
|
10
|
+
const debug = debuglog("egg/logrotator/lib/rotator");
|
|
11
|
+
var LogRotator = class {
|
|
12
|
+
options;
|
|
13
|
+
app;
|
|
14
|
+
logger;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
assert(this.options.app, "options.app is required");
|
|
18
|
+
this.app = this.options.app;
|
|
19
|
+
this.logger = this.app.coreLogger;
|
|
20
|
+
}
|
|
21
|
+
async rotate() {
|
|
22
|
+
const files = await this.getRotateFiles();
|
|
23
|
+
assert(files instanceof Map, "getRotateFiles should return a Map");
|
|
24
|
+
const rotatedFiles = [];
|
|
25
|
+
for (const file of files.values()) try {
|
|
26
|
+
debug("rename from %s to %s", file.srcPath, file.targetPath);
|
|
27
|
+
await renameOrDelete(file.srcPath, file.targetPath, this.app.config.logrotator.gzip);
|
|
28
|
+
rotatedFiles.push(`${file.srcPath} -> ${file.targetPath}`);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
const err = e;
|
|
31
|
+
err.message = `[@eggjs/logrotator] rename ${file.srcPath}, found exception: ${err.message}`;
|
|
32
|
+
this.logger.error(err);
|
|
33
|
+
}
|
|
34
|
+
if (rotatedFiles.length > 0) {
|
|
35
|
+
debug("broadcast log-reload, rotated files: %j", rotatedFiles);
|
|
36
|
+
this.logger.info("[@eggjs/logrotator] broadcast log-reload");
|
|
37
|
+
this.app.messenger.sendToApp("log-reload");
|
|
38
|
+
this.app.messenger.sendToAgent("log-reload");
|
|
39
|
+
}
|
|
40
|
+
this.logger.info("[@eggjs/logrotator] rotate files success by %s, files %j", this.constructor.name, rotatedFiles);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
async function renameOrDelete(srcPath, targetPath, gzip) {
|
|
44
|
+
if (srcPath === targetPath) return;
|
|
45
|
+
if (!await exists(srcPath)) return;
|
|
46
|
+
if (await exists(targetPath)) throw /* @__PURE__ */ new Error(`targetFile ${targetPath} exists!!!`);
|
|
47
|
+
if (gzip === true) {
|
|
48
|
+
const tmpPath = `${targetPath}.tmp`;
|
|
49
|
+
await fs.rename(srcPath, tmpPath);
|
|
50
|
+
await pipeline(createReadStream(tmpPath), createGzip(), createWriteStream(targetPath));
|
|
51
|
+
await fs.unlink(tmpPath);
|
|
52
|
+
} else await fs.rename(srcPath, targetPath);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { LogRotator };
|