Repository navigation
[BUG] MaxBackups never deletes old monthly logs (cleanup glob derived from current month's basename) #1294
Description
Summary
RotateOption.MaxBackups never deletes old monthly log files. The cleanup glob in RotateLog() is derived from the current log file's basename, so it can only ever match files belonging to the current month. Archived logs from previous months (zr_<year>-<month>.log) are never matched and accumulate indefinitely.
Observed on a production instance: 9 monthly log files, 1.8 GB total, none removed, with MaxBackups: 16 configured.
Affected code
src/mod/info/logger/rotate.go, in RotateLog():
baseName := filepath.Base(l.CurrentLogFile)
baseName = baseName[:len(baseName)-len(filepath.Ext(baseName))]
// ...
if l.RotateOption.MaxBackups > 0 {
files, err := filepath.Glob(filepath.Join(backupDir, baseName+".*"))
if err == nil && len(files) > l.RotateOption.MaxBackups {
// delete oldest
}
}baseName comes from l.CurrentLogFile. Per src/mod/info/logger/logger.go:
func (l *Logger) getLogFilepath() string {
year, month, _ := time.Now().Date()
return filepath.Join(l.LogFolder, l.Prefix+"_"+strconv.Itoa(year)+"-"+strconv.Itoa(int(month))+".log")
}So in September 2026 baseName is zr_2026-9, and the glob is:
/opt/zoraxy/log/zr_2026-9.*
That pattern cannot match zr_2026-8.log, zr_2026-7.log, etc. The month is part of the basename itself, so each month's cleanup only ever sees its own files. MaxBackups is effectively a no-op for the monthly rollover files produced by ArchiveLog().
Second contributing factor
LogNeedRotate() returns early unless info.Size() >= l.RotateOption.MaxSize. A config carrying "maxSize": "0" (the value shipped in conf/log_conf.json on this instance) is parsed as 0, and while size >= 0 is technically always true, the whole path is gated behind RotateOption.Enabled, which defaults to false. Combined, an operator who never touches the logging settings gets no rotation and no retention at all — which is easy to miss because the monthly rollover in ArchiveLog() does keep producing new files and looks like rotation is working.
Steps to reproduce
- Run Zoraxy across several month boundaries so
ArchiveLog()createszr_<year>-<month>.logfiles. - Set
RotateOption.Enabled = truewith anyMaxBackupssmaller than the number of existing monthly files. - Trigger rotation (hourly ticker or
POST /api/log/rotate/trigger).
Expected: oldest monthly logs beyond MaxBackups are removed.
Actual: nothing is removed; only files matching the current month's prefix are ever considered.
Environment
- Zoraxy 3.3.4 (also present in
mainat time of writing) - Debian 13, amd64, systemd service
conf/log_conf.json:{"enabled": false, "maxSize": "0", "maxBackups": 16, "compress": true}
Suggested fix
Derive the cleanup pattern from the logger's Prefix rather than from the current file's basename, and exclude the file currently being written:
pattern := filepath.Join(backupDir, l.Prefix+"_*.log*")
files, err := filepath.Glob(pattern)
// filter out l.CurrentLogFile before applying MaxBackupsSorting lexicographically also mis-orders months once the year has more than nine (zr_2026-10 sorts before zr_2026-9), so ordering by modification time — or zero-padding the month in getLogFilepath() — would be worth addressing in the same change. Note that zero-padding alone would change existing filenames, so the glob should tolerate both forms during a transition.
A time-based retention option (MaxAge in days) alongside MaxBackups would also fit the monthly-file model better than a pure count, since one file equals one month.
Workaround for other operators
Until this is fixed, an external timer that compresses and prunes zr_*.log files works, as long as it never touches the file for the current month (Zoraxy holds it open, and log consumers such as CrowdSec tail it via a wildcard).
Activity
tobychui commentedon Sep 17, 2026
Will look into it later this weekend.
Btw since you already dig into the code base, you got interest to be our log system maintainer? I have been looking for someone to help with maintaining the log module, some additional help would be greatly appreciated ✨
BerziOnline commentedon Sep 17, 2026
Thank you very much!
Thank you very much, but to be honest I have not a very well coding background, being more network technician O:-)
Fix for #1294