How to daily rotate logs using Winston except the

2019-06-15 13:45发布

问题:

I need to rotate the logs daily except the file for current day. I'm using winston and winston-daily-rotate-file libraries.

In the following example, a file "info.log.2016-08-09" is generated just the first time I execute node.

But, I really need to generate the file "info.log", and after this day, should be renamed to "info.log.2016-08-09", and create a new "info.log" for the current day. I understant that this is the normal behaviour in other applications.

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"
    })
   ]
});
 

回答1:

Another approach without data boundary issues would be just to use:

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

And then create a symlink for info.log that links to the current day's file. Finally you can use:

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

to update the symlink when it rotates.

If your log files are particularly large this will save some disk space as well.



回答2:

Well one workaround can be to have one more transport to info.log

Just like this :

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

And then set up some cron to delete info.log at midnight, i.e. node-schedule

However, with this approach there can be little inconsistency, if something is run through midnight, it can log few lines into info.log which belongs to next day and then it is deleted, therefore info.log can be incompleted.

But all the logs with this info.log.2016-08-09 format remains full and unaffected.

So it is to consider if very small chance to have incomplete info.log for one day is acceptable. (however you can create more advanced checker that does not just delete file, but looks if exist file of new day and if so, it looks whats inside and then delete only the logs from previous days from info.log and it does not delete it all at once)