2021-03-27 22:27:40 +00:00
|
|
|
#!/usr/bin/env sh
|
|
|
|
|
|
|
|
title=tinystatus
|
|
|
|
timeout=10
|
2021-03-28 20:20:27 +00:00
|
|
|
tmp="$(mktemp -d)"
|
2021-03-29 15:25:25 +00:00
|
|
|
checkfile="${1:-checks.csv}"
|
2021-03-28 20:14:08 +00:00
|
|
|
incidentsfile="${2:-incidents.list}"
|
2021-03-28 20:20:27 +00:00
|
|
|
useragent="User-Agent: Mozilla/5.0 (X11; Linux x86_64; Debian) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
|
2021-03-27 22:27:40 +00:00
|
|
|
|
|
|
|
command_exists(){
|
|
|
|
if ! command -v "${1}" >/dev/null 2>&1; then
|
|
|
|
echo >&2 "Error: ${1} missing. Please install it"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
get_element(){
|
2021-03-29 15:25:25 +00:00
|
|
|
echo "${2}" | awk -v col="${1}" -F',' '{gsub(/^[ \t]+|[ \t]+$/, "", $col); print $col}'
|
2021-03-27 22:27:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
check(){
|
|
|
|
ctype="${1}"
|
|
|
|
host="${2}"
|
|
|
|
name="${3}"
|
|
|
|
expectedcode="${4}"
|
|
|
|
|
2021-03-29 18:55:23 +00:00
|
|
|
IPv="$(echo "${ctype}" | grep -o '[0-9]$')"
|
|
|
|
case "${ctype}" in
|
|
|
|
http*)
|
|
|
|
statuscode="$(curl -${IPv}sSkLo /dev/null -H "${useragent}" -m "${timeout}" -w "%{http_code}" "${host}" 2> "${tmp}/ko/${name}.error")";;
|
|
|
|
ping*)
|
|
|
|
ping -W${IPv} "${timeout}" -c 1 "${host}" >/dev/null 2>&1
|
|
|
|
statuscode=$?
|
|
|
|
[ ${statuscode} -ne ${expectedcode} ] && echo 'Host unreachable' > "${tmp}/ko/${name}.error";;
|
|
|
|
port*)
|
|
|
|
error="$(nc -w${IPv} "${timeout}" -zv ${host} 2>&1)"
|
|
|
|
statuscode=$?
|
|
|
|
[ ${statuscode} -ne ${expectedcode} ] && echo "${error}" > "${tmp}/ko/${name}.error";;
|
|
|
|
esac
|
2021-03-27 22:27:40 +00:00
|
|
|
|
|
|
|
# verity status and write files
|
|
|
|
if [ ${statuscode} -eq ${expectedcode} ]; then
|
|
|
|
echo "Status code: ${statuscode}" > "${tmp}/ok/${name}.status"
|
|
|
|
else
|
|
|
|
echo "Status code: ${statuscode}" > "${tmp}/ko/${name}.status"
|
|
|
|
fi
|
|
|
|
if [ -s "${tmp}/ko/${name}.error" ]; then
|
|
|
|
sed "${tmp}/ko/${name}.error" \
|
|
|
|
-e 's,curl: ([0-9]*) ,,' \
|
|
|
|
-e 's,.*) failed: ,,' > "${tmp}/ko/${name}.status"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
command_exists 'curl'
|
|
|
|
command_exists 'nc'
|
2021-03-29 15:03:37 +00:00
|
|
|
command_exists 'ping'
|
2021-03-27 22:27:40 +00:00
|
|
|
mkdir -p "${tmp}/ok" "${tmp}/ko" || exit 1
|
|
|
|
|
|
|
|
while IFS='\n' read -r line; do
|
|
|
|
ctype="$(get_element 1 "${line}")"
|
|
|
|
code="$(get_element 2 "${line}")"
|
|
|
|
name="$(get_element 3 "${line}")"
|
|
|
|
host="$(get_element 4 "${line}")"
|
|
|
|
check "${ctype}" "${host}" "${name}" "${code}" &
|
2021-03-29 18:55:23 +00:00
|
|
|
done < "${checkfile}"
|
2021-03-27 22:27:40 +00:00
|
|
|
wait
|
|
|
|
|
|
|
|
cat << EOF
|
2021-03-29 06:13:47 +00:00
|
|
|
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>${title}</title><style>
|
2021-03-27 22:27:40 +00:00
|
|
|
body { font-family: segoe ui,Roboto,Oxygen-Sans,Ubuntu,Cantarell,helvetica neue,Verdana,sans-serif; }
|
|
|
|
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; }
|
|
|
|
.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; }
|
|
|
|
</style></head>
|
|
|
|
<body>
|
|
|
|
<div class='container'>
|
|
|
|
<h1>Global status</h1>
|
|
|
|
EOF
|
|
|
|
outagenb=$(find ${tmp}/ko -mindepth 1 | grep -c 'status$')
|
|
|
|
if [ ${outagenb} -ne 0 ]; then
|
|
|
|
echo "<ul><li class='panel failed-bg'>${outagenb} Outage(s)</li></ul>"
|
2021-03-29 14:58:19 +00:00
|
|
|
exitcode=1
|
2021-03-27 22:27:40 +00:00
|
|
|
else
|
|
|
|
echo "<ul><li class='panel success-bg'>All Systems Operational</li></ul>"
|
2021-03-29 14:58:19 +00:00
|
|
|
exitcode=0
|
2021-03-27 22:27:40 +00:00
|
|
|
fi
|
|
|
|
cat << EOF
|
|
|
|
<h1>Services</h1>
|
|
|
|
<ul>
|
|
|
|
EOF
|
|
|
|
for file in ${tmp}/ko/*.status; do
|
|
|
|
[ -e "${file}" ] || continue
|
2021-03-27 22:34:27 +00:00
|
|
|
name="$(basename "${file}" | sed 's,.status$,,')"
|
|
|
|
status="$(cat "${file}")"
|
2021-03-27 22:27:40 +00:00
|
|
|
echo "<li>${name} <span class='small failed'>(${status})</span><span class='status failed'>Disrupted</span></li>"
|
|
|
|
done
|
|
|
|
for file in ${tmp}/ok/*.status; do
|
|
|
|
[ -e "${file}" ] || continue
|
2021-03-27 22:34:27 +00:00
|
|
|
name="$(basename "${file}" | sed 's,.status$,,')"
|
2021-03-28 21:29:06 +00:00
|
|
|
echo "<li>${name} <span class='status success'>Operational</span></li>"
|
2021-03-27 22:27:40 +00:00
|
|
|
done
|
|
|
|
cat << EOF
|
|
|
|
</ul>
|
2021-03-29 15:01:07 +00:00
|
|
|
<p class=small> Last check: $(date -I'seconds')</p>
|
2021-03-27 22:27:40 +00:00
|
|
|
EOF
|
2021-03-28 20:14:08 +00:00
|
|
|
if [ -f "${incidentsfile}" ]; then
|
|
|
|
echo '<h1>Incidents</h1>'
|
|
|
|
if [ -s "${incidentsfile}" ]; then
|
|
|
|
sed 's|^\(.*\)$|<p>\1</p>|' "${incidentsfile}"
|
|
|
|
else
|
|
|
|
echo '<p>No incident reported yet ;)</p>'
|
|
|
|
fi
|
|
|
|
fi
|
2021-03-27 22:27:40 +00:00
|
|
|
cat <<EOF
|
|
|
|
</div>
|
|
|
|
</body></html>
|
|
|
|
EOF
|
2021-03-28 20:20:27 +00:00
|
|
|
rm -r "${tmp}" 2>/dev/null
|
2021-03-27 22:27:40 +00:00
|
|
|
|
2021-03-29 14:58:19 +00:00
|
|
|
# Allow the script execution itself to signal success, e.g. for use in healthchecks
|
|
|
|
exit ${exitcode}
|