Skip to content

gookit/rotatefile

Repository files navigation

Rotate File

GoDoc Go Report Card Unit-Tests GitHub tag

rotatefile is a lightweight Go library for log file rotation, cleanup and gzip compression.

中文说明 | English

rotatefile.Writer is a plain io.Writer, so it drops into the standard library log/slog, the standard log, zap, gookit/slog — any logger that writes to an io.Writer. The Go standard library has no built-in log rotation; this fills that gap.

🪄 rotatefile is a package split from gookit/slog.

Features

  • Rotate by size and/or time (every hour / day / 30min / minute …)
  • Two rotate modes: rename (write to one file, rename on rotate) and create (write to a new dated file each period)
  • Cleanup old files by BackupNum (max count) and/or BackupTime (max age)
  • Compress rotated files with gzip
  • Customizable: filename for size-rotation, time clock, file permission
  • FilesClear — a standalone old-files cleaner, usable for any program's logs (even non-Go ones, e.g. PHP-FPM)
  • filecleaner CLI — a JSON-configured command-line cleaner built on FilesClear
  • Sub-package bufwrite — buffered writers, incl. LineWriter that keeps every write (one log line) intact
  • Tiny dependency surface: only github.com/gookit/goutil

Install

go get github.com/gookit/rotatefile

Quick Start

Create a rotating writer

package main

import "github.com/gookit/rotatefile"

func main() {
	w, err := rotatefile.NewConfig("testdata/app.log").Create()
	if err != nil {
		panic(err)
	}
	defer w.Close() // flush + close

	_, _ = w.Write([]byte("a log message\n"))
}

Common config options

w, err := rotatefile.NewConfig("testdata/app.log", func(c *rotatefile.Config) {
	c.MaxSize = 100 * rotatefile.OneMByte // rotate at 100MB (0 = disable size rotate)
	c.RotateTime = rotatefile.EveryDay    // also rotate daily (0 = disable time rotate)
	c.RotateMode = rotatefile.ModeRename  // or rotatefile.ModeCreate
	c.BackupNum = 30                      // keep at most 30 old files
	c.BackupTime = 24 * 7                 // and/or keep files up to a week (hours)
	c.Compress = true                     // gzip rotated files
}).Create()

See Config on GoDoc for the full list.

Use with the standard log/slog (Go 1.21+)

import (
	"log/slog"

	"github.com/gookit/rotatefile"
)

w, _ := rotatefile.NewConfig("testdata/app.log", func(c *rotatefile.Config) {
	c.MaxSize = 50 * rotatefile.OneMByte
	c.RotateTime = rotatefile.EveryDay
	c.BackupNum = 7
}).Create()

logger := slog.New(slog.NewJSONHandler(w, nil))
logger.Info("log via std slog", "key", "value")

Use with the standard log (or zap, etc.)

import (
	"log"

	"github.com/gookit/rotatefile"
)

w, _ := rotatefile.NewConfig("testdata/app.log").Create()
log.SetOutput(w)
log.Println("log message")

Any logger that accepts an io.Writer works the same way (e.g. zap via zapcore.AddSync(w)).

Buffered writing (bufwrite)

import (
	"github.com/gookit/rotatefile"
	"github.com/gookit/rotatefile/bufwrite"
)

w, _ := rotatefile.NewConfig("testdata/app.log").Create()

// LineWriter keeps each Write (one log line) intact - it won't split a record
// across a flush, so an external collector never reads a half-written line.
bw := bufwrite.NewLineWriter(w)
defer bw.Close() // flush + close

_, _ = bw.Write([]byte("a complete log line\n"))

Clean old files (FilesClear)

FilesClear cleans old/expired files by pattern, independent of the rotating writer. It can also run as a background daemon.

fc := rotatefile.NewFilesClear(func(c *rotatefile.CConfig) {
	c.AddPattern("/path/to/some*.log")
	c.BackupNum = 2
	c.BackupTime = 12 // 12 hours
})

// one-off clean
_ = fc.Clean()

// or run on a daemon
go fc.DaemonClean(nil)
// NOTE: stop the daemon before exit
// fc.StopDaemon()

See CConfig on GoDoc for clean options.

filecleaner CLI

cmd/filecleaner is a small command-line tool built on FilesClear. It cleans old/expired files by patterns, configured via a JSON file — handy for cron jobs or cleaning logs of non-Go programs.

go install github.com/gookit/rotatefile/cmd/filecleaner@latest

filecleaner -c filecleaner.json            # one-off clean
filecleaner --dry-run -c filecleaner.json  # print what would be removed, delete nothing
filecleaner --daemon  -c filecleaner.json  # run periodically until Ctrl+C

Config file — a jobs array, one retention policy per job:

{
  "jobs": [
    { "patterns": ["/var/log/app/*.log.*"], "backup_num": 20, "backup_time": 168, "time_unit": "1h" },
    { "patterns": ["/var/log/svc"], "recursive": true, "remove_empty_dir": true, "backup_time": 7, "time_unit": "24h" }
  ]
}

See cmd/filecleaner/README.md for all options.

Related

License

MIT

About

rotatefile - provides simple file rotation, compression and cleanup, can be used with any logging library. 是一个轻量的 Go 库,提供日志文件轮转(切割)、清理与 gzip 压缩,可以用于任何日志库。

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors