diff --git a/modules/logging/filewriter.go b/modules/logging/filewriter.go index 0445ef06f..2e19ec843 100644 --- a/modules/logging/filewriter.go +++ b/modules/logging/filewriter.go @@ -108,7 +108,7 @@ type FileWriter struct { RollSizeMB int `json:"roll_size_mb,omitempty"` // Roll log file after some time - RollInterval time.Duration `json:"roll_interval,omitempty"` + RollInterval caddy.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 @@ -287,7 +287,7 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) { MaxBackups: fw.RollKeep, LocalTime: fw.RollLocalTime, Compression: compression, - RotationInterval: fw.RollInterval, + RotationInterval: time.Duration(fw.RollInterval), RotateAtMinutes: fw.RollAtMinutes, RotateAt: fw.RollAt, BackupTimeFormat: fw.BackupTimeFormat, @@ -489,11 +489,11 @@ func (fw *FileWriter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { if !d.AllArgs(&durationStr) { return d.ArgErr() } - duration, err := time.ParseDuration(durationStr) + duration, err := caddy.ParseDuration(durationStr) if err != nil { return d.Errf("parsing roll_interval duration: %v", err) } - fw.RollInterval = duration + fw.RollInterval = caddy.Duration(duration) case "roll_minutes": // Accept either a single comma-separated argument or diff --git a/modules/logging/filewriter_test.go b/modules/logging/filewriter_test.go index de46891fa..2425381f3 100644 --- a/modules/logging/filewriter_test.go +++ b/modules/logging/filewriter_test.go @@ -23,6 +23,7 @@ import ( "path/filepath" "syscall" "testing" + "time" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" ) @@ -648,3 +649,69 @@ file /var/log/app.log { t.Fatal("expected error for invalid dir_mode") } } + +func TestCaddyfile_RollInterval(t *testing.T) { + tests := []struct { + name string + input string + wantSecs float64 + wantErr bool + }{ + { + name: "day unit", + input: `file /var/log/app.log { + roll_interval 1d +}`, + wantSecs: 86400, + }, + { + name: "hours unit", + input: `file /var/log/app.log { + roll_interval 24h +}`, + wantSecs: 86400, + }, + { + name: "minutes unit", + input: `file /var/log/app.log { + roll_interval 30m +}`, + wantSecs: 1800, + }, + { + name: "fractional days", + input: `file /var/log/app.log { + roll_interval 1.5d +}`, + wantSecs: 129600, + }, + { + name: "invalid duration", + input: `file /var/log/app.log { + roll_interval bogus +}`, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d := caddyfile.NewTestDispenser(tt.input) + var fw FileWriter + err := fw.UnmarshalCaddyfile(d) + if tt.wantErr { + if err == nil { + t.Fatal("expected error but got none") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + gotSecs := time.Duration(fw.RollInterval).Seconds() + if gotSecs != tt.wantSecs { + t.Errorf("got %v seconds, want %v", gotSecs, tt.wantSecs) + } + }) + } +}