Golang でのログローテション

前に試して、メモするの忘れてた。


Golang のロギングライブラリで、logrus を使ってるけど、これにはローテート機能が無い。
README には logrotate(8) でやれやとあるけど、ポータビリティに欠けるので、Golang にやらせたい。


lumberjack を使えばいけそうだけど、上手い事行かなかったので、@lestrrat さんの go-file-rotatelogs を使った。
GitHub - lestrrat/go-file-rotatelogs: [MOVED] See github.com/lestrrat-go/file-rotatelogs

func setupLogger(logLevel string) *logrus.Logger {
    level, err := logrus.ParseLevel(logLevel)
    if err != nil {
        log.Fatalf("Log level error %v", err)
    }

    path, err := filepath.Abs("logs/app.log.%Y%m%d")
    if err != nil {
        log.Fatalf("Log level error %v", err)
    }
    rl := rotatelogs.NewRotateLogs(path)

    rl.LinkName = "logs/app.log"
    rl.RotationTime = 3600 * time.Second
    rl.Offset = (9 * 60 * 60) * time.Second // Time zone `9 * 60 * 60` is Asia/Tokyo.

    out := io.MultiWriter(os.Stdout, rl)
    logger := logrus.Logger{
        Formatter: &logrus.JSONFormatter{},
        Level:     level,
        Out:       out,
    }
    logger.Info("Setup log finished.")

    return &logger
}

こんな感じで書く。
最初 `rl.Offset` が良くわかんなかったので、元ネタの Perl5 のドキュメントを読んで何を設定すれば良いのか分かった。


@lestrrat さん製のライブラリなので安心して使える。
便利!