proxmox-server-setup/kuma-push.sh

91 lines
2.9 KiB
Bash

#!/usr/bin/env bash
###############################################################################
# Uptime Kuma push script - Bash + jq + wget (no curl)
###############################################################################
set -Eeuo pipefail
CFG="/opt/kuma-checks.json"
BASE="https://status.jordanwages.com/api/push"
WGET_OPTS=(--quiet --tries=1 --timeout=4 --output-document=/dev/null)
# 0-4 s jitter so many VMs don't hit Kuma at the exact same second
sleep $(( RANDOM % 5 ))
# --------------------------------------------------------------------------- #
push() { # $1 token $2 status $3 msg $4 ping-ms
local url="${BASE}/${1}?status=${2}&msg=${3// /%20}&ping=${4}"
wget "${WGET_OPTS[@]}" "$url" || true # Kuma will alert if pushes stop
}
check_http() { # arg: URL
local start elapsed
start=$(date +%s%3N)
if wget "${WGET_OPTS[@]}" "$1"; then
elapsed=$(( $(date +%s%3N) - start ))
echo "up $elapsed"
else
elapsed=$(( $(date +%s%3N) - start ))
echo "down $elapsed"
fi
}
check_service() { systemctl is-active --quiet "$1" && echo "up 0" || echo "down 0"; }
check_docker() { docker inspect -f '{{.State.Running}}' "$1" &>/dev/null && echo "up 0" || echo "down 0"; }
check_mount() { mountpoint -q "$1" 2>/dev/null && echo "up 0" || echo "down 0"; }
check_disk() {
# args: device (e.g. sda, /dev/vda5) and threshold percentage
local raw_target="$1" threshold="$2" dev mount usage
if [[ -z "$threshold" || ! "$threshold" =~ ^[0-9]+$ ]]; then
echo "down 0"
return 0
fi
if [[ "$raw_target" == /dev/* ]]; then
dev="$raw_target"
else
dev="/dev/$raw_target"
fi
if ! mount=$(findmnt -nr -S "$dev" -o TARGET 2>/dev/null); then
echo "down 0"
return 0
fi
usage=$(df --output=pcent "$mount" 2>/dev/null | awk 'NR==2 {gsub(/%/, ""); print $1}') || true
if [[ -z "$usage" ]]; then
echo "down 0"
return 0
fi
if (( usage >= threshold )); then
echo "down $usage"
else
echo "up $usage"
fi
}
check_native() { echo "up 0"; }
# --------------------------------------------------------------------------- #
# Iterate through JSON inventory
jq -c '.[]' "$CFG" | while IFS= read -r item; do
name=$(jq -r '.name' <<<"$item")
type=$(jq -r '.type' <<<"$item")
id=$(jq -r '.push' <<<"$item")
tgt=$(jq -r '.target // empty' <<<"$item") # target may be absent
thr=$(jq -r '.threshold // empty' <<<"$item")
case "$type" in
http) read -r stat ping < <(check_http "$tgt") ;;
service) read -r stat ping < <(check_service "$tgt") ;;
docker) read -r stat ping < <(check_docker "$tgt") ;;
mount) read -r stat ping < <(check_mount "$tgt") ;;
disk) read -r stat ping < <(check_disk "$tgt" "$thr") ;;
native) read -r stat ping < <(check_native) ;;
*) stat=down ping=0 ;;
esac
push "$id" "$stat" "$name" "$ping"
done