Add disk full incident response toolkit
This commit is contained in:
+97
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00_env.sh
|
||||
. "$SCRIPT_DIR/00_env.sh"
|
||||
|
||||
EXECUTE=false
|
||||
LOG_PATH="/var/log"
|
||||
DAYS_OLD=14
|
||||
|
||||
usage() {
|
||||
printf 'Usage: %s [--path <path>] [--days-old <N>] [--execute]\n' "$(basename "$0")"
|
||||
}
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--path) LOG_PATH="${2:-}"; shift 2 ;;
|
||||
--days-old) DAYS_OLD="${2:-}"; shift 2 ;;
|
||||
--execute) EXECUTE=true; DRY_RUN=false; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) critical "Unknown argument: $1"; usage; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! [[ "$DAYS_OLD" =~ ^[0-9]+$ ]] || (( DAYS_OLD < 1 )); then
|
||||
critical "--days-old must be a positive integer"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
validate_path "$LOG_PATH" || exit 2
|
||||
require_cmd find || exit 1
|
||||
require_cmd sort || exit 1
|
||||
require_cmd xargs || true
|
||||
|
||||
section "Large Log Files In $LOG_PATH"
|
||||
find "$LOG_PATH" -xdev -type f \( -name '*.log' -o -name '*log' -o -name 'messages*' -o -name 'syslog*' \) -size +100M -printf '%s\t%p\n' 2>/dev/null |
|
||||
sort -rn |
|
||||
awk '
|
||||
function human(bytes) {
|
||||
split("B KB MB GB TB", unit)
|
||||
size = bytes
|
||||
idx = 1
|
||||
while (size >= 1024 && idx < 5) {
|
||||
size = size / 1024
|
||||
idx++
|
||||
}
|
||||
return sprintf("%.1f%s", size, unit[idx])
|
||||
}
|
||||
{ size = $1; $1 = ""; sub(/^\t/, ""); printf "%10s %s\n", human(size), $0 }
|
||||
' | tee -a "$LOG_FILE"
|
||||
|
||||
section "Old Rotated Logs Eligible For Review"
|
||||
mapfile -t rotated_logs < <(
|
||||
find "$LOG_PATH" -xdev -type f \
|
||||
\( -name '*.gz' -o -name '*.1' -o -name '*.old' -o -name '*.bz2' -o -name '*.xz' \) \
|
||||
-mtime +"$DAYS_OLD" -print 2>/dev/null | sort
|
||||
)
|
||||
|
||||
if [[ "${#rotated_logs[@]}" -eq 0 ]]; then
|
||||
ok "No old rotated logs found under $LOG_PATH with age greater than $DAYS_OLD days."
|
||||
else
|
||||
printf '%s\n' "${rotated_logs[@]}" | tee -a "$LOG_FILE"
|
||||
fi
|
||||
|
||||
section "Suggested Cleanup Commands"
|
||||
cat <<SUGGESTIONS | tee -a "$LOG_FILE"
|
||||
# Review large active logs before truncating. Prefer application-aware log rotation:
|
||||
logrotate -d /etc/logrotate.conf
|
||||
|
||||
# Remove old rotated logs only after retention approval:
|
||||
$(basename "$0") --path "$LOG_PATH" --days-old "$DAYS_OLD" --execute
|
||||
SUGGESTIONS
|
||||
|
||||
if [[ "$EXECUTE" != "true" ]]; then
|
||||
ok "Safe mode. No logs were removed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${#rotated_logs[@]}" -eq 0 ]]; then
|
||||
ok "Execution requested, but there are no eligible old rotated logs to remove."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
confirm_execute "remove old rotated logs from $LOG_PATH"
|
||||
|
||||
for file in "${rotated_logs[@]}"; do
|
||||
if [[ -f "$file" && ! -L "$file" ]]; then
|
||||
run_cmd rm -f -- "$file"
|
||||
else
|
||||
warning "Skipped non-regular file or symlink: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
ok "Old rotated log cleanup completed."
|
||||
Reference in New Issue
Block a user