@eggjs/logrotator 4.1.0 → 5.0.0-beta.17

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.
Files changed (125) hide show
  1. package/README.md +1 -3
  2. package/README.zh-CN.md +1 -3
  3. package/dist/agent.d.ts +2 -0
  4. package/dist/agent.js +7 -0
  5. package/dist/app/extend/agent.d.ts +8 -0
  6. package/dist/app/extend/agent.js +7 -0
  7. package/dist/app/extend/application.d.ts +8 -0
  8. package/dist/app/extend/application.js +7 -0
  9. package/dist/app/schedule/clean_log.d.ts +12 -0
  10. package/dist/app/schedule/clean_log.js +60 -0
  11. package/dist/app/schedule/rotate_by_file.d.ts +13 -0
  12. package/dist/app/schedule/rotate_by_file.js +19 -0
  13. package/dist/app/schedule/rotate_by_hour.d.ts +13 -0
  14. package/dist/app/schedule/rotate_by_hour.js +19 -0
  15. package/dist/app/schedule/rotate_by_size.d.ts +13 -0
  16. package/dist/app/schedule/rotate_by_size.js +19 -0
  17. package/dist/app.d.ts +2 -0
  18. package/dist/app.js +7 -0
  19. package/dist/boot.d.ts +10 -0
  20. package/dist/boot.js +16 -0
  21. package/{src/config/config.default.ts → dist/config/config.default.d.ts} +6 -18
  22. package/dist/config/config.default.js +15 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +5 -0
  25. package/dist/lib/day_rotator.d.ts +12 -0
  26. package/dist/lib/day_rotator.js +64 -0
  27. package/dist/lib/hour_rotator.d.ts +10 -0
  28. package/dist/lib/hour_rotator.js +38 -0
  29. package/dist/lib/rotator.d.ts +20 -0
  30. package/dist/lib/rotator.js +56 -0
  31. package/dist/lib/size_rotator.d.ts +9 -0
  32. package/dist/lib/size_rotator.js +61 -0
  33. package/dist/lib/utils.d.ts +12 -0
  34. package/dist/lib/utils.js +15 -0
  35. package/dist/types.d.ts +19 -0
  36. package/dist/types.js +1 -0
  37. package/package.json +53 -78
  38. package/dist/commonjs/agent.d.ts +0 -2
  39. package/dist/commonjs/agent.js +0 -5
  40. package/dist/commonjs/app/extend/agent.d.ts +0 -5
  41. package/dist/commonjs/app/extend/agent.js +0 -8
  42. package/dist/commonjs/app/extend/application.d.ts +0 -5
  43. package/dist/commonjs/app/extend/application.js +0 -7
  44. package/dist/commonjs/app/schedule/clean_log.d.ts +0 -9
  45. package/dist/commonjs/app/schedule/clean_log.js +0 -75
  46. package/dist/commonjs/app/schedule/rotate_by_file.d.ts +0 -10
  47. package/dist/commonjs/app/schedule/rotate_by_file.js +0 -17
  48. package/dist/commonjs/app/schedule/rotate_by_hour.d.ts +0 -10
  49. package/dist/commonjs/app/schedule/rotate_by_hour.js +0 -17
  50. package/dist/commonjs/app/schedule/rotate_by_size.d.ts +0 -10
  51. package/dist/commonjs/app/schedule/rotate_by_size.js +0 -17
  52. package/dist/commonjs/app.d.ts +0 -2
  53. package/dist/commonjs/app.js +0 -5
  54. package/dist/commonjs/boot.d.ts +0 -6
  55. package/dist/commonjs/boot.js +0 -18
  56. package/dist/commonjs/config/config.default.d.ts +0 -64
  57. package/dist/commonjs/config/config.default.js +0 -16
  58. package/dist/commonjs/index.d.ts +0 -2
  59. package/dist/commonjs/index.js +0 -19
  60. package/dist/commonjs/lib/day_rotator.d.ts +0 -8
  61. package/dist/commonjs/lib/day_rotator.js +0 -91
  62. package/dist/commonjs/lib/hour_rotator.d.ts +0 -6
  63. package/dist/commonjs/lib/hour_rotator.js +0 -50
  64. package/dist/commonjs/lib/rotator.d.ts +0 -16
  65. package/dist/commonjs/lib/rotator.js +0 -81
  66. package/dist/commonjs/lib/size_rotator.d.ts +0 -5
  67. package/dist/commonjs/lib/size_rotator.js +0 -74
  68. package/dist/commonjs/lib/utils.d.ts +0 -10
  69. package/dist/commonjs/lib/utils.js +0 -19
  70. package/dist/commonjs/package.json +0 -3
  71. package/dist/commonjs/types.d.ts +0 -11
  72. package/dist/commonjs/types.js +0 -3
  73. package/dist/esm/agent.d.ts +0 -2
  74. package/dist/esm/agent.js +0 -3
  75. package/dist/esm/app/extend/agent.d.ts +0 -5
  76. package/dist/esm/app/extend/agent.js +0 -6
  77. package/dist/esm/app/extend/application.d.ts +0 -5
  78. package/dist/esm/app/extend/application.js +0 -5
  79. package/dist/esm/app/schedule/clean_log.d.ts +0 -9
  80. package/dist/esm/app/schedule/clean_log.js +0 -70
  81. package/dist/esm/app/schedule/rotate_by_file.d.ts +0 -10
  82. package/dist/esm/app/schedule/rotate_by_file.js +0 -15
  83. package/dist/esm/app/schedule/rotate_by_hour.d.ts +0 -10
  84. package/dist/esm/app/schedule/rotate_by_hour.js +0 -15
  85. package/dist/esm/app/schedule/rotate_by_size.d.ts +0 -10
  86. package/dist/esm/app/schedule/rotate_by_size.js +0 -15
  87. package/dist/esm/app.d.ts +0 -2
  88. package/dist/esm/app.js +0 -3
  89. package/dist/esm/boot.d.ts +0 -6
  90. package/dist/esm/boot.js +0 -14
  91. package/dist/esm/config/config.default.d.ts +0 -64
  92. package/dist/esm/config/config.default.js +0 -14
  93. package/dist/esm/index.d.ts +0 -2
  94. package/dist/esm/index.js +0 -3
  95. package/dist/esm/lib/day_rotator.d.ts +0 -8
  96. package/dist/esm/lib/day_rotator.js +0 -84
  97. package/dist/esm/lib/hour_rotator.d.ts +0 -6
  98. package/dist/esm/lib/hour_rotator.js +0 -43
  99. package/dist/esm/lib/rotator.d.ts +0 -16
  100. package/dist/esm/lib/rotator.js +0 -74
  101. package/dist/esm/lib/size_rotator.d.ts +0 -5
  102. package/dist/esm/lib/size_rotator.js +0 -67
  103. package/dist/esm/lib/utils.d.ts +0 -10
  104. package/dist/esm/lib/utils.js +0 -16
  105. package/dist/esm/package.json +0 -3
  106. package/dist/esm/types.d.ts +0 -11
  107. package/dist/esm/types.js +0 -2
  108. package/dist/package.json +0 -4
  109. package/src/agent.ts +0 -3
  110. package/src/app/extend/agent.ts +0 -6
  111. package/src/app/extend/application.ts +0 -5
  112. package/src/app/schedule/clean_log.ts +0 -87
  113. package/src/app/schedule/rotate_by_file.ts +0 -18
  114. package/src/app/schedule/rotate_by_hour.ts +0 -18
  115. package/src/app/schedule/rotate_by_size.ts +0 -18
  116. package/src/app.ts +0 -3
  117. package/src/boot.ts +0 -16
  118. package/src/index.ts +0 -3
  119. package/src/lib/day_rotator.ts +0 -98
  120. package/src/lib/hour_rotator.ts +0 -52
  121. package/src/lib/rotator.ts +0 -107
  122. package/src/lib/size_rotator.ts +0 -75
  123. package/src/lib/utils.ts +0 -23
  124. package/src/types.ts +0 -15
  125. package/src/typings/index.d.ts +0 -4
