#!/usr/bin/env bash # Author : Allan Christensen # First Created : 12-03-2001 (DD-MM-YYYY) # Description : Clears rotated logfiles and reports large unrotated logs in /var/log # License : MIT License # # Are we root # if [[ $(id -u) -ne 0 ]]; then echo "" && echo "Must be root or use sudo" && echo "" ; exit ; fi # # Safety controls # # # Dry run mode # # true = simulate deletions, nothing is removed # false = real run (cron) # dryrun=true # # Extended rotated log cleanup # # Controls deletion of non-logrotate files like: # app.log.1234 # installer-debug.log.9876 # # false = report only (safe default) # true = delete during real runs (dryrun must also be false) # extended_cleanup=false # # Define variables # logdir="/var/log" # # Warning threshold for unrotated logs (megabytes) # warning=200 resultlog="/var/log/clear-log-files.log" # # Initialize log file # : > "$resultlog" chmod 644 "$resultlog" { echo "Clear logfiles run : $(date)" echo "Log Directory : $logdir" echo "Warning threshold : ${warning} MB" echo "Dry run : $dryrun" echo "Extended cleanup : $extended_cleanup" echo "" } >> "$resultlog" # # Safety check # if [[ ! "$logdir" =~ ^/var/log(/|$) ]]; then echo "ERROR: Refusing to operate outside /var/log: $logdir" >> "$resultlog" exit 1 fi # # Pass 1 — classic rotated logs (logrotate style) # echo "Classic rotated log files:" >> "$resultlog" found=false while IFS= read -r file; do found=true if [[ "$dryrun" == true ]]; then echo " $file (dry-run)" >> "$resultlog" else echo " $file" >> "$resultlog" rm -f "$file" fi done < <( find "$logdir" -type f \ \( \ -name "*.log.[1-9]" -o -name "*.log.[1-9][0-9]" \ -o -name "*.log.[1-9].gz" -o -name "*.log.[1-9][0-9].gz" \ -o -name "*.log.[1-9].xz" -o -name "*.log.[1-9][0-9].xz" \ -o -name "*.log.[1-9].bz2" -o -name "*.log.[1-9][0-9].bz2" \ -o -name "*.log.[1-9].zst" -o -name "*.log.[1-9][0-9].zst" \ \ -o -name "syslog.[1-9]" -o -name "syslog.[1-9][0-9]" \ -o -name "syslog.[1-9].gz" -o -name "syslog.[1-9][0-9].gz" \ -o -name "syslog.[1-9].xz" -o -name "syslog.[1-9][0-9].xz" \ -o -name "syslog.[1-9].bz2" -o -name "syslog.[1-9][0-9].bz2" \ -o -name "syslog.[1-9].zst" -o -name "syslog.[1-9][0-9].zst" \ \) \ ! -name "clear-log-files.log*" \ 2>/dev/null ) [[ "$found" == false ]] && echo " None" >> "$resultlog" echo "" >> "$resultlog" # # Pass 2 — extended rotated logs (non-standard) # echo "Extended rotated log files:" >> "$resultlog" found=false while IFS= read -r file; do found=true if [[ "$dryrun" == true || "$extended_cleanup" == false ]]; then echo " $file (reported only)" >> "$resultlog" else echo " $file" >> "$resultlog" rm -f "$file" fi done < <( find "$logdir" -type f \ -name "*.log.*" \ ! -name "*.log.[1-9]*" \ ! -name "clear-log-files.log*" \ 2>/dev/null ) [[ "$found" == false ]] && echo " None" >> "$resultlog" echo "" >> "$resultlog" # # Detect large unrotated logs # echo "Large unrotated log files detected:" >> "$resultlog" found=false while IFS= read -r file; do size_mb=$(( $(stat -c %s "$file") / 1024 / 1024 )) if (( size_mb >= warning )); then echo " WARNING: $file (${size_mb} MB)" >> "$resultlog" found=true fi done < <( find "$logdir" -type f \ -name "*.log" \ ! -name "clear-log-files.log" \ 2>/dev/null ) [[ "$found" == false ]] && echo " None" >> "$resultlog" echo "" >> "$resultlog" # # End of script #