From 987375297862d9cd0a3fa33cfb199c25e504ad1b Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 23 Feb 2026 18:04:45 -0500 Subject: [PATCH] logging: Support `zstd` roll compression (#7515) --- .../log_roll_days.caddyfiletest | 4 ++ modules/logging/filewriter.go | 44 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/caddytest/integration/caddyfile_adapt/log_roll_days.caddyfiletest b/caddytest/integration/caddyfile_adapt/log_roll_days.caddyfiletest index 3e2aa0d81..9b15eb282 100644 --- a/caddytest/integration/caddyfile_adapt/log_roll_days.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/log_roll_days.caddyfiletest @@ -6,6 +6,7 @@ log one { dir_mode 0755 roll_size 1gb roll_uncompressed + roll_compression none roll_local_time roll_keep 5 roll_keep_for 90d @@ -16,6 +17,7 @@ log two { mode 0777 dir_mode from_file roll_size 1gib + roll_compression zstd roll_interval 12h roll_at 00:00 06:00 12:00,18:00 roll_minutes 10 40 45,46 @@ -39,6 +41,7 @@ log two { "filename": "/var/log/access.log", "mode": "0644", "output": "file", + "roll_compression": "none", "roll_gzip": false, "roll_keep": 5, "roll_keep_days": 90, @@ -61,6 +64,7 @@ log two { "12:00", "18:00" ], + "roll_compression": "zstd", "roll_interval": 43200000000000, "roll_keep": 10, "roll_keep_days": 90, diff --git a/modules/logging/filewriter.go b/modules/logging/filewriter.go index e9ca4013a..0ffcfa9bf 100644 --- a/modules/logging/filewriter.go +++ b/modules/logging/filewriter.go @@ -122,9 +122,16 @@ type FileWriter struct { // 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 + // Whether to compress rolled files. + // Default: true. + // Deprecated: Use RollCompression instead, setting it to "none". RollCompress *bool `json:"roll_gzip,omitempty"` + // RollCompression selects the compression algorithm for rolled files. + // Accepted values: "none", "gzip", "zstd". + // Default: gzip + RollCompression string `json:"roll_compression,omitempty"` + // Whether to use local timestamps in rolled filenames. // Default: false RollLocalTime bool `json:"roll_local_time,omitempty"` @@ -254,13 +261,32 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) { if fw.RollKeepDays == 0 { fw.RollKeepDays = 90 } + + // Determine compression algorithm to use. Priority: + // 1) explicit RollCompression (none|gzip|zstd) + // 2) if RollCompress is unset or true -> gzip + // 3) if RollCompress is false -> none + var compression string + if fw.RollCompression != "" { + compression = strings.ToLower(strings.TrimSpace(fw.RollCompression)) + if compression != "none" && compression != "gzip" && compression != "zstd" { + return nil, fmt.Errorf("invalid roll_compression: %s", fw.RollCompression) + } + } else { + if fw.RollCompress == nil || *fw.RollCompress { + compression = "gzip" + } else { + compression = "none" + } + } + return &timberjack.Logger{ Filename: fw.Filename, MaxSize: fw.RollSizeMB, MaxAge: fw.RollKeepDays, MaxBackups: fw.RollKeep, LocalTime: fw.RollLocalTime, - Compress: *fw.RollCompress, + Compression: compression, RotationInterval: fw.RollInterval, RotateAtMinutes: fw.RollAtMinutes, RotateAt: fw.RollAt, @@ -332,6 +358,7 @@ func mkdirAllFromFile(dir string, fileMode os.FileMode) error { // roll_disabled // roll_size // roll_uncompressed +// roll_compression // roll_local_time // roll_keep // roll_keep_for @@ -413,6 +440,19 @@ func (fw *FileWriter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return d.ArgErr() } + case "roll_compression": + var comp string + if !d.AllArgs(&comp) { + return d.ArgErr() + } + comp = strings.ToLower(strings.TrimSpace(comp)) + switch comp { + case "none", "gzip", "zstd": + fw.RollCompression = comp + default: + return d.Errf("parsing roll_compression: must be 'none', 'gzip' or 'zstd'") + } + case "roll_local_time": fw.RollLocalTime = true if d.NextArg() {