除第一天外,如何使用 Winston 每天轮换日志

Posted

技术标签:

【中文标题】除第一天外,如何使用 Winston 每天轮换日志【英文标题】:How to daily rotate logs using Winston except the first day 【发布时间】:2016-12-15 15:25:09 【问题描述】:

我需要每天轮换日志,但当天的文件除外。 我正在使用 winstonwinston-daily-rotate-file 库。

在以下示例中,仅在我第一次执行节点时生成了一个文件“info.log.2016-08-09”。

但是,我确实需要生成文件“info.log”,并且在这一天之后,应该重命名为“info.log.2016-08-09”,并为该文件创建一个新的“info.log”当前日期。 我知道这是其他应用程序中的正常行为。

var logger = new (winston.Logger)(
  transports: [
    new dailyRotateFile(  
      
        name: 'cronInfo',
        filename:  path.join(__dirname,"log", "info.log"),
      level: 'info',
       timestamp: function()                
        return utils.formatDate(new Date(), "yyyy-mm-dd'T'HH:MM:ss.l'Z'")
      ,
      formatter: function(options) 
          return  options.timestamp() +' ['+ options.level.toUpperCase() +'] '+ (undefined !== options.message ? options.message : '') +
               (options.meta && Object.keys(options.meta).length ? '\n\t'+ JSON.stringify(options.meta) : '' );          
      ,
      json:false,
      datePattern:".yyyy-MM-dd"
    )
   ]
);
 

【问题讨论】:

当应用程序启动时,您可以在time-to-change-log-name 上设置计时器。 On timer:重命名日志文件,通过Sync函数创建新的info.log以避免Winston调用,设置下一个定时器。也许,Winston 必须重新启动以更新日志文件描述符/流(我不确定它是否可能)。 github.com/winstonjs/winston-daily-rotate-file/issues/23 【参考方案1】:

一种解决方法是再传输一次到 info.log

就像这样:

var logger = new (winston.Logger)(
  transports: [
    new dailyRotateFile(  
      
        //your definition of rotate file
      ),
    new (winston.transports.File)( filename: 'info.log' )
   ]
);

然后设置一些cron在午夜删除info.log,即node-schedule

但是,这种方式可能会出现一点点不一致,如果有事情跑到半夜,它会在 info.log 中记录几行属于第二天的内容,然后将其删除,因此 info.log 可能会不完整。

但所有具有这种info.log.2016-08-09 格式的日志仍然完整且不受影响。

因此,要考虑是否可以接受一天内出现不完整 info.log 的可能性很小。 (但是您可以创建更高级的检查器,它不仅删除文件,而且查看是否存在新一天的文件,如果存在,它会查看里面的内容,然后仅从 info.log 中删除前几天的日志,并且不会删除它一下子)

【讨论】:

【参考方案2】:

另一种没有数据边界问题的方法就是使用:

var logger = new (winston.Logger)(
  transports: [
    new dailyRotateFile(  
      
        // your definition of rotate file
      )
   ]
);

然后为 info.log 创建一个链接到当天文件的符号链接。最后你可以使用:

transport.on('rotate', function(oldFilename, newFilename) 
    fs.symlinkSync(newFilename, 'info.log');
);

在旋转时更新符号链接。

如果您的日志文件特别大,这也会节省一些磁盘空间。

【讨论】:

【参考方案3】:

对于那些可能仍在寻找正确方法的人,此功能已添加到v.4.1.0。

只需使用createSymlinksymlinkName 选项:

new DailyRotateFile(
    ...
    createSymlink: true,
    symlinkName: 'info.log',
);

【讨论】:

以上是关于除第一天外,如何使用 Winston 每天轮换日志的主要内容,如果未能解决你的问题,请参考以下文章

Winston - 使用 maxsize 时记录轮换顺序

如何将 log4j 每日日志轮换与基于文件大小的轮换和最大备份相结合?

使用 logrotate 每小时轮换文件? [关闭]

什么是 Ansible 日志轮换周期?

如何更改 winston 日志格式?

如何使用winston在子目录而不是根目录中设置日志?