Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.25

require (
github.com/BurntSushi/toml v1.5.0
github.com/DeRuina/timberjack v1.3.5
github.com/KimMachineGun/automemlimit v0.7.4
github.com/Masterminds/sprig/v3 v3.3.0
github.com/alecthomas/chroma/v2 v2.20.0
Expand Down Expand Up @@ -43,7 +44,6 @@ require (
golang.org/x/sync v0.16.0
golang.org/x/term v0.34.0
golang.org/x/time v0.12.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOv
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/DeRuina/timberjack v1.3.5 h1:a8QrIyFCmnx6sjqmroFTIXcmNcen69dlx8DBRmN8+qU=
github.com/DeRuina/timberjack v1.3.5/go.mod h1:oir/YwhAK3URX7u4CDuMzdVQtLQqc1l3M/vJ6WBsjZs=
github.com/KimMachineGun/automemlimit v0.7.4 h1:UY7QYOIfrr3wjjOAqahFmC3IaQCLWvur9nmfIn6LnWk=
github.com/KimMachineGun/automemlimit v0.7.4/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
Expand Down Expand Up @@ -149,6 +151,8 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
Expand Down Expand Up @@ -663,8 +667,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
93 changes: 83 additions & 10 deletions modules/logging/filewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import (
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/DeRuina/timberjack"
"github.com/dustin/go-humanize"
"gopkg.in/natefinch/lumberjack.v2"

"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
Expand Down Expand Up @@ -96,6 +98,21 @@ type FileWriter struct {
// it will be rotated.
RollSizeMB int `json:"roll_size_mb,omitempty"`

// Roll log file after some time
RollInterval time.Duration `json:"roll_interval,omitempty"`

// Roll log file at fix minutes
// For example []int{0, 30} will roll file at xx:00 and xx:30 each hour
// Invalid value are ignored with a warning on stderr
// See https://github.com/DeRuina/timberjack#%EF%B8%8F-rotation-notes--warnings for caveats
RollAtMinutes []int `json:"roll_minutes,omitempty"`

// Roll log file at fix time
// For example []string{"00:00", "12:00"} will roll file at 00:00 and 12:00 each day
// Invalid value are ignored with a warning on stderr
// See https://github.com/DeRuina/timberjack#%EF%B8%8F-rotation-notes--warnings for caveats
RollAt []string `json:"roll_at,omitempty"`

// Whether to compress rolled files. Default: true
RollCompress *bool `json:"roll_gzip,omitempty"`

Expand All @@ -109,6 +126,11 @@ type FileWriter struct {

// How many days to keep rolled log files. Default: 90
RollKeepDays int `json:"roll_keep_days,omitempty"`

// Rotated file will have format <logfilename>-<format>-<criterion>.log
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should explain that the default from timberjack is:

// Optional. If unset or invalid, defaults to 2006-01-02T15-04-05.000 (with fallback warning)

Also mention that the <format> must be a Go time compatible format described here https://pkg.go.dev/time#pkg-constants

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add doc & link to go doc in 6ff7126

// Optional. If unset or invalid, defaults to 2006-01-02T15-04-05.000 (with fallback warning)
// <format> must be a Go time compatible format, see https://pkg.go.dev/time#pkg-constants
BackupTimeFormat string `json:"backup_time_format,omitempty"`
}

// CaddyModule returns the Caddy module information.
Expand Down Expand Up @@ -156,7 +178,7 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
roll := fw.Roll == nil || *fw.Roll

// create the file if it does not exist; create with the configured mode, or default
// to restrictive if not set. (lumberjack will reuse the file mode across log rotation)
// to restrictive if not set. (timberjack will reuse the file mode across log rotation)
if err := os.MkdirAll(filepath.Dir(fw.Filename), 0o700); err != nil {
return nil, err
}
Expand All @@ -166,7 +188,7 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
}
info, err := file.Stat()
if roll {
file.Close() // lumberjack will reopen it on its own
file.Close() // timberjack will reopen it on its own
}

// Ensure already existing files have the right mode, since OpenFile will not set the mode in such case.
Expand Down Expand Up @@ -201,13 +223,17 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
if fw.RollKeepDays == 0 {
fw.RollKeepDays = 90
}
return &lumberjack.Logger{
Filename: fw.Filename,
MaxSize: fw.RollSizeMB,
MaxAge: fw.RollKeepDays,
MaxBackups: fw.RollKeep,
LocalTime: fw.RollLocalTime,
Compress: *fw.RollCompress,
return &timberjack.Logger{
Filename: fw.Filename,
MaxSize: fw.RollSizeMB,
MaxAge: fw.RollKeepDays,
MaxBackups: fw.RollKeep,
LocalTime: fw.RollLocalTime,
Compress: *fw.RollCompress,
RotationInterval: fw.RollInterval,
RotateAtMinutes: fw.RollAtMinutes,
RotateAt: fw.RollAt,
BackupTimeFormat: fw.BackupTimeFormat,
}, nil
}

Expand Down Expand Up @@ -314,6 +340,53 @@ func (fw *FileWriter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
fw.RollKeepDays = int(math.Ceil(keepFor.Hours() / 24))

case "roll_interval":
var durationStr string
if !d.AllArgs(&durationStr) {
return d.ArgErr()
}
duration, err := time.ParseDuration(durationStr)
if err != nil {
return d.Errf("parsing roll_interval duration: %v", err)
}
fw.RollInterval = duration

case "roll_minutes":
var minutesArrayStr string
if !d.AllArgs(&minutesArrayStr) {
return d.ArgErr()
}
minutesStr := strings.Split(minutesArrayStr, ",")
minutes := make([]int, len(minutesStr))
for i := range minutesStr {
ms := strings.Trim(minutesStr[i], " ")
m, err := strconv.Atoi(ms)
if err != nil {
return d.Errf("parsing roll_minutes number: %v", err)
}
minutes[i] = m
}
fw.RollAtMinutes = minutes

case "roll_at":
var timeArrayStr string
if !d.AllArgs(&timeArrayStr) {
return d.ArgErr()
}
timeStr := strings.Split(timeArrayStr, ",")
times := make([]string, len(timeStr))
for i := range timeStr {
times[i] = strings.Trim(timeStr[i], " ")
}
fw.RollAt = times

case "backup_time_format":
var format string
if !d.AllArgs(&format) {
return d.ArgErr()
}
fw.BackupTimeFormat = format

default:
return d.Errf("unrecognized subdirective '%s'", d.Val())
}
Expand Down
Loading