How to Automate Log Cleanup with Logrotate and Scripts
Unmanaged log files can fill your Breeze instance disk, causing application crashes and service outages. Logrotate is a Linux utility that automatically rotates, compresses, and removes old log files, keeping your system healthy.
How Logrotate Works
Logrotate runs daily via cron (or a systemd timer). It reads configuration files to determine which logs to rotate and how:
# Check if logrotate is installed
logrotate --version
# Main configuration
cat /etc/logrotate.conf
# Application-specific configs are in /etc/logrotate.d/
ls /etc/logrotate.d/
Creating a Custom Logrotate Configuration
Create a configuration for your application logs:
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily # Rotate daily
missingok # Don't error if log file is missing
rotate 14 # Keep 14 rotated files
compress # Compress rotated files with gzip
delaycompress # Delay compression by one rotation
notifempty # Don't rotate empty files
create 0640 www-data adm # Set permissions on new log file
sharedscripts # Run scripts once, not per matched file
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
Common Logrotate Directives
| Directive | Description |
|---|---|
daily / weekly / monthly | Rotation frequency |
rotate N | Keep N rotated files before deleting |
compress | Compress old logs with gzip |
delaycompress | Delay compression to the next rotation cycle |
size 100M | Rotate when file exceeds 100 MB |
maxsize 500M | Rotate when size exceeds limit, even between scheduled rotations |
minsize 10M | Only rotate if file is at least 10 MB |
copytruncate | Copy then truncate instead of moving (for apps that hold file handles) |
dateext | Use date as extension instead of numbers |
Nginx Log Rotation Example
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 $(cat /var/run/nginx.pid)
fi
endscript
}
Custom Cleanup Script
For logs not managed by logrotate, write a cleanup script:
#!/usr/bin/env bash
# /usr/local/bin/log-cleanup.sh
set -euo pipefail
LOG_DIRS=(
"/var/log/myapp"
"/home/deploy/logs"
"/var/log/custom"
)
DAYS_TO_KEEP=30
for dir in "${LOG_DIRS[@]}"; do
if [[ -d "$dir" ]]; then
# Delete logs older than retention period
find "$dir" -name "*.log.gz" -mtime +"$DAYS_TO_KEEP" -delete
find "$dir" -name "*.log.[0-9]*" -mtime +"$DAYS_TO_KEEP" -delete
# Report disk usage
echo "$(date '+%Y-%m-%d %H:%M:%S') - $dir: $(du -sh "$dir" | cut -f1)"
fi
done
# Clean journal logs older than 7 days
journalctl --vacuum-time=7d
Testing and Debugging
# Test configuration without actually rotating
sudo logrotate -d /etc/logrotate.d/myapp
# Force rotation (for testing)
sudo logrotate -f /etc/logrotate.d/myapp
# Check logrotate state file
cat /var/lib/logrotate/status
Best Practices
- Use logrotate for standard logs — it handles rotation, compression, and cleanup in one tool
- Set size limits — combine time-based and size-based rotation with
maxsize - Use copytruncate for stubborn apps — works with applications that keep log files open
- Monitor disk usage — set up alerts when
/var/logexceeds a threshold - Clean journal logs — systemd journal can grow large; use
journalctl --vacuum-time - Test configurations — always run with
-d(debug) before deploying new configs
Proper log rotation keeps your Breeze instances running smoothly by preventing disk exhaustion while preserving enough log history for debugging.