1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
| send_dingding() { local title="${1}" local body=$(echo -e "${2}" | sed s@\n@\\n@g -) curl -qsk -o /dev/null -H 'Content-Type: application/json;charset=UTF-8' -d "$(printf "${DDPAYLOAD}" "${title}" "${title}" "${body}")" ${DDURL} }
send_pushbear() { local title="${1}" local body=$(echo -e "${2}" | sed s@\n@%0A@g -) curl -qsk -o /dev/null -d "$(printf "${FTPAYLOAD}" "${title}" "${body}")" ${FTURL} }
send() { local title="${1}" local body="${2}" case ${NOTIFY_TYPE} in dingding) send_dingding "${title}" "${body}" ;; pushbear) send_pushbear "${title}" "${body}" ;; all) send_dingding "${title}" "${body}" send_pushbear "${title}" "${body}" ;; esac }
getstatus() { echo $(cat status/${app}-svc.json) }
setstatus() { local svc=${1} local status=${2} lastStatus=${status} echo "${status:UP}">status/${svc}-svc.json }
getdowntime() { local svc=${1} echo $(cat downtime/${svc}-svc.json) }
setdowntime() { local svc=${1} echo "$(date +%s)">downtime/${svc}-svc.json }
getchecktime() { local svc=${1} echo $(cat checktime/${svc}-svc.json) }
setchecktime() { local svc=${1} local times=${2} checkTime=${times} echo "${times}">checktime/${svc}-svc.json }
down_check(){ local app=${1} local code=${2} if [[ "$(echo ${UPSTATUS} | grep ${code})" == "" ]]; then if [[ "${checkTime}" == "1" ]]; then setdowntime ${app} fi setchecktime ${app} $(( ${checkTime} + 1 )) if [[ "${lastStatus}" == "UP" ]] && [[ ${checkTime} > ${CHECKTIME} ]]; then setstatus ${app} "DOWN" send "${app} 宕机" "- 服务地址: [点击访问](${url})\n- 当前状态: ${code}\n- 请检查相关服务是否运行正常!\n- 时间: `date`" fi else setchecktime ${app} 1 fi }
up_check() { local app=${1} local code=${2} if [[ "$(echo ${UPSTATUS} | grep ${code})" != "" ]] && [[ "${lastStatus}" == "DOWN" ]]; then setstatus ${app} "UP" downtime=$(( $(date +%s) - $(getdowntime ${app}) )) send "${app} 恢复运行" "- 服务地址: [点击访问](${url})\n- 当前状态: ${code}\n- 宕机时长: ${downtime}秒\n- 时间: `date`" fi }
check_app() { local app=${1:?No Space APP} local url=${2:?No Space URL} local start=$(date +%s%N) local code=$(curl --request GET -Iqsw %{http_code} --connect-timeout 1 -m${TIMEOUT} -o/dev/null $url) delayTime=$(( ( $(date +%s%N) - ${start} ) / 1000000 )) checkTime=$(getchecktime ${app}) lastStatus=$(getstatus ${app}) down_check ${app} ${code} up_check ${app} ${code} echo "${app} STATUS: ${lastStatus} CODE: ${code} TIME: ${delayTime}ms" echo "{'name':'${app}','status':'${lastStatus}','code':'${code}','time':'${delayTime}','url':'${url}'},">temp/${app}-svc.json }
merge_result() { echo "">temp.json for svc in $(ls temp | grep svc.json); do cat temp/${svc}>>temp.json done echo "{'status':'200','data':[$(echo $(cat temp.json) | sed 's/.$//' -)],'msg':'OK'}">result.json sed -i s/\'/\"/g result.json }
main() { for app in ${!apps[*]}; do #这里可以丢到后台执行 但是可能会造成延时变大 check_app "${app}" "${apps[${app}]}" # & done wait merge_result echo '{"status":"200", "data":"'$(date +%s%N)'", "msg":"OK"}'>lastupdate.json echo "========== Check Time: $(date) ==========" }
init_config() { # 方糖自定义配置 https://pushbear.ftqq.com/admin FTURL=https://pushbear.ftqq.com/sub # 发送的Payload FTPAYLOAD="sendkey=${FT_KEY:?please config FT_KEY if you want use pushbear}&text=%s&desp=%s" # 钉钉自定义配置 DDURL=https://oapi.dingtalk.com/robot/send?access_token=${DD_KEY:?please config DD_KEY if you want use pushbear} # 发送的Payload DDPAYLOAD="{ \"msgtype\": \"markdown\", \"markdown\": { \"title\":\"%s\", \"text\":\"## %s\n%s\n- @${DD_MOBILE}\" }, \"at\": { \"atMobiles\": [ \"${DD_MOBILE}\" ], \"isAtAll\": false } }" }
init() { init_config # 清理缓存 rm -rf temp
# 初始化缓存目录 mkdir -p temp mkdir -p status mkdir -p downtime mkdir -p checktime
# 初始化状态MAP for app in ${!apps[*]}; do if [[ ! -f status/${app}-svc.json ]]; then echo "UP">status/${app}-svc.json fi done
# 初始化状态MAP for app in ${!apps[*]}; do if [[ ! -f checktime/${app}-svc.json ]]; then echo "0">checktime/${app}-svc.json fi done
# 循环检查服务状态 while true; do main sleep 5 done }
# 发送通知类型(可选 dingding[钉钉] pushbear[方糖] all[全部通知]) NOTIFY_TYPE='none' # 钉钉的发送Token DD_KEY='' # 需要@的手机号 DD_MOBILE='' # 方糖的Key 参考 https://pushbear.ftqq.com/admin FT_KEY='' # 定义UP状态的状态码 UPSTATUS='200 404' # 检查次数(异常连续超过这个次数则判定为DOWN) CHECKTIME=5 # 超时时间 TIMEOUT=3
# 定义服务MAP declare -A apps=( ["百度"]="https://www.baidu.com" ["Google"]="https://www.google.com" ["腾讯"]="https://www.qq.com" )
|