Log rotation¶
/bin/rotate_log compresses oversized cron.log into a timestamped
tar.gz and trims old archives. It runs on ROTATE_LOG_CRON (default
weekly on Saturday at midnight).
Variables¶
| Variable | Default | Description |
|---|---|---|
ROTATE_LOG_CRON |
0 0 * * 6 |
Cron schedule for /bin/rotate_log. |
CRON_LOG_MAX_SIZE |
1048576 |
Rotate when /var/log/cron.log exceeds this size (bytes). |
MAX_CRON_LOG_ARCHIVES |
5 |
Keep this many compressed archives cron_log_<timestamp>.tar.gz. |
The job is wrapped in /bin/locked_run rotate_log like every other cron
entry, so it cannot run concurrently with a previous rotation tick.
What it does¶
flowchart LR
A[/bin/rotate_log] --> B{cron.log > CRON_LOG_MAX_SIZE?}
B -- no --> Z[Exit 0]
B -- yes --> C[Rename cron.log → cron_log_YYYYMMDD-HHMMSS]
C --> D[gzip into tar.gz]
D --> E[Create empty cron.log]
E --> F{Archives > MAX_CRON_LOG_ARCHIVES?}
F -- no --> Z
F -- yes --> G[Delete oldest extras]
G --> Z
/var/log/cron.log is the only file rotated. Per-worker *-last.log
files are overwritten on each run, and the structured last-*.json is
overwritten via *.tmp + mv; neither needs rotation.
Disabling rotation¶
The image deliberately does not support an empty ROTATE_LOG_CRON
(it is a required schedule). To effectively disable rotation, raise
CRON_LOG_MAX_SIZE to a value the log will never reach (e.g.
1099511627776 = 1 TiB) — the cron tick still fires but does nothing.
If you ship cron logs externally (Loki, ELK, Datadog), the simplest pattern is:
- Mount
/var/logsomewhere you can scrape. - Set
CRON_LOG_MAX_SIZE=10485760(10 MiB) so even a misbehaving scrape cannot leave you log-less. - Set
MAX_CRON_LOG_ARCHIVES=20for a small forensic tail.
Manual rotation¶
docker exec -ti restic-backup-helper /bin/rotate_log
docker exec -ti restic-backup-helper ls -la /var/log/cron_log_*.tar.gz
Run on demand before triaging a logspam incident so the archive preserves the relevant tail before the next tick.
Why a custom rotator¶
logrotate is not in the upstream restic/restic Alpine base. The
helper rolls its own minimal rotator to avoid pulling a heavier package
just for one file, and to keep the cron syntax consistent (*_CRON for
every scheduled thing). If you want a different policy (size-based
rolling, daily forced rotation, …), wrap the host cron.log with
logrotate outside the container.