@@ -1,18 +0,0 @@
1
- import type { EggCore } from '@eggjs/core';
2
- import { SizeRotator } from '../../lib/size_rotator.js';
3
-
4
- export default (app: EggCore) => {
5
- const rotator = new SizeRotator({ app });
6
-
7
- return {
8
- schedule: {
9
- type: 'worker',
10
- interval: app.config.logrotator.rotateDuration,
11
- disable: (app.config.logrotator.filesRotateBySize || []).length === 0,
12
- },
13
-
14
- async task() {
15
- await rotator.rotate();
16
- },
17
- };
18
- };
package/src/app.ts DELETED
@@ -1,3 +0,0 @@
1
- import { Boot } from './boot.js';
2
-
3
- export default Boot;
package/src/boot.ts DELETED
@@ -1,16 +0,0 @@
1
- import type { EggCore, ILifecycleBoot } from '@eggjs/core';
2
-
3
- export class Boot implements ILifecycleBoot {
4
- constructor(private readonly app: EggCore) {}
5
-
6
- async didLoad() {
7
- // reload logger to new fd after rotating
8
- this.app.messenger.on('log-reload', () => {
9
- this.app.loggers.reload();
10
- this.app.coreLogger.info(
11
- '[@eggjs/logrotator] %s logger reload: got log-reload message',
12
- this.app.type
13
- );
14
- });
15
- }
16
- }
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- import './types.js';
2
-
3
- export * from './lib/rotator.js';
@@ -1,98 +0,0 @@
1
- import path from 'node:path';
2
- import moment from 'moment';
3
- import fs from 'node:fs/promises';
4
- import { debuglog } from 'node:util';
5
-
6
- import { exists } from 'utility';
7
-
8
- import { LogRotator, type RotateFile, type RotatorOptions } from './rotator.js';
9
- import { walkLoggerFile } from './utils.js';
10
-
11
- const debug = debuglog('@eggjs/logrotator/lib/day_rotator');
12
-
13
- // rotate log by day
14
- // rename from foo.log to foo.log.YYYY-MM-DD
15
- export class DayRotator extends LogRotator {
16
- private filesRotateBySize: string[];
17
- private filesRotateByHour: string[];
18
-
19
- constructor(options: RotatorOptions) {
20
- super(options);
21
- this.filesRotateBySize = this.app.config.logrotator.filesRotateBySize || [];
22
- this.filesRotateByHour = this.app.config.logrotator.filesRotateByHour || [];
23
- }
24
-
25
- async getRotateFiles() {
26
- const files = new Map<string, RotateFile>();
27
- const logDir = this.app.config.logger.dir;
28
- const loggers = this.app.loggers;
29
- const loggerFiles = walkLoggerFile(loggers);
30
- for (let file of loggerFiles) {
31
- // support relative path
32
- if (!path.isAbsolute(file)) {
33
- file = path.join(logDir, file);
34
- }
35
- this._setFile(file, files);
36
- }
37
-
38
- // Should rotate agent log, because schedule is running under app worker,
39
- // agent log is the only difference between app worker and agent worker.
40
- // - app worker -> egg-web.log
41
- // - agent worker -> egg-agent.log
42
- const agentLogName = this.app.config.logger.agentLogName;
43
- this._setFile(path.join(logDir, agentLogName), files);
44
-
45
- // rotateLogDirs is deprecated
46
- const rotateLogDirs = this.app.config.logger.rotateLogDirs;
47
- if (rotateLogDirs && rotateLogDirs.length > 0) {
48
- this.app.deprecate(
49
- '[egg-logrotator] Do not use app.config.logger.rotateLogDirs, only rotate core loggers and custom loggers'
50
- );
51
-
52
- for (const dir of rotateLogDirs) {
53
- const stat = await exists(dir);
54
- if (!stat) continue;
55
-
56
- try {
57
- const names = await fs.readdir(dir);
58
- for (const name of names) {
59
- if (!name.endsWith('.log')) {
60
- continue;
61
- }
62
- this._setFile(path.join(dir, name), files);
63
- }
64
- } catch (err) {
65
- this.logger.error(err);
66
- }
67
- }
68
- }
69
-
70
- return files;
71
- }
72
-
73
- _setFile(srcPath: string, files: Map<string, RotateFile>) {
74
- // don't rotate logPath in filesRotateBySize
75
- if (this.filesRotateBySize.includes(srcPath)) {
76
- return;
77
- }
78
-
79
- // don't rotate logPath in filesRotateByHour
80
- if (this.filesRotateByHour.includes(srcPath)) {
81
- return;
82
- }
83
-
84
- if (!files.has(srcPath)) {
85
- const ext = this.app.config.logrotator.gzip === true ? '.gz' : '';
86
- // allow 2 minutes deviation
87
- const targetPath =
88
- srcPath +
89
- moment()
90
- .subtract(23, 'hours')
91
- .subtract(58, 'minutes')
92
- .format('.YYYY-MM-DD') +
93
- ext;
94
- debug('set file %s => %s', srcPath, targetPath);
95
- files.set(srcPath, { srcPath, targetPath });
96
- }
97
- }
98
- }
@@ -1,52 +0,0 @@
1
- import moment from 'moment';
2
- import path from 'node:path';
3
- import { debuglog } from 'node:util';
4
-
5
- import { exists } from 'utility';
6
-
7
- import { LogRotator, type RotateFile } from './rotator.js';
8
-
9
- const debug = debuglog('@eggjs/logrotator/lib/hour_rotator');
10
-
11
- // rotate log by hour
12
- // rename from foo.log to foo.log.YYYY-MM-DD-HH
13
- export class HourRotator extends LogRotator {
14
- async getRotateFiles() {
15
- const files = new Map<string, RotateFile>();
16
- const logDir = this.app.config.logger.dir;
17
- const filesRotateByHour =
18
- this.app.config.logrotator.filesRotateByHour || [];
19
-
20
- for (let logPath of filesRotateByHour) {
21
- // support relative path
22
- if (!path.isAbsolute(logPath)) {
23
- logPath = path.join(logDir, logPath);
24
- }
25
- const stat = await exists(logPath);
26
- if (!stat) {
27
- continue;
28
- }
29
- this._setFile(logPath, files);
30
- }
31
-
32
- return files;
33
- }
34
-
35
- get hourDelimiter() {
36
- return this.app.config.logrotator.hourDelimiter;
37
- }
38
-
39
- _setFile(srcPath: string, files: Map<string, RotateFile>) {
40
- if (!files.has(srcPath)) {
41
- const ext = this.app.config.logrotator.gzip === true ? '.gz' : '';
42
- const targetPath =
43
- srcPath +
44
- moment()
45
- .subtract(1, 'hours')
46
- .format(`.YYYY-MM-DD${this.hourDelimiter}HH`) +
47
- ext;
48
- debug('set file %s => %s', srcPath, targetPath);
49
- files.set(srcPath, { srcPath, targetPath });
50
- }
51
- }
52
- }
@@ -1,107 +0,0 @@
1
- import assert from 'node:assert';
2
- import { createWriteStream, createReadStream } 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
-
8
- import { exists } from 'utility';
9
- import type { EggCore } from '@eggjs/core';
10
-
11
- const debug = debuglog('@eggjs/logrotator/lib/rotator');
12
-
13
- export interface RotatorOptions {
14
- app: EggCore;
15
- }
16
-
17
- export interface RotateFile {
18
- srcPath: string;
19
- targetPath: string;
20
- }
21
-
22
- export abstract class LogRotator {
23
- protected readonly options: RotatorOptions;
24
- protected readonly app: EggCore;
25
- protected readonly logger: EggCore['coreLogger'];
26
-
27
- constructor(options: RotatorOptions) {
28
- this.options = options;
29
- assert(this.options.app, 'options.app is required');
30
- this.app = this.options.app;
31
- this.logger = this.app.coreLogger;
32
- }
33
-
34
- abstract getRotateFiles(): Promise<Map<string, RotateFile>>;
35
-
36
- async rotate() {
37
- const files = await this.getRotateFiles();
38
- assert(files instanceof Map, 'getRotateFiles should return a Map');
39
- const rotatedFiles: string[] = [];
40
- for (const file of files.values()) {
41
- try {
42
- debug('rename from %s to %s', file.srcPath, file.targetPath);
43
- await renameOrDelete(
44
- file.srcPath,
45
- file.targetPath,
46
- this.app.config.logrotator.gzip
47
- );
48
- rotatedFiles.push(`${file.srcPath} -> ${file.targetPath}`);
49
- } catch (e) {
50
- const err = e as Error;
51
- err.message =
52
- `[@eggjs/logrotator] rename ${file.srcPath}, found exception: ` +
53
- err.message;
54
- this.logger.error(err);
55
- }
56
- }
57
-
58
- if (rotatedFiles.length > 0) {
59
- // tell every one to reload logger
60
- this.logger.info('[@eggjs/logrotator] broadcast log-reload');
61
- this.app.messenger.sendToApp('log-reload');
62
- this.app.messenger.sendToAgent('log-reload');
63
- }
64
-
65
- this.logger.info(
66
- '[@eggjs/logrotator] rotate files success by %s, files %j',
67
- this.constructor.name,
68
- rotatedFiles
69
- );
70
- }
71
- }
72
-
73
- // rename from srcPath to targetPath, for example foo.log.1 > foo.log.2
74
- // if gzip is true, then use gzip to compress the file, and delete the src file, for example foo.log.1 -> foo.log.2.gz
75
- async function renameOrDelete(
76
- srcPath: string,
77
- targetPath: string,
78
- gzip: boolean
79
- ) {
80
- if (srcPath === targetPath) {
81
- return;
82
- }
83
- const srcExists = await exists(srcPath);
84
- if (!srcExists) {
85
- return;
86
- }
87
- const targetExists = await exists(targetPath);
88
- // if target file exists, then throw
89
- // because the target file always be renamed first.
90
- if (targetExists) {
91
- const err = new Error(`targetFile ${targetPath} exists!!!`);
92
- throw err;
93
- }
94
- // if gzip is true, then use gzip
95
- if (gzip === true) {
96
- const tmpPath = `${targetPath}.tmp`;
97
- await fs.rename(srcPath, tmpPath);
98
- await pipeline(
99
- createReadStream(tmpPath),
100
- createGzip(),
101
- createWriteStream(targetPath)
102
- );
103
- await fs.unlink(tmpPath);
104
- } else {
105
- await fs.rename(srcPath, targetPath);
106
- }
107
- }
@@ -1,75 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import { debuglog } from 'node:util';
4
-
5
- import { exists } from 'utility';
6
-
7
- import { LogRotator, type RotateFile } from './rotator.js';
8
-
9
- const debug = debuglog('@eggjs/logrotator/lib/size_rotator');
10
-
11
- // rotate log by size, if the size of file over maxFileSize,
12
- // it will rename from foo.log to foo.log.1
13
- // if foo.log.1 exists, foo.log.1 will rename to foo.log.2
14
- export class SizeRotator extends LogRotator {
15
- async getRotateFiles() {
16
- const files = new Map<string, RotateFile>();
17
- const logDir = this.app.config.logger.dir;
18
- const filesRotateBySize =
19
- this.app.config.logrotator.filesRotateBySize || [];
20
- const maxFileSize = this.app.config.logrotator.maxFileSize;
21
- const maxFiles = this.app.config.logrotator.maxFiles;
22
- for (let logPath of filesRotateBySize) {
23
- // support relative path
24
- if (!path.isAbsolute(logPath)) {
25
- logPath = path.join(logDir, logPath);
26
- }
27
- const stat = await exists(logPath);
28
- if (!stat) {
29
- continue;
30
- }
31
- const size = stat.size;
32
- try {
33
- if (size >= maxFileSize) {
34
- this.logger.info(
35
- `[@eggjs/logrotator] file ${logPath} reach the maximum file size, current size: ${size}, max size: ${maxFileSize}`
36
- );
37
- // delete max log file if exists, otherwise will throw when rename
38
- const maxFileName = `${logPath}.${maxFiles}`;
39
- const stat = await exists(maxFileName);
40
- if (stat) {
41
- await fs.unlink(maxFileName);
42
- this.logger.info(
43
- `[@eggjs/logrotator] delete max log file ${maxFileName}`
44
- );
45
- }
46
- this._setFile(logPath, files);
47
- }
48
- } catch (e) {
49
- const err = e as Error;
50
- err.message = '[@eggjs/logrotator] ' + err.message;
51
- this.logger.error(err);
52
- }
53
- }
54
- return files;
55
- }
56
-
57
- _setFile(logPath: string, files: Map<string, RotateFile>) {
58
- const maxFiles = this.app.config.logrotator.maxFiles;
59
- if (files.has(logPath)) {
60
- return;
61
- }
62
- const ext = this.app.config.logrotator.gzip === true ? '.gz' : '';
63
- // foo.log.2 -> foo.log.3
64
- // foo.log.1 -> foo.log.2
65
- for (let i = maxFiles - 1; i >= 1; i--) {
66
- const srcPath = `${logPath}.${i}`;
67
- const targetPath = `${logPath}.${i + 1}${ext}`;
68
- debug('set file %s => %s', srcPath, targetPath);
69
- files.set(srcPath, { srcPath, targetPath });
70
- }
71
- // foo.log -> foo.log.1
72
- debug('set file %s => %s', logPath, `${logPath}.1`);
73
- files.set(logPath, { srcPath: logPath, targetPath: `${logPath}.1${ext}` });
74
- }
75
- }
package/src/lib/utils.ts DELETED
@@ -1,23 +0,0 @@
1
- interface LoggerTransport {
2
- options: {
3
- file: string;
4
- };
5
- }
6
-
7
- /**
8
- * Walk all logger files from loggers
9
- */
10
- export function walkLoggerFile(
11
- loggers: Record<string, Map<string, LoggerTransport>>
12
- ) {
13
- const files: string[] = [];
14
- for (const registeredLogger of Object.values(loggers)) {
15
- for (const transport of registeredLogger.values()) {
16
- const file = transport.options.file;
17
- if (file) {
18
- files.push(file);
19
- }
20
- }
21
- }
22
- return files;
23
- }
package/src/types.ts DELETED
@@ -1,15 +0,0 @@
1
- import type { LogrotatorConfig } from './config/config.default.js';
2
- import type { LogRotator } from './lib/rotator.js';
3
-
4
- export type { LogrotatorConfig };
5
-
6
- declare module '@eggjs/core' {
7
- // add EggAppConfig overrides types
8
- interface EggAppConfig {
9
- logrotator: LogrotatorConfig;
10
- }
11
-
12
- interface EggCore {
13
- LogRotator: typeof LogRotator;
14
- }
15
- }
@@ -1,4 +0,0 @@
1
- // make sure to import egg typings and let typescript know about it
2
- // @see https://github.com/whxaxes/blog/issues/11
3
- // and https://www.typescriptlang.org/docs/handbook/declaration-merging.html
4
- import 'egg';