@marcel91200 / caddy Mirror · read-only / commits / 98737529
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 14:45 UTC

logging: Support `zstd` roll compression (#7515)

Francis Lavoie committed Feb 23, 2026 at 18:04 UTC 987375297862d9cd0a3fa33cfb199c25e504ad1b
2 files changed +46 -2
caddytest/integration/caddyfile_adapt/log_roll_days.caddyfiletest
+4
@@ -6,6 +6,7 @@ log one {
6 dir_mode 0755
7 roll_size 1gb
8 roll_uncompressed
9 + roll_compression none
10 roll_local_time
11 roll_keep 5
12 roll_keep_for 90d
@@ -16,6 +17,7 @@ log two {
17 mode 0777
18 dir_mode from_file
19 roll_size 1gib
20 + roll_compression zstd
21 roll_interval 12h
22 roll_at 00:00 06:00 12:00,18:00
23 roll_minutes 10 40 45,46
@@ -39,6 +41,7 @@ log two {
41 "filename": "/var/log/access.log",
42 "mode": "0644",
43 "output": "file",
44 + "roll_compression": "none",
45 "roll_gzip": false,
46 "roll_keep": 5,
47 "roll_keep_days": 90,
@@ -61,6 +64,7 @@ log two {
64 "12:00",
65 "18:00"
66 ],
67 + "roll_compression": "zstd",
68 "roll_interval": 43200000000000,
69 "roll_keep": 10,
70 "roll_keep_days": 90,
modules/logging/filewriter.go
+42 -2
@@ -122,9 +122,16 @@ type FileWriter struct {
122 // See https://github.com/DeRuina/timberjack#%EF%B8%8F-rotation-notes--warnings for caveats
123 RollAt []string `json:"roll_at,omitempty"`
124
125 - // Whether to compress rolled files. Default: true
125 + // Whether to compress rolled files.
126 + // Default: true.
127 + // Deprecated: Use RollCompression instead, setting it to "none".
128 RollCompress *bool `json:"roll_gzip,omitempty"`
129
130 + // RollCompression selects the compression algorithm for rolled files.
131 + // Accepted values: "none", "gzip", "zstd".
132 + // Default: gzip
133 + RollCompression string `json:"roll_compression,omitempty"`
134 +
135 // Whether to use local timestamps in rolled filenames.
136 // Default: false
137 RollLocalTime bool `json:"roll_local_time,omitempty"`
@@ -254,13 +261,32 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
261 if fw.RollKeepDays == 0 {
262 fw.RollKeepDays = 90
263 }
264 +
265 + // Determine compression algorithm to use. Priority:
266 + // 1) explicit RollCompression (none|gzip|zstd)
267 + // 2) if RollCompress is unset or true -> gzip
268 + // 3) if RollCompress is false -> none
269 + var compression string
270 + if fw.RollCompression != "" {
271 + compression = strings.ToLower(strings.TrimSpace(fw.RollCompression))
272 + if compression != "none" && compression != "gzip" && compression != "zstd" {
273 + return nil, fmt.Errorf("invalid roll_compression: %s", fw.RollCompression)
274 + }
275 + } else {
276 + if fw.RollCompress == nil || *fw.RollCompress {
277 + compression = "gzip"
278 + } else {
279 + compression = "none"
280 + }
281 + }
282 +
283 return &timberjack.Logger{
284 Filename: fw.Filename,
285 MaxSize: fw.RollSizeMB,
286 MaxAge: fw.RollKeepDays,
287 MaxBackups: fw.RollKeep,
288 LocalTime: fw.RollLocalTime,
263 - Compress: *fw.RollCompress,
289 + Compression: compression,
290 RotationInterval: fw.RollInterval,
291 RotateAtMinutes: fw.RollAtMinutes,
292 RotateAt: fw.RollAt,
@@ -332,6 +358,7 @@ func mkdirAllFromFile(dir string, fileMode os.FileMode) error {
358 // roll_disabled
359 // roll_size <size>
360 // roll_uncompressed
361 +// roll_compression <none|gzip|zstd>
362 // roll_local_time
363 // roll_keep <num>
364 // roll_keep_for <days>
@@ -413,6 +440,19 @@ func (fw *FileWriter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
440 return d.ArgErr()
441 }
442
443 + case "roll_compression":
444 + var comp string
445 + if !d.AllArgs(&comp) {
446 + return d.ArgErr()
447 + }
448 + comp = strings.ToLower(strings.TrimSpace(comp))
449 + switch comp {
450 + case "none", "gzip", "zstd":
451 + fw.RollCompression = comp
452 + default:
453 + return d.Errf("parsing roll_compression: must be 'none', 'gzip' or 'zstd'")
454 + }
455 +
456 case "roll_local_time":
457 fw.RollLocalTime = true
458 if d.NextArg() {