#!/usr/bin/env sh # generate-status-page.sh # Fragt VictoriaMetrics ab und erzeugt eine statische HTML-Statusseite. # Läuft in einem Alpine-Container im Docker-Netz (http://victoriametrics:9090) # oder auf dem Host (http://localhost:9090). # # Ausgabe: /output/index.html (gemountet als /Volumes/ManaData/landings/status/) set -eu VM_URL="${VICTORIAMETRICS_URL:-http://victoriametrics:9090}" OUTPUT="${OUTPUT_FILE:-/output/index.html}" TMPDIR_LOCAL="$(mktemp -d)" trap 'rm -rf "$TMPDIR_LOCAL"' EXIT # ── Daten aus VictoriaMetrics holen ──────────────────────────────────────── fetch_metric() { curl -sf --max-time 10 \ "${VM_URL}/api/v1/query?query=$(printf '%s' "$1" | sed 's/ /%20/g;s/{/%7B/g;s/}/%7D/g;s/=~/%3D~/g;s/|/%7C/g;s/"/%22/g')" \ 2>/dev/null || echo '{"status":"error","data":{"result":[]}}' } SUCCESS_JSON="$(fetch_metric 'probe_success{job=~"blackbox-web|blackbox-api|blackbox-infra|blackbox-gpu"}')" DURATION_JSON="$(fetch_metric 'probe_duration_seconds{job=~"blackbox-web|blackbox-api|blackbox-infra|blackbox-gpu"}')" # ── Hilfsfunktionen ───────────────────────────────────────────────────────── # Gibt den probe_success-Wert für eine Instanz zurück (0 oder 1) get_success() { instance="$1" echo "$SUCCESS_JSON" | jq -r --arg inst "$instance" \ '.data.result[] | select(.metric.instance == $inst) | .value[1]' 2>/dev/null || echo "0" } # Gibt die Antwortzeit in ms zurück get_duration_ms() { instance="$1" val=$(echo "$DURATION_JSON" | jq -r --arg inst "$instance" \ '.data.result[] | select(.metric.instance == $inst) | .value[1]' 2>/dev/null || echo "") if [ -n "$val" ] && [ "$val" != "null" ]; then printf "%.0f" "$(echo "$val * 1000" | awk '{printf "%.1f", $1}')" else echo "" fi } # Alle Instanzen einer Job-Gruppe, sortiert get_instances() { job="$1" echo "$SUCCESS_JSON" | jq -r --arg job "$job" \ '.data.result[] | select(.metric.job == $job) | .metric.instance' 2>/dev/null | sort } # Freundlicher Name aus URL friendly_name() { url="$1" # Entferne https:// und .mana.how name="${url#https://}" name="${name%.mana.how}" # Entferne /health suffix name="${name%/health}" # Erster Buchstabe groß (POSIX-kompatibel) printf '%s' "$name" | awk '{print toupper(substr($0,1,1)) substr($0,2)}' } # Zählt UP-Dienste einer Job-Gruppe count_up() { job="$1" echo "$SUCCESS_JSON" | jq -r --arg job "$job" \ '[.data.result[] | select(.metric.job == $job) | .value[1]] | map(tonumber) | add // 0' \ 2>/dev/null || echo "0" } count_total() { job="$1" echo "$SUCCESS_JSON" | jq -r --arg job "$job" \ '[.data.result[] | select(.metric.job == $job)] | length' \ 2>/dev/null || echo "0" } # ── Service-Rows HTML ──────────────────────────────────────────────────────── render_rows() { job="$1" instances="$(get_instances "$job")" if [ -z "$instances" ]; then printf '