Files
checkbot/deploy/checkmk/checkbot-local-check
T
patrickandClaude Sonnet 5.5 453c077386 feat: Phase 6d API-Selbsttest gegen Checkmk
Lesender Selbsttest (Version, Services, Hosts, Downtimes) beim Start und
täglich 04:00, Seite /selftest, Teilcheck checkmk_api in /health, Chat-Meldung
bei Wechsel. Toleranter Antwort-Parser (value/members, state_type int/String),
Fallbacks für Host-Abfrage und Downtime-Liste, Fehlerhinweise je HTTP-Status.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 12:55:57 +01:00

72 lines
2.2 KiB
Python
Executable File

#!/usr/bin/env python3
# Checkmk-Local-Check: ruft /health des Bots ab und gibt pro Teilcheck eine Zeile "Status Name Metrik Text" aus.
import json
import os
import sys
import urllib.error
import urllib.request
HEALTH_URL = os.environ.get("CHECKBOT_HEALTH_URL", "http://127.0.0.1:8080/health")
# Der Bot prüft seine Backends mit bis zu 10 s Timeout, daher etwas mehr.
TIMEOUT_SECONDS = 15
CHECK_NAMES = ("db", "checkmk", "checkmk_api", "ollama", "poller", "telegram", "matrix")
SERVICE_PREFIX = "Checkbot_"
API_SERVICE = "Checkbot_api"
NOT_CONFIGURED = "nicht konfiguriert"
NOT_YET_RUN = "noch nicht gelaufen"
WARN_DETAILS = (NOT_CONFIGURED, NOT_YET_RUN)
MAX_TEXT = 200
OK, WARN, CRIT = 0, 1, 2
def fetch_health() -> dict:
request = urllib.request.Request(HEALTH_URL, headers={"Accept": "application/json"})
try:
with urllib.request.urlopen(request, timeout=TIMEOUT_SECONDS) as response:
body = response.read()
except urllib.error.HTTPError as exc:
body = exc.read()
data = json.loads(body)
if not isinstance(data.get("checks"), dict):
raise ValueError("Antwort ohne Feld 'checks'")
return data
def clean(text) -> str:
return " ".join(str(text).split())[:MAX_TEXT]
def line(state: int, name: str, text: str) -> str:
return f"{state} {name} - {clean(text)}"
def evaluate(name: str, result: dict | None) -> str:
service = SERVICE_PREFIX + name
if result is None:
return line(OK, service, "deaktiviert")
detail = result.get("detail", "")
if result.get("ok"):
return line(OK, service, detail or "ok")
if detail in WARN_DETAILS:
return line(WARN, service, detail)
return line(CRIT, service, detail or "Fehler")
def main() -> int:
try:
checks = fetch_health()["checks"]
except Exception as exc:
reason = f"Bot nicht erreichbar ({type(exc).__name__}: {exc})"
print(line(CRIT, API_SERVICE, reason))
for name in CHECK_NAMES:
print(line(CRIT, SERVICE_PREFIX + name, reason))
return 0
print(line(OK, API_SERVICE, f"{HEALTH_URL} erreichbar"))
for name in CHECK_NAMES:
print(evaluate(name, checks.get(name)))
return 0
if __name__ == "__main__":
sys.exit(main())