logrotate — the standard Linux tool for managing log files. Rotates (renames), compresses, deletes old logs on a schedule. Installed in most distributions by default. Config in /etc/logrotate.d/. Runs daily via cron. Important: postrotate hook for reloading the app after rotation (nginx, syslog).
Below: step-by-step, working examples, common pitfalls, FAQ.
/var/log/myapp/*.logsystemctl reload nginx if HUP is requiredlogrotate -d /etc/logrotate.d/myapp (debug mode, no changes)logrotate -f /etc/logrotate.d/myapp| Scenario | Config |
|---|---|
| Standard nginx rotation | /var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 640 nginx adm
sharedscripts
postrotate
systemctl reload nginx > /dev/null 2>&1 || true
endscript
} |
| Weekly with size limit | /var/log/myapp/*.log {
weekly
rotate 12
size 100M
compress
missingok
} |
| copytruncate (for apps without HUP handler) | /var/log/app.log {
daily
rotate 7
copytruncate
# Copies the file and truncates the original in-place
} |
| Date in rotated filename | /var/log/myapp/*.log {
daily
rotate 30
dateext
dateformat -%Y%m%d
compress
} |
| Dry-run test | logrotate -d /etc/logrotate.d/myapp # debug, shows what would happen |
|| true — failing script blocks rotation/var/lib/logrotate/status is updatingjournald — built into systemd, binary format, <code>journalctl</code>. logrotate — text files with compression. For apps that write to files — logrotate.
cron.daily — once a day. For more frequent — hourly via /etc/logrotate.d/ and a cron entry.
Same directory with .1, .2, .gz suffixes. Example: access.log → access.log.1 → access.log.2.gz.
<code>logrotate -d</code> (dry-run) shows what would happen. Status: <code>cat /var/lib/logrotate/status</code> — last rotation time.