Shell脚本批量清理磁盘并钉钉推送通知

# BLOG:https://renwole.com/
# 以下脚本需要使用跳板机,或免密登录的机器批量执行,但也可改造单机执行,仅需将登录环节注释掉即可
#
tite=$(date "+%Y-%m-%d %H:%M:%S")
#hostnamelist="主机文件列表,一行一个IP,无需加双引号,例如;/mnt/renwolecom"
hostnamelist="/tmp/renwole_com"
# 清理失败的日志
renwole_com_disk_clean_log="/tmp/renwole_clean_failure.log"
#for envNamelist in ${Name[@]}; do
#       如果使用api接口获取主机列表,可以使用jq过滤josn,但请先安装jq 1.5 及以上版本,yum install epel && yum install jq ,epel源 Centos 7 默认版本1.5+,Centos6+版本均为1.3
#       curl -s 可通过url获取josn格式并通过jq过滤 | jq .data | jq -r .[].hostname
#done >$hostnamelist

# 钉钉通知,可根据if条件,指定多个不符合条件的通知
dingding_Notice()
{
    dingtalk_openapi_url="https://oapi.dingtalk.com"
    dingtalk_openapi_token="Token"
    if [[ "$(disk_use)" -ge 80 ]]; then
        curl ''$dingtalk_openapi_url'/robot/send?access_token='$dingtalk_openapi_token'' \
        -H 'Content-Type: application/json' \
        -d '{"msgtype": "text",
        "text": {
        "content": "系统日志已清理成功,但依旧使用空间依旧超过80%,请及时修复,机器是:'"$hostname"'"
    }
}'
   fi
}

# 检测机器是否能够登录,最大尝试5次,每次等待5秒(机器非常卡时,不做重试可能会出现误报情况)
check_login()
{
for i in $(seq 1 5); do
        [ $i -gt 1 ]
        $login_docker 2> /dev/null exit && antl=0 && break || antl=$?;
        sleep 5
done
echo $antl
}

# 登录容器后,检测相关命令是否可用,失败重试3次(某些机器非常卡,获取结果时会超时或为空的情况下重试)
check_login_command()
{
    for i in $(seq 1 3); do
        [[ $i -gt 1 ]]
        $login_docker >/dev/null 2>&1 "type du" >/dev/null 2>&1 && antc=0 && break || antc=$?;
        sleep 5
    done
    echo $antc
}

# 检测机器是否可正常联网,失败重试5次,每次重试等待10秒钟(可选项)
check_login_command_netwotk()
{
    # 如果网络异常,请到容器机器上查看此文件
    gateway="www.renwole.com"
    curl_timeout="curl -I -s --connect-timeout 16"
    for i in $(seq 1 5); do
        [[ $i -gt 1 ]]
        $login_docker "$curl_timeout $gateway 2>/dev/null -w %{http_code} | tail -n1" && antn=200 && break || antn="$?";
        sleep 10
    done
}

# 远程获取当前磁盘使用大小
disk_use()
{
    disk_uses=$($login_docker "df -P|sort -n|grep /dev |grep -v -E '(shm|tmp|boot)'")
    disk_status=$(echo $disk_uses | awk -F'[ %]+' '{print $5}')
    echo $disk_status
}

# 查找需要清理的日志目录及文件类型,并指定所需要清理的大小,这里指定20M
system_log_file()
{
    # 支持多个目录巡检,以空格分隔,后面的'/'一定要加
    renwole_log_dir=(/var/log/ /usr/local/nginx/logs/)
    for log_dirs in ${renwole_log_dir[*]}; do
        # 远程登录机器,并定义需要清理的文件类型,然后丢进黑洞
        $login_docker "find $log_dirs 2> /dev/null -type f -size +20M \( -name "*.data*" \
        -o -name "message*" -o -iname "wtm*" -o -name "vsa*" -o -name "secu*" \
        -o -name "cron*" -o -name "*.log*" \) -exec cp /dev/null {} \;"
    done
}

# 获取哪些目录或文件占用的空间大,并按大小排序,并获取前两行文件大小目录
system_file_size_check()
{
    home_file_size=$($login_docker "du -h --max-depth=5 /home/* | sort -h | tail -n5 |head -n2")
    echo $home_file_size
}

# 管道令牌 | 进程并发 
renwole_com="/tmp/renwolcomfile"
[ -e "$renwole_com" ] || mkfifo $renwole_com
exec 3<>$renwole_com
rm -rf $renwole_com

for ((i=1;i<=1000;i++)); do echo >&3
done

# 开始循环检测机器磁盘磁盘使用状态,不符合条件的则报警
for hostname in `cat $hostnamelist`; do
    read -u3
    {
        # 远程检测机器是否可登录,最大尝试30s,无法免密登录的机器则自动跳过登录
        login_docker="timeout 30 ssh -o BatchMode=yes $hostname"
        if [[ $(check_login) -ne 0 ]]; then
            echo "容器登录失败 $hostname" >>$renwole_com_disk_clean_log
            # 符合条件终止本次循环,继续下次循环
            echo >&3
            continue 
        fi

        if [[ $(check_login_command) -ne 0 ]]; then
            echo "无法找到du命令 $hostname" >>$renwole_com_disk_clean_log
            echo >&3
            continue
        fi

        if [[ $(disk_use)  -gt 80 ]]; then
            # 如果磁盘使用率大于80%,触发清理
            system_log_file
        else
            echo "当前磁盘使用 $(disk_use)% 未超 80%,$hostname"
            echo >&3
            continue
        fi

        if [[ $(disk_use)  -gt 80 ]]; then
            echo "$tite $hostname 磁盘清理失败,当前使用率为 $(disk_use)%,文件大小:$(system_file_size_check)" >>$renwole_com_disk_clean_log
            echo "清理磁盘失败,当前使用率为 $(disk_use)% $hostname"
        else
            echo "清理磁盘成功,清理后使用率 $(disk_use)% $hostname"
        fi
        echo >&3
    }&
done
wait
# 关闭
exec 3<&-
exec 3>&-
# 是否开启钉钉通知,默认关闭
# dingding_Notice