#!/usr/bin/env python3 """ checkmk local check: Geoblocking Wertet die Log-Datei von geoblock.py aus und meldet an checkmk, ob der letzte Lauf (systemd-Timer: beim Boot + taeglich) erfolgreich und aktuell war. INSTALLATION: 1. LOG_FILE unten auf den Pfad anpassen, der in der geoblock.ini unter [geoblock] log_file konfiguriert ist (Default passt zum mitgelieferten install_geoblock.sh). 2. Datei ausfuehrbar machen und ins checkmk-Agent local-Verzeichnis legen: cp geoblock_checkmk /usr/lib/check_mk_agent/local/ chmod 755 /usr/lib/check_mk_agent/local/geoblock_checkmk (Pfad haengt von Distro/Checkmk-Setup ab - ueblich sind /usr/lib/check_mk_agent/local/ oder bei OMD-Sites ~/local/lib/check_mk_agent/local/. Bei Bedarf: 'check_mk_agent' Pfad des jeweiligen Hosts pruefen.) 3. Naechster Agent-Abruf zeigt den Service "Geoblock" in checkmk. AUSGABE-LOGIK: - Keine Log-Datei / keine RESULT-Zeile gefunden -> UNKNOWN (3) - Letzter Lauf hatte status=ERROR -> CRIT (2) - Letzter erfolgreicher Lauf zu alt (> CRIT_AGE) -> CRIT (2) - Letzter erfolgreicher Lauf etwas alt (> WARN) -> WARN (1) - Sonst -> OK (0) """ import datetime import os import re import time # --- Anpassen: muss zum log_file-Pfad aus der geoblock.ini passen --- LOG_FILE = "/var/log/geoblock/geoblock.log" # Timer laeuft taeglich -> grosszuegig bemessen, damit ein einzelner # verpasster Lauf (Host kurz aus) nicht sofort CRIT ausloest. WARN_AGE_SEC = 36 * 3600 # 36h CRIT_AGE_SEC = 72 * 3600 # 72h SERVICE_NAME = "Geoblock" # Beispiel-Zeile in der Log-Datei (von geoblock.py log_result() geschrieben): # 2026-07-21T10:00:00+02:00 [geoblock] RESULT ts=2026-07-21T10:00:00+02:00 # status=OK action=apply countries=4 entries=123456 msg="Geoblock aktualisiert (..)" RESULT_RE = re.compile( r'RESULT ts=(?P\S+) status=(?P\S+) action=(?P\S+)' r'(?: countries=(?P\d+))?(?: entries=(?P\d+))? ' r'msg="(?P.*)"\s*$' ) def emit(status, perfdata, text): perf = perfdata if perfdata else "-" print(f"{status} {SERVICE_NAME} {perf} {text}") def main(): if not os.path.isfile(LOG_FILE): emit(3, "-", f"Log-Datei nicht gefunden ({LOG_FILE}) - lief geoblock.py schon einmal mit --apply?") return last_match = None try: with open(LOG_FILE, "r", encoding="utf-8", errors="ignore") as f: for line in f: m = RESULT_RE.search(line.strip()) if m: last_match = m # letzte Übereinstimmung gewinnt (Datei waechst append-only) except OSError as e: emit(3, "-", f"Log-Datei nicht lesbar: {e}") return if not last_match: emit(3, "-", f"Keine RESULT-Zeile in {LOG_FILE} gefunden - lief geoblock.py schon mit --apply?") return ts_raw = last_match.group("ts") action = last_match.group("action") status_str = last_match.group("status") countries = last_match.group("countries") entries = last_match.group("entries") msg = last_match.group("msg") try: last_dt = datetime.datetime.fromisoformat(ts_raw) age = time.time() - last_dt.timestamp() except ValueError: emit(3, "-", f"Konnte Zeitstempel nicht parsen: {ts_raw}") return perf = f"age={int(age)}s;{WARN_AGE_SEC};{CRIT_AGE_SEC}" if entries is not None: perf += f"|entries={entries}" if status_str != "OK": emit(2, perf, f"Letzter Lauf ({action}) fehlgeschlagen: {msg}") return if age > CRIT_AGE_SEC: emit(2, perf, f"Letzter erfolgreicher Lauf ist {int(age / 3600)}h alt " f"(Schwelle {CRIT_AGE_SEC // 3600}h) - Timer laeuft nicht mehr? Letzte msg: {msg}") return if age > WARN_AGE_SEC: emit(1, perf, f"Letzter erfolgreicher Lauf ist {int(age / 3600)}h alt " f"(Schwelle {WARN_AGE_SEC // 3600}h) - Letzte msg: {msg}") return extra = f", {countries} Laender" if countries else "" emit(0, perf, f"OK - letzter Lauf vor {int(age / 60)}min{extra}: {msg}") if __name__ == "__main__": main()