rotatefile

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2025 License: MIT Imports: 19 Imported by: 16

README

Rotate File

rotatefile provides simple file rotation, compression and cleanup.

Features

  • Rotate file by size and time
    • Custom filename for rotate file by size
    • Custom time clock for rotate
    • Custom file perm for create log file
    • Custom rotate mode: create, rename
  • Compress rotated file
  • Cleanup old files

Install

go get github.com/gookit/slog/rotatefile

Usage

Create a file writer
logFile := "testdata/go_logger.log"
writer, err := rotatefile.NewConfig(logFile).Create()
if err != nil {
    panic(err)
}

// use writer
writer.Write([]byte("log message\n"))
Use on another logger
package main

import (
  "log"

  "github.com/gookit/slog/rotatefile"
)

func main() {
	logFile := "testdata/go_logger.log"
	writer, err := rotatefile.NewConfig(logFile).Create()
	if err != nil {
		panic(err) 
	}

	log.SetOutput(writer)
	log.Println("log message")
}
Available config options
// Config struct for rotate dispatcher
type Config struct {
    // Filepath the log file path, will be rotating
    Filepath string `json:"filepath" yaml:"filepath"`
    
    // FilePerm for create log file. default DefaultFilePerm
    FilePerm os.FileMode `json:"file_perm" yaml:"file_perm"`
    
    // MaxSize file contents max size, unit is bytes.
    // If is equals zero, disable rotate file by size
    //
    // default see DefaultMaxSize
    MaxSize uint64 `json:"max_size" yaml:"max_size"`
    
    // RotateTime the file rotate interval time, unit is seconds.
    // If is equals zero, disable rotate file by time
    //
    // default see EveryHour
    RotateTime RotateTime `json:"rotate_time" yaml:"rotate_time"`
    
    // CloseLock use sync lock on write contents, rotating file.
    //
    // default: false
    CloseLock bool `json:"close_lock" yaml:"close_lock"`
    
    // BackupNum max number for keep old files.
    //
    // 0 is not limit, default is DefaultBackNum
    BackupNum uint `json:"backup_num" yaml:"backup_num"`
    
    // BackupTime max time for keep old files, unit is hours.
    //
    // 0 is not limit, default is DefaultBackTime
    BackupTime uint `json:"backup_time" yaml:"backup_time"`
    
    // Compress determines if the rotated log files should be compressed using gzip.
    // The default is not to perform compression.
    Compress bool `json:"compress" yaml:"compress"`
    
    // RenameFunc you can custom-build filename for rotate file by size.
    //
    // default see DefaultFilenameFn
    RenameFunc func(filePath string, rotateNum uint) string
    
    // TimeClock for rotate
    TimeClock Clocker
}

Files clear

	fc := rotatefile.NewFilesClear(func(c *rotatefile.CConfig) {
		c.AddPattern("/path/to/some*.log")
		c.BackupNum = 2
		c.BackupTime = 12 // 12 hours
	})
	
	// clear files on daemon
	go fc.DaemonClean(nil)
	
	// NOTE: stop daemon before exit
	// fc.QuitDaemon()
Configs

// CConfig struct for clean files
type CConfig struct {
	// BackupNum max number for keep old files.
	// 0 is not limit, default is 20.
	BackupNum uint `json:"backup_num" yaml:"backup_num"`

	// BackupTime max time for keep old files, unit is TimeUnit.
	//
	// 0 is not limit, default is a week.
	BackupTime uint `json:"backup_time" yaml:"backup_time"`

	// Compress determines if the rotated log files should be compressed using gzip.
	// The default is not to perform compression.
	Compress bool `json:"compress" yaml:"compress"`

	// Patterns dir path with filename match patterns.
	//
	// eg: ["/tmp/error.log.*", "/path/to/info.log.*", "/path/to/dir/*"]
	Patterns []string `json:"patterns" yaml:"patterns"`

	// TimeClock for clean files
	TimeClock Clocker

	// TimeUnit for BackupTime. default is hours: time.Hour
	TimeUnit time.Duration `json:"time_unit" yaml:"time_unit"`

	// CheckInterval for clean files on daemon run. default is 60s.
	CheckInterval time.Duration `json:"check_interval" yaml:"check_interval"`

	// IgnoreError ignore remove error
	// TODO IgnoreError bool

	// RotateMode for rotate split files TODO
	//  - copy+cut: copy contents then truncate file
	//	- rename : rename file(use for like PHP-FPM app)
	// RotateMode RotateMode `json:"rotate_mode" yaml:"rotate_mode"`
}

Documentation

Overview

Package rotatefile provides simple file rotation, compression and cleanup.

Index

Examples

Constants

