Automated Log Cleanup Script for /var/log on Linux
Shell script to automatically clean up old log files in /var/log, including compression, rotation, and size-based cleanup with logging.
Automated Log Cleanup Script for /var/log on Linux
Log files grow unbounded and can fill up your disk if not managed properly. I wrote a cleanup script after a production server hit 100% disk usage due to accumulated logs. This script handles rotation, compression, and size-based cleanup.
Environment
- OS: Ubuntu 22.04 LTS
- Problem: /var/log grew to 15GB, consuming 75% of root partition
- Solution: Automated cleanup script with cron job
$ du -sh /var/log
15G /var/log
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 18G 2G 90% /The Problem
$ sudo du -sh /var/log/*
5.2G /var/log/syslog
4.1G /var/log/syslog.1
3.8G /var/log/nginx
1.2G /var/log/journal
800M /var/log/aptMultiple large log files accumulating without rotation.
Solution
Basic Cleanup Script
#!/bin/bash
# /usr/local/bin/log-cleanup.sh
# Automated log cleanup for /var/log
set -euo pipefail
LOG_DIR="/var/log"
LOG_RETENTION_DAYS=30
COMPRESSED_RETENTION_DAYS=90
MAX_LOG_SIZE_MB=100
LOGFILE="/var/log/log-cleanup.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOGFILE"
}
log_message "Starting log cleanup..."
# 1. Rotate large log files
find "$LOG_DIR" -type f -name "*.log" -size +${MAX_LOG_SIZE_MB}M -exec bash -c '
for file do
if [ -f "$file" ]; then
timestamp=$(date +%Y%m%d_%H%M%S)
gzip -9 "$file"
mv "${file}.gz" "${file}.${timestamp}.gz"
touch "$file"
log_message "Rotated: $file"
fi
done
' _ {} +
# 2. Remove old uncompressed logs
find "$LOG_DIR" -type f -name "*.log" -mtime +${LOG_RETENTION_DAYS} -delete
log_message "Removed uncompressed logs older than ${LOG_RETENTION_DAYS} days"
# 3. Remove old compressed logs
find "$LOG_DIR" -type f \( -name "*.gz" -o -name "*.bz2" -o -name "*.xz" \) \
-mtime +${COMPRESSED_RETENTION_DAYS} -delete
log_message "Removed compressed logs older than ${COMPRESSED_RETENTION_DAYS} days"
# 4. Clean journal logs
journalctl --vacuum-time=30d --vacuum-size=500M
log_message "Cleaned journal logs"
# 5. Clean apt cache
apt-get clean
log_message "Cleaned apt cache"
# 6. Clean tmp files
find /tmp -type f -atime +7 -delete 2>/dev/null || true
log_message "Cleaned /tmp"
# Report disk usage after cleanup
DISK_USAGE=$(df / --output=pcent | tail -1 | tr -d '% ')
log_message "Disk usage after cleanup: ${DISK_USAGE}%"
log_message "Log cleanup completed"Advanced Cleanup Script with Email Alerts
#!/bin/bash
# /usr/local/bin/log-cleanup-advanced.sh
set -euo pipefail
LOG_RETENTION_DAYS=30
ALERT_THRESHOLD=80
ADMIN_EMAIL="admin@example.com"
HOSTNAME=$(hostname)
# Calculate total log size before cleanup
BEFORE_SIZE=$(du -sh /var/log 2>/dev/null | cut -f1)
# Run cleanup
/usr/local/bin/log-cleanup.sh
# Calculate size after
AFTER_SIZE=$(du -sh /var/log 2>/dev/null | cut -f1)
DISK_USAGE=$(df / --output=pcent | tail -1 | tr -d '% ')
# Send alert if disk usage is still high
if [ "$DISK_USAGE" -gt "$ALERT_THRESHOLD" ]; then
echo "Disk usage on ${HOSTNAME} is ${DISK_USAGE}% after cleanup.
Before: ${BEFORE_SIZE}
After: ${AFTER_SIZE}" | mail -s "Disk Alert: ${HOSTNAME}" "$ADMIN_EMAIL"
fiMake Scripts Executable and Schedule
# Make executable
$ sudo chmod +x /usr/local/bin/log-cleanup.sh
$ sudo chmod +x /usr/local/bin/log-cleanup-advanced.sh
# Schedule with cron
$ sudo crontab -e
# Add these lines:
# Run basic cleanup daily at 2 AM
0 2 * * * /usr/local/bin/log-cleanup.sh
# Run advanced cleanup weekly on Sunday
0 3 * * 0 /usr/local/bin/log-cleanup-advanced.shConfigure logrotate
# Create custom logrotate config
$ sudo cat > /etc/logrotate.d/custom << 'EOF'
/var/log/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
size 100M
create 0640 root adm
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate 2>/dev/null || true
endscript
}
EOF
# Test logrotate
$ sudo logrotate -d /etc/logrotate.d/customVerify Cleanup
# Check disk usage
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 8G 12G 40% /
# Check /var/log size
$ du -sh /var/log
3G /var/log
# Verify cron job is scheduled
$ sudo crontab -l | grep log-cleanup
0 2 * * * /usr/local/bin/log-cleanup.shLessons Learned
- Always test cleanup scripts on non-production systems first.
- Use
set -euo pipefailto catch errors early. - Monitor disk usage after implementing cleanup to verify it works.
- Keep compressed logs longer than uncompressed for debugging.
- Log cleanup activity to a separate file for auditing.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.