Search code examples
gologrus

How to re-create log file automatically in logrus/lumberjack on macOS


I use logrus and lumberjack for log file on macOS.

logger := &lumberjack.Logger{
    // Log path
    Filename: filepath.Join(logFolder, "xxx.log"),
    // Log size MB
    MaxSize: 10,
    // Backup count
    MaxBackups: 3,
    // expire days
    // MaxAge: 28,
    // gzip compress
    Compress: false,
}
logrus.SetOutput(logger)

When I start my application, It will create log file as expected.
However, when my app is running, I manually delete log file, as my app is continuing to run, I expect it will re-create log file, however, the log file is not created.
But if I restart my app, the log file will be created again.
So what should I do to make my app (keep running) to re-create and write log file when log file is deleted.

Thanks in advance.


Solution

  • Here is another way to monitor the log file using fsnotify lib. fsnotify monitors the directory where xxx.log is located, tell lumberjack to Rotate() when xxx.log deleted.

    import (
        "fmt"
        "log"
        "path/filepath"
        "time"
    
        "github.com/fsnotify/fsnotify"
        "gopkg.in/natefinch/lumberjack.v2"
    )
    
    func main() {
        logPath := "./xxx.log"
        logName := filepath.Base(logPath)
    
        logger := &lumberjack.Logger{
            // Log path
            Filename: logPath,
            // Log size MB
            MaxSize: 10,
            // Backup count
            MaxBackups: 3,
            // expire days
            // MaxAge: 28,
            // gzip compress
            Compress: false,
        }
    
        watcher, err := fsnotify.NewWatcher()
        if err != nil {
            log.Fatal(err)
        }
        defer watcher.Close()
    
        go func() {
            for event := range watcher.Events {
                if event.Op&fsnotify.Remove == fsnotify.Remove &&
                    event.Name == logName {
                    log.Println("rotate log", event.Name)
                    logger.Rotate()
                }
            }
        }()
    
        err = watcher.Add(filepath.Dir(logPath))
        if err != nil {
            log.Fatal(err)
        }
    
        for {
            logger.Write([]byte(fmt.Sprintf("current time:%v\n", time.Now())))
            time.Sleep(3 * time.Second)
        }
    }