View Source
const (
	// OneMByte size
	OneMByte uint64 = 1024 * 1024

	// DefaultMaxSize of a log file. default is 20M.
	DefaultMaxSize = 20 * OneMByte
	// DefaultBackNum default backup numbers for old files.
	DefaultBackNum uint = 20
	// DefaultBackTime default backup time for old files. default keeps a week.
	DefaultBackTime uint = 24 * 7
)

Variables

View Source
var (
	// DefaultFilePerm perm and flags for create log file
	DefaultFilePerm os.FileMode = 0664
	// DefaultFileFlags for open log file
	DefaultFileFlags = os.O_CREATE | os.O_WRONLY | os.O_APPEND

	// DefaultTimeClockFn for create time
	DefaultTimeClockFn = ClockFn(func() time.Time {
		return time.Now()
	})
)

Functions

func WithCompress added in v0.5.8

func WithCompress(c *Config)

WithCompress setting for compress

func WithDebugMode added in v0.5.6

func WithDebugMode(c *Config)

WithDebugMode setting for debug mode

Types

type CConfig added in v0.3.2

type CConfig struct {
	// BackupNum max number for keep old files.
	//
	// 0 is not limit, default is 20.
	BackupNum uint `json:"backup_num" yaml:"backup_num"`

	// BackupTime max time for keep old files, unit is TimeUnit.
	//
	// 0 is not limit, default is a week.
	BackupTime uint `json:"backup_time" yaml:"backup_time"`

	// Compress determines if the rotated log files should be compressed using gzip.
	// The default is not to perform compression.
	Compress bool `json:"compress" yaml:"compress"`

	// Patterns dir path with filename match patterns.
	//
	// eg: ["/tmp/error.log.*", "/path/to/info.log.*", "/path/to/dir/*"]
	Patterns []string `json:"patterns" yaml:"patterns"`

	// TimeClock for clean files
	TimeClock Clocker

	// TimeUnit for BackupTime. default is hours: time.Hour
	TimeUnit time.Duration `json:"time_unit" yaml:"time_unit"`

	// CheckInterval for clean files on daemon run. default is 60s.
	CheckInterval time.Duration `json:"check_interval" yaml:"check_interval"`
}

CConfig struct for clean files

func NewCConfig added in v0.3.3

func NewCConfig() *CConfig

NewCConfig instance

func (*CConfig) AddDirPath added in v0.5.3

func (c *CConfig) AddDirPath(dirPaths ...string) *CConfig

AddDirPath for clean, will auto append * for match all files

func (*CConfig) AddPattern added in v0.5.3

func (c *CConfig) AddPattern(patterns ...string) *CConfig

AddPattern for clean. eg: "/tmp/error.log.*"

func (*CConfig) WithConfigFn added in v0.5.3

func (c *CConfig) WithConfigFn(fns ...CConfigFunc) *CConfig

WithConfigFn for custom settings

type CConfigFunc added in v0.5.3

type CConfigFunc func(c *CConfig)

CConfigFunc for clean config

type ClockFn

type ClockFn func() time.Time

ClockFn func

func (ClockFn) Now

func (fn ClockFn) Now() time.Time

Now implements the Clocker

type Clocker

type Clocker interface {
	Now() time.Time
}

Clocker is the interface used for determine the current time

type Config

type Config struct {
	// Filepath the log file path, will be rotating. eg: "logs/error.log"
	Filepath string `json:"filepath" yaml:"filepath"`

	// FilePerm for create log file. default DefaultFilePerm
	FilePerm os.FileMode `json:"file_perm" yaml:"file_perm"`

	// RotateMode for rotate file. default ModeRename
	RotateMode RotateMode `json:"rotate_mode" yaml:"rotate_mode"`

	// MaxSize file contents max size, unit is bytes.
	// If is equals zero, disable rotate file by size
	//
	// default see DefaultMaxSize
	MaxSize uint64 `json:"max_size" yaml:"max_size"`

	// RotateTime the file rotating interval time, unit is seconds.
	// If is equals zero, disable rotate file by time
	//
	// default: EveryHour
	RotateTime RotateTime `json:"rotate_time" yaml:"rotate_time"`

	// CloseLock use sync lock on writing contents, rotating file.
	//
	// default: false
	CloseLock bool `json:"close_lock" yaml:"close_lock"`

	// BackupNum max number for keep old files.
	//
	// 0 is not limit, default is DefaultBackNum
	BackupNum uint `json:"backup_num" yaml:"backup_num"`

	// BackupTime max time for keep old files, unit is hours.
	//
	// 0 is not limit, default is DefaultBackTime
	BackupTime uint `json:"backup_time" yaml:"backup_time"`

	// CleanOnClose determines if the rotated log files should be cleaned up when close.
	CleanOnClose bool `json:"clean_on_close" yaml:"clean_on_close"`

	// Compress determines if the rotated log files should be compressed using gzip.
	// The default is not to perform compression.
	Compress bool `json:"compress" yaml:"compress"`

	// RenameFunc you can custom-build filename for rotate file by size.
	//
	// Example:
	//
	//  c.RenameFunc = func(filepath string, rotateNum uint) string {
	// 		suffix := time.Now().Format("06010215")
	//
	// 		// eg: /tmp/error.log => /tmp/error.log.24032116_894136
	// 		return filepath + fmt.Sprintf(".%s_%d", suffix, rotateNum)
	//  }
	RenameFunc func(filePath string, rotateNum uint) string `json:"-" yaml:"-"`

	// TimeClock for a rotating file by time.
	TimeClock Clocker `json:"-" yaml:"-"`

	// DebugMode for debug on development.
	DebugMode bool `json:"debug_mode" yaml:"debug_mode"`
}

