User Tools

Site Tools


Misc:tools:tinystatus.sh:start

source d'inspiration: https://github.com/bderenzo/tinystatus

I modified Bderenzo's tinystatus, by adding an indication of the number of days remaining before the certificate expires, and I also added a variable for periodic page reloading.

fichier tinystatus.sh:

#!/usr/bin/env bash
# source https://github.com/bderenzo/tinystatus
# MIT licence: https://github.com/bderenzo/tinystatus/tree/master?tab=MIT-1-ov-file#readme
# Configuration variables
TITLE="Tinystatus"
HEADER="Global Status"
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)"
TMP_DIR_DEBUG="/tmp/tinystatus-debug"
refresh_delay="60"
 
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(){
    check="${1}"
    host="${2}"
    name="${3}"
    expected_rc="${4}"
    id="${5}"
    today=$(date +%s)
 
    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")"
            cert="$(curl ${host} -vI 2>&1 | grep "expire date"| tr -s " "| cut -d" " -f4-8)"
            date_exp="$(curl ${host} -vI 2>&1 | grep "expire date")"
            date_cert=$(date -d "${cert}" +"%s")
            delay_cert0=$((date_cert - today))
            delay_cert=$((delay_cert0 / 86400))
            echo "$delay_cert" > "${TMP_DIR}/${id}.ok.cert"
            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";;
#        cert*)
#            rc="$(curl ${host} -vI 2>&1 | grep "expire date" > "${TMP_DIR}/${id}.cert")";;
    esac
 
#set -x
    # verity status and write files
    if [[ "${rc}" == "${expected_rc}" ]]; then
        echo "${name}" > "${TMP_DIR}/${id}.ok"
#            rc="$(curl ${host} -vI 2>&1 | grep "expire date" >> "${TMP_DIR}/${id}.ok")"
    else
        echo "${name}" > "${TMP_DIR}/${id}.ko"
#            rc="$(curl ${host} -vI 2>&1 | grep "expire date" >> "${TMP_DIR}/${id}.ko")"
    fi
#set +x
}
 
# Verify requirements
command_exists 'curl'
command_exists 'nc'
command_exists 'ping'
command_exists 'grep'
#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)"
#OUTAGES_COUNT="0"
 
# Generate HTML
cat << EOF
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" http-equiv="refresh" content="${refresh_delay}" 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; }
h1 { margin-top: 3em; }
ul { padding: 0px; }
li { list-style: none; margin-bottom: 2px; padding: 5px; border-bottom: 1px solid #ddd;  }
.container { max-width: 80em; 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>${HEADER}</h1>
EOF
if [ "${OUTAGES_COUNT}" -ne 0 ]; then
    echo "<ul><li class='panel failed-bg'>${OUTAGES_COUNT} Outage(s)</li></ul>"
else
    echo "<ul><li class='panel success-bg'>All Systems Operational</li></ul>"
fi
cat << EOF
<h1>Services</h1>
(updated every ${refresh_delay}s)
<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><a href="$(cat "${file}")">$(cat "${file}")</a> <span class='status success'>certificat expire in $(cat "${file}.cert") days</span></li>"
done
 
 
cat << EOF
</ul>
<p class=small> Last check: $(date +%FT_%T)</p>
EOF
if [ -f "${INCIDENTS_FILE}" ]; then
    echo '<h1>Incidents</h1>'
    if [ -s "${INCIDENTS_FILE}" ]; then
        sed 's|^\(.*\)$|<p>\1</p>|' "${INCIDENTS_FILE}"
    else
        echo '<p>No incident reported yet ;)</p>'
    fi
fi
cat <<EOF
</div>
</body></html>
EOF
 
# Cleanup and exit
rm -r "${TMP_DIR}" 2>/dev/null
if "${OUTAGE_RC}"; then
    exit "${OUTAGES_COUNT}"
fi

file example check.csv:

http4,  200,  https://err404.numericore.com (IPv4),             https://err404.numericore.com
http6,  200,  https://err404.numericore.com (IPv6),             https://err404.numericore.com
http4,  200,  https://wow.err404.numericore.com (IPv4),         https://wow.err404.numericore.com
http6,  200,  https://wow.err404.numericore.com (IPv6),         https://wow.err404.numericore.com
Misc/tools/tinystatus.sh/start.txt · Last modified: by err404

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki