Documentation
¶
Overview ¶
Package timberjack provides a rolling logger with size-based and time-based rotation.
Timberjack is a simple, pluggable component for log rotation. It can rotate the active log file when any of the following occur:
- the file grows beyond MaxSize (size-based)
- the configured RotationInterval elapses (interval-based)
- a scheduled time is reached via RotateAt or RotateAtMinutes (clock-based)
- rotation is triggered explicitly via Rotate() (manual)
Rotated files can optionally be compressed with gzip or zstd. Cleanup is handled automatically. Old log files are removed based on MaxBackups and MaxAge.
Import:
import "github.com/DeRuina/timberjack"
Timberjack works with any logger that writes to an io.Writer, including the standard library’s log package.
Concurrency note: timberjack assumes a single process writes to the target files. Reusing the same Logger configuration across multiple processes on the same machine may lead to improper behavior.
Source code: https://github.com/DeRuina/timberjack
Example ¶
To use timberjack with the standard library's log package, just pass it into the SetOutput function when your application starts.
log.SetOutput(&Logger{
Filename: "/var/log/myapp/foo.log",
MaxSize: 500, // megabytes
MaxBackups: 3, // number of backups
MaxAge: 28, // days
Compress: true, // disabled by default
LocalTime: true, // use the local timezone
RotationInterval: time.Hour * 24, // rotate daily
})
Index ¶
- Variables
- func Format(p string, t time.Time, options ...Option) (string, error)
- type AppendFunc
- type Appender
- type Clock
- type Event
- type EventType
- type FileRotatedEvent
- type Handler
- type HandlerFunc
- type Logger
- type Option
- func WithBackupTimeFormat(format string) Option
- func WithClock(c Clock) Option
- func WithCompress(n bool) Option
- func WithCompression(compression string) Option
- func WithLocalTime(localTime bool) Option
- func WithLocation(loc *time.Location) Option
- func WithMaxAge(d int) Option
- func WithMaxBackups(s int) Option
- func WithMaxSize(maxSize int) Option
- func WithMicroseconds(b byte) Option
- func WithMilliseconds(b byte) Option
- func WithPrefix(prefix string) Option
- func WithRotateAtMinutes(d []int) Option
- func WithRotationInterval(d time.Duration) Option
- func WithRotationTime(d time.Duration) Option
- func WithSpecification(b byte, a Appender) Option
- func WithSpecificationSet(ds SpecificationSet) Option
- func WithUnixSeconds(b byte) Option
- type SpecificationSet
- type Strftime
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // empty BackupTimeFormatField ErrEmptyBackupTimeFormatField = errors.New("empty backupformat field") )
var Local = clockFn(time.Now)
Local is an object satisfying the Clock interface, which returns the current time in the local timezone
var UTC = clockFn(func() time.Time { return time.Now().UTC() })
UTC is an object satisfying the Clock interface, which returns the current time in UTC
Functions ¶
func Format ¶
Format takes the format `s` and the time `t` to produce the format date/time. Note that this function re-compiles the pattern every time it is called.
If you know beforehand that you will be reusing the pattern within your application, consider creating a `Strftime` object and reusing it.
Types ¶
type AppendFunc ¶
AppendFunc is an utility type to allow users to create a function-only version of an Appender
type Appender ¶
Appender is the interface that must be fulfilled by components that implement the translation of specifications to actual time value.
The Append method takes the accumulated byte buffer, and the time to use to generate the textual representation. The resulting byte sequence must be returned by this method, normally by using the append() builtin function.
func Microseconds ¶
func Microseconds() Appender
Microsecond returns the Appender suitable for creating a zero-padded, 6-digit microsecond textual representation.
func Milliseconds ¶
func Milliseconds() Appender
Milliseconds returns the Appender suitable for creating a zero-padded, 3-digit millisecond textual representation.
func StdlibFormat ¶
StdlibFormat returns an Appender that simply goes through `time.Format()` For example, if you know you want to display the abbreviated month name for %b, you can create a StdlibFormat with the pattern `Jan` and register that for specification `b`:
a := StdlibFormat(`Jan`) ss := NewSpecificationSet() ss.Set('b', a) // does %b -> abbreviated month name
func UnixSeconds ¶
func UnixSeconds() Appender
UnixSeconds returns the Appender suitable for creating unix timestamp textual representation.
type FileRotatedEvent ¶
type FileRotatedEvent struct {
// contains filtered or unexported fields
}
type HandlerFunc ¶
type HandlerFunc func(Event)
type Logger ¶
type Logger struct {
// Filename is the file to write logs to. Backup log files will be retained
// in the same directory. It uses <processname>-timberjack.log in
// os.TempDir() if empty.
Filename string `json:"filename" yaml:"filename"`
// MaxSize is the maximum size in megabytes of the log file before it gets
// rotated. It defaults to 100 megabytes.
MaxSize int `json:"maxsize" yaml:"maxsize"`
// MaxAge is the maximum number of days to retain old log files based on the
// timestamp encoded in their filename. Note that a day is defined as 24
// hours and may not exactly correspond to calendar days due to daylight
// savings, leap seconds, etc. The default is not to remove old log files
// based on age.
MaxAge int `json:"maxage" yaml:"maxage"`
//历史文件保存数量
RotationCount uint `json:"rotationCount" yaml:"rotationCount"`
// MaxBackups is the maximum number of old log files to retain. The default
// is to retain all old log files (though MaxAge may still cause them to get
// deleted.) MaxBackups counts distinct rotation events (timestamps).
MaxBackups int `json:"maxbackups" yaml:"maxbackups"`
// LocalTime determines if the time used for formatting the timestamps in
// backup files is the computer's local time. The default is to use UTC
// time.
LocalTime bool `json:"localtime" yaml:"localtime"`
// Deprecated: use Compression instead ("none" | "gzip" | "zstd").
Compress bool `json:"compress,omitempty" yaml:"compress,omitempty"`
// Compression selects the algorithm. If empty, legacy Compress is used.
// Allowed values: "none", "gzip", "zstd". Unknown => "none" (with a warning).
Compression string `json:"compression,omitempty" yaml:"compression,omitempty"`
// RotationInterval is the maximum duration between log rotations.
// If the elapsed time since the last rotation exceeds this interval,
// the log file is rotated, even if the file size has not reached MaxSize.
// The minimum recommended value is 1 minute. If set to 0, time-based rotation is disabled.
//
// Example: RotationInterval = time.Hour * 24 will rotate logs daily.
RotationInterval time.Duration `json:"rotationinterval" yaml:"rotationinterval"`
// BackupTimeFormat defines the layout for the timestamp appended to rotated file names.
// While other formats are allowed, it is recommended to follow the standard Go time layout
// (https://pkg.go.dev/time#pkg-constants). Use the ValidateBackupTimeFormat() method to check
// if the value is valid. It is recommended to call this method before using the Logger instance.
//
// WARNING: This field is assumed to be constant after initialization.
// WARNING: If invalid value is supplied then default format `2006-01-02T15-04-05.000` will be used.
//
// Example:
// BackupTimeFormat = `2006-01-02-15-04-05`
// will generate rotated backup files in the format:
// <logfilename>-2006-01-02-15-04-05-<rotationCriterion>-timberjack.log
// where `rotationCriterion` could be `time` or `size`.
BackupTimeFormat string `json:"backuptimeformat" yaml:"backuptimeformat"`
// RotateAtMinutes defines specific minutes within an hour (0-59) to trigger a rotation.
// For example, []int{0} for top of the hour, []int{0, 30} for top and half-past the hour.
// Rotations are aligned to the clock minute (second 0).
// This operates in addition to RotationInterval and MaxSize.
// If multiple rotation conditions are met, the first one encountered typically triggers.
RotateAtMinutes []int `json:"rotateAtMinutes" yaml:"rotateAtMinutes"`
// RotateAt defines specific time within a day to trigger a rotation.
// For example, []string{'00:00'} for midnight, []string{'00:00', '12:00'} for
// midnight and midday.
// Rotations are aligned to the clock minute (second 0).
// This operates in addition to RotationInterval and MaxSize.
// If multiple rotation conditions are met, the first one encountered typically triggers.
RotateAt []string `json:"rotateAt" yaml:"rotateAt"`
// AppendTimeAfterExt controls where the timestamp/reason go.
// false (default): <name>-<timestamp>-<reason>.log
// true: <name>.log-<timestamp>-<reason>
AppendTimeAfterExt bool `json:"appendTimeAfterExt" yaml:"appendTimeAfterExt"`
// FileMode sets the permissions to use when creating new log files.
// It will be inherited by rotated files.
// If zero, the default of 0o640 is used.
//
// Note that a local umask may alter the final permissions.
// Also, on non-Linux systems this might not have the desired effect.
FileMode os.FileMode `json:"filemode" yaml:"filemode"`
// contains filtered or unexported fields
}
Logger is an io.WriteCloser that writes to the specified filename.
Logger opens or creates the logfile on the first Write. If the file exists and is smaller than MaxSize megabytes, timberjack will open and append to that file. If the file's size exceeds MaxSize, or if the configured RotationInterval has elapsed since the last rotation, the file is closed, renamed with a timestamp, and a new logfile is created using the original filename.
Thus, the filename you give Logger is always the "current" log file.
Backups use the log file name given to Logger, in the form: `name-timestamp-<reason>.ext` where `name` is the filename without the extension, `timestamp` is the time of rotation formatted as `2006-01-02T15-04-05.000`, `reason` is "size" or "time" (Rotate/auto), or a custom tag (RotateWithReason), and `ext` is the original extension. For example, if your Logger.Filename is `/var/log/foo/server.log`, a backup created at 6:30pm on Nov 11 2016 due to size would use the filename `/var/log/foo/server-2016-11-04T18-30-00.000-size.log`.
Cleaning Up Old Log Files ¶
Whenever a new logfile is created, old log files may be deleted based on MaxBackups and MaxAge. The most recent files (according to the timestamp) will be retained up to MaxBackups (or all files if MaxBackups is 0). Any files with a timestamp older than MaxAge days are deleted, regardless of MaxBackups. Note that the timestamp is the rotation time, not necessarily the last write time.
If MaxBackups and MaxAge are both 0, no old log files will be deleted.
timberjack assumes only a single process is writing to the log files at a time.
func (*Logger) Close ¶
Close implements io.Closer, and closes the current logfile. It also signals any running goroutines (like scheduled rotation or mill) to stop.
func (*Logger) Rotate ¶
Rotate forces an immediate rotation using the legacy auto-reason logic. (empty reason => "time" if an interval rotation is due, otherwise "size")
Example ¶
Example of how to rotate in response to SIGHUP.
l := &Logger{}
log.SetOutput(l)
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP)
go func() {
for {
<-c
l.Rotate()
}
}()
func (*Logger) RotateWithReason ¶
RotateWithReason forces a rotation immediately and tags the backup filename with the provided reason (after sanitization). If the sanitized reason is empty, it falls back to the default behavior used by Rotate(): "time" if an interval rotation is due, otherwise "size".
NOTE: Like Rotate(), this does not modify lastRotationTime. If an interval rotation is already due, a subsequent write may still trigger another interval-based rotation.
func (*Logger) ValidateBackupTimeFormat ¶
ValidateBackupTimeFormat checks if the configured BackupTimeFormat is a valid time layout. While other formats are allowed, it is recommended to follow the standard time layout rules as defined here: https://pkg.go.dev/time#pkg-constants
WARNING: Assumes that BackupTimeFormat value remains constant after initialization.
func (*Logger) Write ¶
Write implements io.Writer. It writes the provided bytes to the current log file. If the log file exceeds MaxSize after writing, or if the configured RotationInterval has elapsed since the last rotation, or if a scheduled rotation time (RotateAtMinutes) has been reached, the file is closed, renamed to include a timestamp, and a new log file is created using the original filename. If the size of a single write exceeds MaxSize, the write is rejected and an error is returned.
type Option ¶
type Option interface {
Name() string
Value() interface{}
}
Option is used to pass optional arguments to the RotateLogs constructor
func WithBackupTimeFormat ¶
func WithClock ¶
WithClock creates a new Option that sets a clock that the RotateLogs object will use to determine the current time.
By default rotatelogs.Local, which returns the current time in the local time zone, is used. If you would rather use UTC, use rotatelogs.UTC as the argument to this option, and pass it to the constructor.
func WithCompress ¶
WithCompress creates a new Option that sets the number of files should be kept before it gets purged from the file system.
func WithCompression ¶
func WithLocalTime ¶
func WithLocation ¶
WithLocation creates a new Option that sets up a "Clock" interface that the RotateLogs object will use to determine the current time.
This optin works by always returning the in the given location.
func WithMaxAge ¶
WithMaxAge creates a new Option that sets the max age of a log file before it gets purged from the file system.
func WithMaxBackups ¶
WithMaxBackups creates a new Option that sets the log file size between rotation.
func WithMaxSize ¶
func WithMicroseconds ¶
WithMicroseconds is similar to WithSpecification, and specifies that the Strftime object should interpret the pattern `%b` (where b is the byte that you specify as the argument) as the zero-padded, 3 letter microseconds of the time.
func WithMilliseconds ¶
WithMilliseconds is similar to WithSpecification, and specifies that the Strftime object should interpret the pattern `%b` (where b is the byte that you specify as the argument) as the zero-padded, 3 letter milliseconds of the time.
func WithPrefix ¶
WithPrefix creates a new Option that sets the prefix of the log file.
func WithRotateAtMinutes ¶
func WithRotationInterval ¶
func WithRotationTime ¶
WithRotationTime creates a new Option that sets the time between rotation.
func WithSpecification ¶
WithSpecification allows you to create a new specification set on the fly, to be used only for that invocation.
func WithSpecificationSet ¶
func WithSpecificationSet(ds SpecificationSet) Option
WithSpecification allows you to specify a custom specification set
func WithUnixSeconds ¶
WithUnixSeconds is similar to WithSpecification, and specifies that the Strftime object should interpret the pattern `%b` (where b is the byte that you specify as the argument) as the unix timestamp in seconds
type SpecificationSet ¶
type SpecificationSet interface {
Lookup(byte) (Appender, error)
Delete(byte) error
Set(byte, Appender) error
}
SpecificationSet is a container for patterns that Strftime uses. If you want a custom strftime, you can copy the default SpecificationSet and tweak it
func NewSpecificationSet ¶
func NewSpecificationSet() SpecificationSet
NewSpecificationSet creates a specification set with the default specifications.
type Strftime ¶
type Strftime struct {
// contains filtered or unexported fields
}
Strftime is the object that represents a compiled strftime pattern
func NewStf ¶
NewStf creates a new Strftime object. If the compilation fails, then an error is returned in the second argument.
func (*Strftime) Dump ¶
Dump outputs the internal structure of the formatter, for debugging purposes. Please do NOT assume the output format to be fixed: it is expected to change in the future.
func (*Strftime) Format ¶
Format takes the destination `dst` and time `t`. It formats the date/time using the pre-compiled pattern, and outputs the results to `dst`
func (*Strftime) FormatBuffer ¶
FormatBuffer is equivalent to Format, but appends the result directly to supplied slice dst, returning the updated slice. This avoids any internal memory allocation.
func (*Strftime) FormatString ¶
FormatString takes the time `t` and formats it, returning the string containing the formated data.