热衷于分享各种干货知识,大家有想看或者想学的可以评论区留言,秉承着“开源知识来源于互联网,回归于互联网”的理念,分享一些日常工作中能用到或者比较重要的内容,希望大家能够喜欢,不足之处请大家多提宝贵地意见,我们一起提升,守住自己的饭碗。
正文开始
脚本内容:
#!/bin/bash
set -eo pipefail
# ====================== 全局配置参数 ======================
LOG_DIR="/var/log" # 主要清理目录(可修改为业务日志路径)
KEEP_DAYS=7 # 常规清理保留天数
DISK_THRESHOLD=75 # 基础触发阈值(百分比)
SAFETY_LOCK="/tmp/disk_clean.lock"# 安全锁文件路径
ALERT_LEVEL=80 # 告警触发阈值(百分比)
# 多级清理策略(按阈值升序排列)
declare -A CLEAN_LEVELS=(
[75]="standard" # 75%触发常规清理(保留N天日志)
[85]="deep" # 85%触发深度清理(保留关键日志)
[95]="emergency"# 95%触发紧急清理(仅保留当天日志)
)
# 全局文件白名单(支持通配符)
PROTECTED_FILES=(
"/var/log/secure"
"/var/log/auth.log"
"/opt/app/config/*.log"
"/data/transaction_*.log"
)
# 通知配置(需自行填写)
DINGTALK_TOKEN="your_dingtalk_token"
MAIL_RECIPIENT="admin@example.com"
# ====================== 核心功能函数 ======================
# 1. 磁盘状态感知系统
get_log_partition() {
df -P "$LOG_DIR" | awk 'END{print $1}'
}
get_disk_usage() {
local partition=$(get_log_partition)
df -P "$partition" | awk 'NR==2{gsub(/%/,"");print $5,$6}'
}
# 2. 安全沙箱机制
apply_whitelist() {
local find_cmd="find \"$LOG_DIR\" -type f"
for file in"${PROTECTED_FILES[@]}"; do
find_cmd+=" ! -path \"$file\""
done
echo"$find_cmd"
}
simulate_clean() {
local find_cmd=$(apply_whitelist)
local clean_type=$1
case$clean_typein
"standard") find_cmd+=" -name '*.log' -mtime +$KEEP_DAYS" ;;
"deep") find_cmd+=" \( -name 'catalina.out' -o -name 'access.log' \) -mtime +7" ;;
"emergency") find_cmd+=" ! -name '*.gz' -mtime +0" ;;
esac
local total_size=0
while IFS= read -r -d $'\0' file; do
((total_size += $(stat -c%s "$file" 2>/dev/null || echo 0)))
done < <($find_cmd -print0 2>/dev/null)
echo"预计释放空间: $(numfmt --to=iec <<<"$total_size")"
}
# 3. 多级清理策略
standard_clean() {
local find_cmd=$(apply_whitelist)
$find_cmd -type f -name "*.log" -mtime +$KEEP_DAYS -print | xargs -r rm -v
}
deep_clean() {
local find_cmd=$(apply_whitelist)
$find_cmd -type f \( -name "catalina.out" -o -name "access.log" \) -mtime +7 -print | xargs -r rm -v
}
emergency_clean() {
local find_cmd=$(apply_whitelist)
$find_cmd -type f ! -name "*.gz" -mtime +0 -print | xargs -r rm -v
auto_archive # 紧急清理后自动压缩剩余日志
}
# 4. 日志归档与优化
auto_archive() {
local find_cmd=$(apply_whitelist)
$find_cmd -type f -mtime +3 ! -name "*.gz" -exec gzip -9 {} \;
}
# 5. 告警通知系统
send_alert() {
local usage=$1
local clean_type=$2
local partition=$(get_log_partition)
local hostname=$(hostname)
local message="🚨 磁盘告警通知\n服务器: $hostname\n监控分区: $partition\n当前使用率: ${usage}%\n触发策略: $clean_type"
# 钉钉通知
if [ -n "$DINGTALK_TOKEN" ]; then
curl -s "https://oapi.dingtalk.com/robot/send?access_token=$DINGTALK_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"msgtype\": \"text\",\"text\": {\"content\": \"$message\"}}" >/dev/null
fi
# 邮件通知
if [ -n "$MAIL_RECIPIENT" ]; then
echo"$message" | mail -s "磁盘告警通知""$MAIL_RECIPIENT"
fi
}
# 6. 报告生成系统
generate_report() {
local start_time=$1
local end_time=$2
local freed_space=$3
local clean_type=$4
echo -e "\n================ 磁盘清理报告 ================"
echo"▶ 执行时间 : $(date -d "@$start_time" +"%Y-%m-%d %H:%M:%S") 至 $(date -d "@$end_time" +"%Y-%m-%d %H:%M:%S")"
echo"▶ 主机名称 : $(hostname)"
echo"▶ 目标分区 : $(get_log_partition)"
echo"▶ 清理前使用率: ${pre_usage}%"
echo"▶ 清理后使用率: ${post_usage}%"
echo"▶ 触发策略 : $clean_type"
echo"▶ 释放空间 : $freed_space"
echo"▶ 保护文件 : ${#PROTECTED_FILES[@]}个"
echo"=============================================="
}
# ====================== 主执行逻辑 ======================
main() {
# 安全锁检查
if [ -f "$SAFETY_LOCK" ]; then
echo"⚠️ 检测到安全锁,上次清理未完成或异常终止,跳过本次执行"
exit 1
fi
touch"$SAFETY_LOCK"
# 初始化变量
local start_time=$(date +%s)
local partition=$(get_log_partition)
local usage_info=$(get_disk_usage)
local pre_usage=$(echo"$usage_info" | awk '{print $1}')
local mount_point=$(echo"$usage_info" | awk '{print $2}')
local clean_type=""
local freed_space=0
# 执行清理策略
for threshold in $(echo"${!CLEAN_LEVELS[@]}" | tr' ''\n' | sort -n); do
if [ "$pre_usage" -ge "$threshold" ]; then
clean_type="${CLEAN_LEVELS[$threshold]}"
echo"🚀 触发$clean_type清理策略(阈值: ${threshold}%)"
# 模拟清理(测试模式)
if [ "$1" = "--dry-run" ]; then
simulate_clean "$clean_type"
break
fi
# 执行实际清理
case$clean_typein
"standard") standard_clean ;;
"deep") deep_clean ;;
"emergency") emergency_clean ;;
esac
break
fi
done
# 清理后状态检查
local post_usage=$(get_disk_usage | awk '{print $1}')
freed_space=$(df -P "$partition" | awk "NR==2{print \$4 - $post_usage*1024/100}") # 近似计算释放空间
freed_space_human=$(numfmt --to=iec <<<"$((freed_space * 1024))")
# 生成报告
local end_time=$(date +%s)
generate_report "$start_time""$end_time""$freed_space_human""$clean_type"
# 发送告警(超过告警阈值时)
if [ "$pre_usage" -ge "$ALERT_LEVEL" ]; then
send_alert "$pre_usage""$clean_type"
fi
# 清理安全锁
rm -f "$SAFETY_LOCK"
}
# ====================== 执行入口 ======================
case$1in
--dry-run)
echo"⚠️ 运行模拟清理模式(不会实际删除文件)"
main "--dry-run"
;;
--monitor)
# 监控模式(仅检查不清理)
local usage=$(get_disk_usage | awk '{print $1}')
if [ "$usage" -ge "$ALERT_LEVEL" ]; then
send_alert "$usage""监控预警"
fi
;;
*)
main
;;
esac
脚本特性说明:
1. 安全机制: • 采用安全锁防止重复执行( /tmp/disk_clean.lock
)• 白名单保护关键文件(支持通配符匹配) • 模拟清理模式( --dry-run
参数)2. 智能策略: • 三级渐进式清理(75%/85%/95%阈值) • 自动日志压缩(清理后自动压缩3天前未压缩日志) • 多目录并行处理(可扩展 LOG_DIRS
数组实现)3. 企业级支持: • 钉钉/邮件多通道告警 • 详细清理报告(包含时间、空间、策略等信息) • 监控模式( --monitor
参数用于定时检测)4. 兼容性优化: • 使用 set -eo pipefail
增强错误处理• 兼容 df
/find
命令的不同系统输出格式• 支持通配符白名单( /opt/app/config/*.log
)
使用说明:
1. 参数配置:修改顶部全局配置参数( LOG_DIR
/KEEP_DAYS
/通知信息等)2. 测试执行: # 模拟清理(安全模式)
./disk_clean.sh --dry-run
# 实际清理
./disk_clean.sh3. 定时任务: # 每日凌晨执行清理(写入crontab)
0 0 * * * path/to/disk_clean.sh > var/log/disk_clean.log 2>&1
# 每30分钟监控告警
*/30 * * * * path/to/disk_clean.sh --monitor4. 验证检查: # 查看实时清理日志
tail -f var/log/disk_clean.log
# 验证白名单保护
find "$LOG_DIR" -type f -name "secure" -ls
# 压力测试(模拟满盘)
fallocate -l 10G "$LOG_DIR/stress_test.log"
注意事项:
• 首次运行建议使用 --dry-run
模式验证清理范围• 生产环境部署前需根据业务日志特性调整白名单 • 钉钉token和邮件配置需要提前申请 • 建议配合监控系统(Prometheus/Grafana)实现可视化 • 定期执行 fallocate
压力测试验证清理流程有效性
文中的概念来源于互联网,如有侵权,请联系我删除。
欢迎关注公众号:小周的数据库进阶之路,一起交流数据库、中间件和云计算等技术。如果觉得读完本文有收获,可以转发给其他朋友,大家一起学习进步!感兴趣的朋友可以加我微信,拉您进群与业界的大佬们一起交流学习。
文章转载自小周的数据库进阶之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




