Logrotate operates in two primary modes that affect how you can monitor it:
- Cron-driven mode: Runs via daily cron job at /etc/cron.daily/logrotate
- Manual execution: Can be triggered with
logrotate -v /path/to/config
The simplest way to monitor logrotate is using verbose mode:
sudo logrotate -v /etc/logrotate.conf
For even more detailed debugging:
sudo logrotate -d /etc/logrotate.conf
Logrotate maintains state in /var/lib/logrotate/status
or /var/lib/logrotate/logrotate.status
. You can inspect this file to see when each log was last rotated:
cat /var/lib/logrotate/status
Since logrotate typically runs via cron, check cron logs:
grep logrotate /var/log/syslog
Or for systems using journalctl:
journalctl -u cron | grep logrotate
For continuous monitoring, create a wrapper script:
#!/bin/bash
LOG_FILE="/var/log/logrotate_debug.log"
echo "$(date) - Starting logrotate" >> $LOG_FILE
/usr/sbin/logrotate -v /etc/logrotate.conf >> $LOG_FILE 2>&1
echo "$(date) - Completed logrotate" >> $LOG_FILE
Common issues to check when monitoring:
- Permission errors in /var/log/
- Missing postrotate scripts
- Incorrect file ownership
Example troubleshooting command:
sudo strace -f -o /tmp/logrotate.trace logrotate -f /etc/logrotate.conf
Add these directives to your config files for enhanced visibility:
# In /etc/logrotate.conf
missingok
notifempty
compress
create 0644 root root
sharedscripts
dateext
dateformat -%Y%m%d-%H%M%S
For production systems, consider integrating with monitoring tools:
# Nagios plugin example
#!/bin/bash
LAST_ROTATION=$(stat -c %Y /var/lib/logrotate/status)
CURRENT_TIME=$(date +%s)
DIFF=$(( (CURRENT_TIME - LAST_ROTATION) / 86400 ))
if [ $DIFF -gt 1 ]; then
echo "CRITICAL: logrotate hasn't run in $DIFF days"
exit 2
else
echo "OK: logrotate ran within $DIFF days"
exit 0
fi
Logrotate operates silently through cron jobs or systemd timers, making its activities invisible by default. The key configuration files are:
/etc/logrotate.conf # Main configuration /etc/logrotate.d/ # Application-specific configurations /var/lib/logrotate/status # Rotation history database
Force verbose output during manual runs with the -v
flag:
sudo logrotate -v /etc/logrotate.conf sudo logrotate -v /etc/logrotate.d/nginx
For permanent verbose logging, edit cron job in /etc/cron.daily/logrotate
:
#!/bin/sh /usr/sbin/logrotate -v /etc/logrotate.conf
Combine -d
(debug) and -f
(force) flags for simulation:
sudo logrotate -df /etc/logrotate.d/apache2
Output shows what would happen without actual rotation.
Configure rsyslog to capture logrotate activity by adding to /etc/rsyslog.conf
:
# Log logrotate messages to separate file :programname, isequal, "logrotate" /var/log/logrotate.log
Then restart rsyslog:
sudo systemctl restart rsyslog
Set up audit rules for comprehensive tracking:
# Monitor logrotate binary execution sudo auditctl -w /usr/sbin/logrotate -p x -k logrotate_trace # Monitor configuration changes sudo auditctl -w /etc/logrotate.conf -p wa -k logrotate_conf sudo auditctl -w /etc/logrotate.d/ -p wa -k logrotate_conf_dir
View logs with:
ausearch -k logrotate_trace | aureport -f -i
Create /usr/local/bin/logrotate-wrapper
:
#!/bin/bash { echo "=== Rotation started at $(date) ===" /usr/sbin/logrotate "$@" echo "=== Rotation completed with status $? ===" echo "Modified files:" find /var/log -type f -mmin -5 -ls } | tee -a /var/log/logrotate_audit.log
Make executable and modify cron jobs to use the wrapper:
sudo chmod +x /usr/local/bin/logrotate-wrapper
The status file records last rotation timestamps:
cat /var/lib/logrotate/status
Example parser script:
#!/usr/bin/python3 from datetime import datetime with open('/var/lib/logrotate/status') as f: for line in f: if line.startswith('log'): parts = line.split() last_rotated = datetime.fromtimestamp(int(parts[1])) print(f"{parts[0]}: last rotated {last_rotated}")
Missing rotations: Check cron is active:
systemctl status cron grep logrotate /var/log/syslog
Permission errors: Test with strace:
strace -f -o /tmp/logrotate.strace logrotate -vf /etc/logrotate.conf