本站之前基本上都是使用site-status+UptimeRobot这样的监控方案,算是常用且成熟的一种方式了,界面也美观,但问题是,它太大了,几个js+css轻松干到500k。放在本地占用带宽是个问题,放在oss上如果被无聊的人拿来做坏事也不是很好玩,于是还是要从源头解决,换用一个更小的方案,即目前的tinystatus方案。
官方提供的demo:here
tinystatus的构成包括三个文件:tinystatus
、checks.csv
、incidents.txt
。
checks.csv
是需要监控的服务列表,格式为:
Command, Expected Code, Status Text, Host to check
- Command:监控服务类型,支持http ping port三种类型,可指定使用IPv4或IPv6监控,比如http4 http6。
- Expected Code:返回的正常值,比如http服务返回200时为正常
- Status Text:服务的名称
Host to check:服务的链接/IP/端口
incidents.txt
可以手工写入事件等信息,没有格式要求。tinystatus
即主程序,一个简单的脚本,通过
tinystatus
即主程序,很简单的一个脚本,作用就是通过nc
curl
ping
三个命令实现对checks.csv
内进行监控然后通过内置的html模版输出成html文件,因此它只有一个用法:
./tinystatus
或者
./tinystatus > index.html
输出的html大小在3k左右,可以说是非常小了。
原版非常简单,我在原版的基础上稍微美化了下:
#!/usr/bin/env sh
# Configuration variables
TITLE="狼的状态板 3.0"
HEADER="全局状态"
CHECKS_FILE="${1:-checks.csv}" #读取监控列表
INCIDENTS_FILE="${2:-incidents.txt}" #读取公告文件
OUTAGE_RC=false
TIMEOUT=10
USER_AGENT="User-Agent: Mozilla/5.0 (X11; Linux x86_64; Debian) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
TMP_DIR="$(mktemp -d)"
command_exists(){
if ! command -v "${1}" >/dev/null 2>&1; then
echo >&2 "错误:未找到组件 ${1} ,请自行安装"
exit 1
fi
}
get_element(){
echo "${2}" | awk -v col="${1}" -F',' '{gsub(/^[ \t]+|[ \t]+$/, "", $col); print $col}'
}
check(){
check="${1}"
host="${2}"
name="${3}"
expected_rc="${4}"
id="${5}"
ipversion="$(echo "${check}" | grep -o '[46]$')"
case "${check}" in
http*)
rc="$(curl -${ipversion}sSkLo /dev/null -H "${USER_AGENT}" -m "${TIMEOUT}" -w "%{http_code}" "${host}" 2> "${TMP_DIR}/${id}.ko.info")"
if [ -s "${TMP_DIR}/${id}.ko.info" ]; then
sed -e 's,curl: ([0-9]*) ,,' -i "${TMP_DIR}/${id}.ko.info"
else
echo "Status code: ${rc}, expected: ${expected_rc}" > "${TMP_DIR}/${id}.ko.info"
fi;;
ping*)
ping -${ipversion}W "${TIMEOUT}" -c 1 "${host}" >/dev/null 2>&1
rc=$?
[ "${rc}" -ne "${expected_rc}" ] && echo 'Host unreachable' > "${TMP_DIR}/${id}.ko.info";;
port*)
error="$(nc -${ipversion}w "${TIMEOUT}" -zv ${host} 2>&1)"
rc=$?
[ "${rc}" -ne "${expected_rc}" ] && echo "${error}" | sed -e 's,nc: ,,' > "${TMP_DIR}/${id}.ko.info";;
esac
# verity status and write files
if [ "${rc}" -eq "${expected_rc}" ]; then
echo "${name}" > "${TMP_DIR}/${id}.ok"
else
echo "${name}" > "${TMP_DIR}/${id}.ko"
fi
}
# Verify requirements
command_exists 'curl'
command_exists 'nc'
command_exists 'ping'
mkdir -p "${TMP_DIR}" || exit 1
# Execute checks
id=0
while IFS="$(printf '\n')" read -r line; do
check="$(get_element 1 "${line}")"
code="$(get_element 2 "${line}")"
name="$(get_element 3 "${line}")"
host="$(get_element 4 "${line}")"
check "${check}" "${host}" "${name}" "${code}" "${id}" &
: $((id++))
done < "${CHECKS_FILE}"
wait
OUTAGES_COUNT="$(ls "${TMP_DIR}/"*.ko | wc -l)"
# Generate HTML
cat << EOF
<!DOCTYPE html><html lang="zh_CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>${TITLE}</title><style>
body { font-family: segoe ui,Roboto,Oxygen-Sans,Ubuntu,Cantarell,helvetica neue,Verdana,sans-serif;background-image: url('background.png');background-size: cover;background-position: center;background-repeat: no-repeat;}
h1 { margin-top: 30px; }
ul { padding: 0px; }
li { list-style: none; margin-bottom: 2px; padding: 5px; border-bottom: 1px solid #ddd; }
.container { max-width: 600px; width: 100%; margin: 15px auto; background-color: rgba(0, 0, 0, 0.5); padding: 20px; border-radius: 10px; color: white; }
.panel { text-align: center; padding: 10px; border: 0px; border-radius: 5px; }
.failed-bg { color: white; background-color: #E25D6A; }
.success-bg { color: white; background-color: #52B86A; }
.failed { color: #E25D6A; }
.success { color: #52B86A; }
.small { font-size: 80%; }
.status { float: right; }
.footer { text-align: center; margin-top: 20px; }
.footer a { text-decoration: none; color: #52B86A; text-shadow: 1px 1px 2px black; }
</style></head>
<body>
<div class='container'>
<h1>${HEADER}</h1>
EOF
if [ "${OUTAGES_COUNT}" -ne 0 ]; then
echo "<ul><li class='panel failed-bg'>${OUTAGES_COUNT} 个服务中断</li></ul>"
else
echo "<ul><li class='panel success-bg'>所有服务运行正常</li></ul>"
fi
cat << EOF
<h1>服务</h1>
<ul>
EOF
for file in "${TMP_DIR}/"*.ko; do
[ -e "${file}" ] || continue
echo "<li>$(cat "${file}") <span class='small failed'>($(cat "${file}.info"))</span><span class='status failed'>已中断</span></li>"
done
for file in "${TMP_DIR}/"*.ok; do
[ -e "${file}" ] || continue
echo "<li>$(cat "${file}") <span class='status success'>正常运作</span></li>"
done
cat << EOF
</ul>
<p class=small> 最后检查时间: $(date +%FT%T%z)</p>
EOF
if [ -f "${INCIDENTS_FILE}" ]; then
echo '<h1>事件</h1>'
if [ -s "${INCIDENTS_FILE}" ]; then
sed 's|^\(.*\)$|<p>\1</p>|' "${INCIDENTS_FILE}"
else
echo '<p>没有事件需要通报 ;)</p>'
fi
fi
cat <<EOF
</div>
<div class='footer'>
<a href="https://blog.tama.guru">公告板</a> |
<a href="https://box.tama.guru">提问箱</a> |
<a href="https://share.tama.guru">盘</a>
</div>
</body></html>
EOF
# Cleanup and exit
rm -r "${TMP_DIR}" 2>/dev/null
if "${OUTAGE_RC}"; then
exit "${OUTAGES_COUNT}"
fi
主要就是汉化了添加了背景,添加了一点css和footer。
需要注意的是nc命令可能不是默认安装的,需要手工安装netcat
才能正常运行。
最后可以通过crontab来定时执行,实现自动刷新:
10 * * * * $tinystatus目录/tinystatus > $网页目录/index.html
又或者可以直接整合进脚本里。
1 条评论
测试评论返回