Setting up logrotate for dependable Linux log management
Linux applications often keep active logs in /var/log, leaving old generations behind unless a rotation policy is configured. Logrotate closes, renames, compresses, and removes expired archives, preventing a busy service from filling the disk.
A practical logrotate configuration on RHEL, CentOS Stream, or Fedora should match the application’s ownership, file-reopening method, and retention requirements. Australian administrators must also account for AEST and AEDT daylight-saving changes, local date conventions, and infrastructure operating across Sydney, Melbourne, Brisbane, and Perth.
How logrotate manages log files
| Concern | File logs with logrotate | systemd journal |
|---|---|---|
| Primary tool | logrotate and logrotate.timer |
systemd-journald |
| Typical location | /var/log |
/var/log/journal |
| Rotation control | Time, size, file count, and age | Journal size and runtime limits |
| Reading history | less, tail, zcat, or zgrep |
journalctl |
| Compression | Configurable with compress |
Usually handled by the journal |
| Best suited to | Legacy daemons and applications writing local files | Services sending output to stdout and stderr |
Traditional applications need a policy describing which files to rotate, how often to rotate them, where compressed copies belong, and when old archives can be deleted. The main /etc/logrotate.conf file normally includes configuration files stored under /etc/logrotate.d.
Services designed for systemd often need no separate logrotate policy for their standard output and error streams. journalctl handles those journals, while SystemMaxUse, RuntimeMaxUse, and related controls determine retention. Directories and applications that still create their own files under /var/log remain candidates for logrotate.
Preparing paths, ownership, and retention
Use an exact path where practical, or a narrow wildcard that cannot match unrelated files. The parent directory should have trusted ownership and permissions because logrotate usually runs as root. Confirm which system account creates or reopens each active log before setting the create directive.
Retention should reflect both operational value and disk capacity. A daily schedule with rotate 14 retains up to 14 archived generations, but that count does not necessarily equal 14 days when a size threshold triggers extra rotations. Add maxage when a strict calendar limit is required.
Products that produce searchable audit trails need deliberate access controls as well as sensible retention. The application activity illustrated by expanded slot events shows why high-volume application records should not share an arbitrary rotation policy with unrelated system logs.
Building a reliable configuration
Create a dedicated policy file, such as /etc/logrotate.d/myapp, without giving it a .conf suffix:
/var/log/myapp/*.log {
daily
rotate 14
maxsize 100M
compress
delaycompress
missingok
notifempty
create 0640 myapp myapp
sharedscripts
postrotate
systemctl kill -s HUP myapp.service >/dev/null 2>&1 || true
endscript
}
The myapp user and group must exist and must match the account that writes the active files. delaycompress keeps the most recent archive uncompressed until the following cycle, while sharedscripts runs the reload command once even when several files match. The service must support SIGHUP and reopen its logs; otherwise, use copytruncate as a carefully tested alternative because it creates a brief window where new writes can be lost.
For logs stored on NFS, the shared storage setup explains the CentOS export, but rotation should still use local files and local state. Shipping logs to the host with rsyslog is more reliable than performing remote renames and compression.
Validating each rotation cycle
Use debug mode to inspect the planned actions without changing files:
sudo logrotate -d /etc/logrotate.d/myapp
sudo systemctl status logrotate.timer
After the check passes, perform a controlled forced rotation on a non-production host with sudo logrotate -f /etc/logrotate.d/myapp. Review the resulting filename, ownership, permissions, compression status, and application output before accepting the policy.
A repeatable verification checklist
Before a scheduled run
- Confirm the application writes to the exact path matched by the policy.
- Check owner, group, directory permissions, and available disk space.
- Review SELinux labels with
ls -Zon RHEL when using nonstandard log paths.
After the run
- Confirm the active file was recreated and the application resumed writing.
- Verify the previous generation exists and compressed archives remain readable.
- Record the rotation time and check the logrotate state file for duplicate processing.
Keeping production logging healthy
Check that logrotate.timer is enabled on systemd-based hosts. Australian organisations often standardise on RHEL, CentOS Stream, or Fedora for on-premises workloads, so package versions and defaults should be tested against the repositories used by the local market rather than copied from an overseas example. Public cloud deployments in Sydney and Melbourne may use different image builds and service accounts from those in Brisbane or Perth.
Monitoring should cover free disk space, rotation failures, unexpected growth, and whether each application reopens its files correctly. Schedule maintenance and reporting with AEST and AEDT in mind, and label timestamps clearly during daylight-saving transitions. Dates should also follow the familiar day/month/year convention where local reports require it.
The durable principle is straightforward: keep rotation local, test it against real file paths, and treat log retention as an essential part of service reliability.