Log Rotation in Node.js?
Asked Answered
B

4

21

In my web analytics, I am logging the data in plain text file. I want to rotate the log on a daily basis because its logging too much data. Currently I am using bunyan to rotate the logs.

Problem I am facing

It is rotating the file correctly, but rotated log file are in the name log.0, log.1, etc. I want the file name to be log.05-08-2013, log.04-08-2013

I can't edit the source of the bunyanpackage because we are installing the modules using package.json via NPM.

So my question is - Is there any other log rotation in Node.js that meets my requirement?

Bentlee answered 5/8, 2013 at 10:29 Comment(3)
I don't think so, maybe winston can do this?Lovel
@Lovel thanks . If dont mind help me to configure the winstonBentlee
Sorry, I don't have experience with winston. I just know it's a very good and popular log lib, nothing else...Lovel
S
49

Winston does support log rotation using a date in the file name. Take a look at this pull request which adds the feature and was merged four months ago. Unfortunately the documentation isn't listed on the site, but there is another pull request pending to fix that. Based on that documentation, and the tests for the log rotation features, you should be able to just add it as a new Transport to enable the log rotation functionality. Something like the following:

winston.add(winston.transports.DailyRotateFile, {
  filename: './logs/my.log',
  datePattern: '.dd-MM-yyyy'
});
Swee answered 8/8, 2013 at 8:4 Comment(3)
Nice! That's what the OP is looking for.Fun
This transport has been moved to it's own npm module now: github.com/winstonjs/winston-daily-rotate-fileGentry
Log rotation isn't working right now, there is a bug github.com/winstonjs/winston/issues/477Haines
F
5

If you also want to add logrotate (e.g. remove logs that are older than a week) in addition to saving logs by date, you can add the following code:

var fs = require('fs');
var path = require("path");
var CronJob = require('cron').CronJob;
var _ = require("lodash");
var logger = require("./logger");

var job = new CronJob('00 00 00 * *', function(){
    // Runs every day
    // at 00:00:00 AM.
    fs.readdir(path.join("/var", "log", "ironbeast"), function(err, files){
        if(err){
            logger.error("error reading log files");
        } else{
            var currentTime = new Date();
            var weekFromNow = currentTime -
                (new Date().getTime() - (7 * 24 * 60 * 60 * 1000));
            _(files).forEach(function(file){
                var fileDate = file.split(".")[2]; // get the date from the file name
                if(fileDate){
                    fileDate = fileDate.replace(/-/g,"/");
                    var fileTime = new Date(fileDate);
                    if((currentTime - fileTime) > weekFromNow){
                        console.log("delete fIle",file);
                        fs.unlink(path.join("/var", "log", "ironbeast", file),
                            function (err) {
                                if (err) {
                                    logger.error(err);
                                }
                                logger.info("deleted log file: " + file);
                            });
                    }
                }
            });
        }
    });
}, function () {
    // This function is executed when the job stops
    console.log("finished logrotate");
},
true, /* Start the job right now */
'Asia/Jerusalem' /* Time zone of this job. */
);

where my logger file is:

var path = require("path");
var winston = require('winston');

var logger = new winston.Logger({
transports: [
    new winston.transports.DailyRotateFile({
        name: 'file#info',
        level: 'info',
        filename: path.join("/var", "log", "MY-APP-LOGS", "main.log"),
        datePattern: '.MM--dd-yyyy'
    }),
    new winston.transports.DailyRotateFile({
        name: 'file#error',
        level: 'error',
        filename: path.join("/var", "log", "MY-APP-LOGS", "error.log"),
        datePattern: '.MM--dd-yyyy',
        handleExceptions: true
    })
]});

module.exports = logger;
Freesia answered 18/5, 2014 at 10:47 Comment(2)
Downvoted since you have 9 level deep nesting in the code. This should not spread! ))Blastosphere
@ArturAleksanyan it's readable though. Not saying it can't be written better, but no need to downvote someone for trying to help, with an easily readable answer, from the answer you can understand what he's doing and why he's doing it.Stereophotography
W
5

There's the logrotator module for log rotation that you can use regardless of the logging mechanism.

You can specify the format option to format the date format (or any other format for that matter)

var logrotate = require('logrotator');

// use the global rotator
var rotator = logrotate.rotator;

// or create a new instance
// var rotator = logrotate.create();

// check file rotation every 5 minutes, and rotate the file if its size exceeds 10 mb.
// keep only 3 rotated files and compress (gzip) them.
rotator.register('/var/log/myfile.log', {
  schedule: '5m', 
  size: '10m', 
  compress: true, 
  count: 3, 
  format: function(index) {
    var d = new Date();
    return d.getDate()+"-"+d.getMonth()+"-"+d.getFullYear();
  }
});
Wilkie answered 21/5, 2016 at 10:30 Comment(2)
Seems count option is not working. it keeps more than 3 rotated file.Interchangeable
Seems github repo deleted. You could use github.com/almas/logrotatorChamkis
O
-1

mongodb

winston itself does not support log rotation. My bad.

mongodb has a log rotation use case. Then you can export the logs to file names per your requirement.

winston also has a mongodb transport but I don't think it supports log rotation out of the box judging from its API.

This may be an overkill though.

forking bunyan

You can fork bunyan and add your repo's url in package.json.

This is the easiest solution if you're fine with freezing bunyan's feature or maintaining your own code.

As it is an open source project, you can even add your feature to it and submit a pull request to help improve bunyan.

Ouphe answered 6/8, 2013 at 5:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.