Config struct for rotate dispatcher

func EmptyConfigWith

func EmptyConfigWith(fns ...ConfigFn) *Config

EmptyConfigWith new empty config with custom func

func NewConfig

func NewConfig(filePath string, fns ...ConfigFn) *Config

NewConfig by file path, and can with custom setting

func NewConfigWith

func NewConfigWith(fns ...ConfigFn) *Config

NewConfigWith custom func

func NewDefaultConfig

func NewDefaultConfig() *Config

NewDefaultConfig instance

func (*Config) Create

func (c *Config) Create() (*Writer, error)

Create new Writer by config

func (*Config) IsMode added in v0.5.2

func (c *Config) IsMode(m RotateMode) bool

IsMode check rotate mode

func (*Config) With

func (c *Config) With(fns ...ConfigFn) *Config

With more config setting func

type ConfigFn

type ConfigFn func(c *Config)

ConfigFn for setting config

func WithBackupNum added in v0.5.8

func WithBackupNum(num uint) ConfigFn

WithBackupNum setting for backup number

func WithFilepath

func WithFilepath(logfile string) ConfigFn

WithFilepath setting

type FilesClear added in v0.3.2

type FilesClear struct {
	// contains filtered or unexported fields
}

FilesClear multi files by time.

use for rotate and clear other program produce log files

func NewFilesClear added in v0.3.3

func NewFilesClear(fns ...CConfigFunc) *FilesClear

NewFilesClear instance

func (*FilesClear) Clean added in v0.3.2

func (r *FilesClear) Clean() error

Clean old files by config

func (*FilesClear) Config added in v0.5.3

func (r *FilesClear) Config() *CConfig

Config get

func (*FilesClear) DaemonClean added in v0.3.2

func (r *FilesClear) DaemonClean(onStop func())

DaemonClean daemon clean old files by config

NOTE: this method will block current goroutine

Usage:

fc := rotatefile.NewFilesClear(nil)
fc.WithConfigFn(func(c *rotatefile.CConfig) {
	c.AddDirPath("./testdata")
})

wg := sync.WaitGroup{}
wg.Add(1)

// start daemon
go fc.DaemonClean(func() {
	wg.Done()
})

// wait for stop
wg.Wait()

func (*FilesClear) StopDaemon added in v0.5.3

func (r *FilesClear) StopDaemon()

StopDaemon for stop daemon clean

func (*FilesClear) WithConfig added in v0.5.3

func (r *FilesClear) WithConfig(cfg *CConfig) *FilesClear

WithConfig for custom set config

func (*FilesClear) WithConfigFn added in v0.3.3

func (r *FilesClear) WithConfigFn(fns ...CConfigFunc) *FilesClear

WithConfigFn for custom settings

type MockClocker added in v0.5.6

type MockClocker struct {
	// contains filtered or unexported fields
}

MockClocker mock clock for test

func NewMockClock added in v0.5.6

func NewMockClock(datetime string) *MockClocker

NewMockClock create a mock time instance from datetime string.

func (*MockClocker) Add added in v0.5.6

func (mt *MockClocker) Add(d time.Duration)

Add progresses time by the given duration.

func (*MockClocker) Datetime added in v0.5.6

func (mt *MockClocker) Datetime() string

Datetime returns the current time in the format "2006-01-02 15:04:05".

func (*MockClocker) Now added in v0.5.6

func (mt *MockClocker) Now() time.Time

Now get current time.

type RotateMode added in v0.5.2

type RotateMode uint8

RotateMode for a rotated file. 0: rename, 1: create

const (
	// ModeRename rotating file by rename.
	//
	// Example flow:
	//  - always write to "error.log"
	//  - rotating by rename it to "error.log.20201223"
	//  - then re-create "error.log"
	ModeRename RotateMode = iota

	// ModeCreate rotating file by create a new file.
	//
	// Example flow:
	//  - directly create a new file on each rotated time. eg: "error.log.20201223", "error.log.20201224"
	ModeCreate
)

