debian

Node.js日志轮转如何实现

小樊
47
2025-07-03 10:55:57
栏目: 编程语言

在 Node.js 应用程序中,实现日志轮转(log rotation)可以通过使用第三方库或自定义代码来完成。以下是两种常见的方法:

方法一:使用 winstonwinston-daily-rotate-file

winston 是一个流行的日志库,而 winston-daily-rotate-file 是一个用于实现日志轮转的传输模块。

  1. 安装依赖

    npm install winston winston-daily-rotate-file
    
  2. 配置 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 类,它会在每次写入日志时检查文件大小,并在需要时进行轮转。

总结

使用 winstonwinston-daily-rotate-file 是实现日志轮转的推荐方法,因为它提供了丰富的配置选项和良好的稳定性。如果你需要更复杂的逻辑或特定的需求,可以考虑自定义日志轮转功能。

0
看了该问题的人还看了