#!/usr/bin/env sh title=tinystatus timeout=10 tmp="$(mktemp -d)" checkfile="${1:-checks.csv}" incidentsfile="${2:-incidents.list}" 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" command_exists(){ if ! command -v "${1}" >/dev/null 2>&1; then echo >&2 "Error: ${1} missing. Please install it" exit 1 fi } get_element(){ echo "${2}" | awk -v col="${1}" -F',' '{gsub(/^[ \t]+|[ \t]+$/, "", $col); print $col}' } check(){ ctype="${1}" host="${2}" name="${3}" expectedcode="${4}" 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 # 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' command_exists 'ping' 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}" & done < "${checkfile}" wait cat << EOF ${title}

Global status

EOF outagenb=$(find ${tmp}/ko -mindepth 1 | grep -c 'status$') if [ ${outagenb} -ne 0 ]; then echo "" exitcode=1 else echo "" exitcode=0 fi cat << EOF

Services

Last check: $(date -I'seconds')

EOF if [ -f "${incidentsfile}" ]; then echo '

Incidents

' if [ -s "${incidentsfile}" ]; then sed 's|^\(.*\)$|

\1

|' "${incidentsfile}" else echo '

No incident reported yet ;)

' fi fi cat < EOF rm -r "${tmp}" 2>/dev/null # Allow the script execution itself to signal success, e.g. for use in healthchecks exit ${exitcode}