在 Node.js 应用程序中,实现日志轮转(log rotation)可以通过使用第三方库或自定义代码来完成。以下是两种常见的方法:
winston
和 winston-daily-rotate-file
winston
是一个流行的日志库,而 winston-daily-rotate-file
是一个用于实现日志轮转的传输模块。
安装依赖:
npm install winston winston-daily-rotate-file
配置 winston
:
const winston = require('winston');
const { createLogger, format, transports } = winston;
const DailyRotateFile = require('winston-daily-rotate-file');
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
format.errors({ stack: true }),
format.splat(),
format.json()
),
transports: [
new DailyRotateFile({
filename: 'application-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d'
})
]
});
logger.info('Hello, world!');
在这个配置中:
filename
指定了日志文件的基本名称和日期格式。datePattern
指定了日期格式,用于生成日志文件的名称。zippedArchive
表示是否将旧的日志文件压缩。maxSize
指定了单个日志文件的最大大小。maxFiles
指定了保留的日志文件数量。如果你不想使用第三方库,可以自己实现一个简单的日志轮转功能。以下是一个基本的示例:
const fs = require('fs');
const path = require('path');
const { createWriteStream } = require('fs');
const { format, createLogger, transports } = require('winston');
class RotatingFileTransport extends transports.Transport {
constructor(opts) {
super(opts);
this.opts = opts;
this.stream = null;
this.rotate();
}
log(info, callback) {
if (!this.stream) {
this.stream = createWriteStream(this.opts.filename, { flags: 'a' });
}
this.stream.write(format.info(info) + '\n');
callback();
}
rotate() {
const now = new Date();
const date = now.toISOString().split('T')[0];
const newFilename = path.join(this.opts.dirname, `${this.opts.filename}-${date}.log`);
if (fs.existsSync(newFilename)) {
fs.unlinkSync(newFilename);
}
fs.renameSync(this.opts.filename, newFilename);
this.stream.end();
this.stream = createWriteStream(this.opts.filename, { flags: 'a' });
}
close(callback) {
if (this.stream) {
this.stream.end();
}
callback();
}
}
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
format.errors({ stack: true }),
format.splat(),
format.json()
),
transports: [
new RotatingFileTransport({
filename: 'application.log',
dirname: './logs'
})
]
});
logger.info('Hello, world!');
在这个示例中,我们创建了一个自定义的 RotatingFileTransport
类,它会在每次写入日志时检查文件大小,并在需要时进行轮转。
使用 winston
和 winston-daily-rotate-file
是实现日志轮转的推荐方法,因为它提供了丰富的配置选项和良好的稳定性。如果你需要更复杂的逻辑或特定的需求,可以考虑自定义日志轮转功能。