func StringToRotateMode added in v0.6.0

func StringToRotateMode(s string) (RotateMode, error)

StringToRotateMode convert string to RotateMode

func (RotateMode) MarshalJSON added in v0.6.0

func (m RotateMode) MarshalJSON() ([]byte, error)

MarshalJSON implement the JSON Marshal interface encoding/json.Marshaler

func (RotateMode) String added in v0.5.2

func (m RotateMode) String() string

String get string name

func (*RotateMode) UnmarshalJSON added in v0.6.0

func (m *RotateMode) UnmarshalJSON(data []byte) error

UnmarshalJSON implement the JSON Unmarshal interface encoding/json.Unmarshaler

type RotateTime

type RotateTime int

RotateTime for a rotating file. unit is seconds.

EveryDay:

  • "error.log.20201223"

EveryHour, Every30Min, EveryMinute:

  • "error.log.20201223_1500"
  • "error.log.20201223_1530"
  • "error.log.20201223_1523"
const (
	EveryMonth  RotateTime = 30 * timex.OneDaySec
	EveryDay    RotateTime = timex.OneDaySec
	EveryHour   RotateTime = timex.OneHourSec
	Every30Min  RotateTime = 30 * timex.OneMinSec
	Every15Min  RotateTime = 15 * timex.OneMinSec
	EveryMinute RotateTime = timex.OneMinSec
	EverySecond RotateTime = 1 // only use for tests
)

built in rotate time constants

func StringToRotateTime added in v0.6.0

func StringToRotateTime(s string) (RotateTime, error)

StringToRotateTime parse and convert string to RotateTime

func (RotateTime) FirstCheckTime

func (rt RotateTime) FirstCheckTime(now time.Time) time.Time

FirstCheckTime for a rotated file. - will automatically align the time from the start of each hour.

func (RotateTime) Interval

func (rt RotateTime) Interval() int64

Interval get check interval time. unit is seconds.

func (RotateTime) MarshalJSON added in v0.6.0

func (rt RotateTime) MarshalJSON() ([]byte, error)

MarshalJSON implement the JSON Marshal interface encoding/json.Marshaler

func (RotateTime) String

func (rt RotateTime) String() string

String rotate type to string

func (RotateTime) TimeFormat

func (rt RotateTime) TimeFormat() (suffixFormat string)

TimeFormat get log file suffix format

EveryDay:

  • "error.log.20201223"

EveryHour, Every30Min, EveryMinute:

  • "error.log.20201223_1500"
  • "error.log.20201223_1530"
  • "error.log.20201223_1523"

func (*RotateTime) UnmarshalJSON added in v0.6.0

func (rt *RotateTime) UnmarshalJSON(data []byte) error

UnmarshalJSON implement the JSON Unmarshal interface encoding/json.Unmarshaler

type RotateWriter

type RotateWriter interface {
	io.WriteCloser
	Clean() error
	Flush() error
	Rotate() error
	Sync() error
}

RotateWriter interface

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer a flush, close, writer and support rotate file.

refer https://github.com/flike/golog/blob/master/filehandler.go

func NewWriter

func NewWriter(c *Config) (*Writer, error)

NewWriter create rotate write with config and init it.

Example (On_other_logger)
package main

import (
	"log"

	"github.com/gookit/slog/rotatefile"
)

func main() {
	logFile := "testdata/another_logger.log"
	writer, err := rotatefile.NewConfig(logFile).Create()
	if err != nil {
		panic(err)
	}

	log.SetOutput(writer)
	log.Println("log message")
}

func NewWriterWith

func NewWriterWith(fns ...ConfigFn) (*Writer, error)

NewWriterWith create a rotated writer with some settings.

func (*Writer) Clean

func (d *Writer) Clean() (err error)

Clean old files by config

func (*Writer) Close

func (d *Writer) Close() error

Close the writer. will sync data to disk, then close the file handle. and it will stop the async clean backups.

func (*Writer) Config

func (d *Writer) Config() Config

Config gets the config

func (*Writer) Flush

func (d *Writer) Flush() error

Flush sync data to disk. alias of Sync()

func (*Writer) MustClose added in v0.5.6

func (d *Writer) MustClose()

MustClose the writer. alias of Close(), but will panic if has error.

func (*Writer) Rotate

func (d *Writer) Rotate() error

Rotate the file by config and async clean backups

func (*Writer) Sync

func (d *Writer) Sync() error

Sync data to disk.

func (*Writer) Write

func (d *Writer) Write(p []byte) (n int, err error)

Write data to file. then check and do rotate file, then async clean backups

func (*Writer) WriteString

func (d *Writer) WriteString(s string) (n int, err error)

WriteString implements the io.StringWriter

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL