rotatefile

package
v0.5.6 Latest Latest
Warning

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

Go to latest
Published: May 2, 2024 License: MIT Imports: 16 Imported by: 4

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 keep 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

	// DefaultFilenameFn default new filename func
	DefaultFilenameFn = func(filepath string, rotateNum uint) string {
		suffix := time.Now().Format("010215")

		return filepath + fmt.Sprintf(".%s_%03d", suffix, rotateNum)
	}

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

Functions

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 rotate 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 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 file by time.
	TimeClock Clocker

	// DebugMode for debug on development.
	DebugMode bool
}

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) *Config

NewConfig by file path

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) Debug added in v0.5.4

func (c *Config) Debug(vs ...any)

Debug print debug message on development

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 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 rotate file

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 new file.
	//
	// Example flow:
	//  - directly create new file on each rotate time. eg: "error.log.20201223", "error.log.20201224"
	ModeCreate
)

func (RotateMode) String added in v0.5.2

func (m RotateMode) String() string

String get string name

type RotateTime

type RotateTime int

RotateTime for rotate file. unit is seconds.

EveryDay:

  • "error.log.20201223"

EveryHour, Every30Min, EveryMinute:

  • "error.log.20201223_1500"
  • "error.log.20201223_1530"
  • "error.log.20201223_1523"
const (
	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 (RotateTime) FirstCheckTime

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

FirstCheckTime for rotate 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) 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"

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")
}
Output:

func NewWriterWith

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

NewWriterWith create rotate 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 will stop the async clean backups.

func (*Writer) Config

func (d *Writer) Config() Config

Config get 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.

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