Skip to content

Monitoring und Alerts

ElGregor edited this page Aug 15, 2026 · 1 revision

Monitoring und Alerts

Home

Wie dieses Repo den Server überwacht: ein Healthcheck-Skript, ein minütlicher Watchdog per Cron, Discord-Benachrichtigungen und RCON-Ansagen an die Spieler. Alles Bestandteil des Standard-Setups — nichts davon muss zusätzlich installiert werden.

Vertieft in Repo: scripts/healthcheck.sh, scripts/monitor.sh, scripts/notify.sh, scripts/announce.sh, scripts/lib/common.sh; Anwendungsseite docs/05-wartung.md, Fehlerbilder docs/07-troubleshooting.md.

healthcheck.sh — die drei Prüfungen

make healthcheck (oder bash scripts/healthcheck.sh) beantwortet die Frage „Ist der Server gesund?" mit drei einzelnen Prüfungen (1:1 aus dem Skript):

# 1. Prozess laeuft?
pgrep -f "ProjectZomboid" || systemctl is-active --quiet zomboid

# 2. UDP-Port offen?
ss -ulnp | grep -q ":${GAME_PORT} "        # GAME_PORT, Default 16261 (Repo-Default)

# 3. Frische kritische Fehler im Log?
sudo journalctl -u zomboid --since "5 min ago" --no-pager | \
  grep -qiE "OutOfMemory|Exception in thread|FATAL"
Pruefung Bei Erfolg Bei Misserfolg Zaehlt fuer Exit-Code
Prozess OK: Server-Prozess aktiv FAIL: Kein Server-Prozess gefunden Ja (FAIL=1)
UDP-Port OK: UDP 16261 gebunden Nur WARN: Port nicht sichtbar (Server evtl. noch am Starten) Nein — reine Warnung (Repo-Default)
Log-Scan (letzte 5 Min) nichts (stille) FAIL: Kritische Fehler im Log Ja (FAIL=1)

Was „gesund" hier konkret heisst: Der Java-Prozess läuft UND das Journal der letzten 5 Minuten keines der Schlüsselwörter OutOfMemory, Exception in thread oder FATAL enthält (1:1 aus dem Skript).

Zwei bewusste Design-Entscheidungen (Repo-Stand):

  • UDP-Fail ist nur eine Warnung. Der Server bindet den Port einige Zeit nach dem Prozessstart; direkt nach systemctl start wäre ein harter Fehler ein Fehlalarm. Erst wenn der Port dauerhaft fehlt, ist das ein echtes Symptom — siehe Troubleshooting.
  • Nur die letzten 5 Minuten werden gescannt. Alte Fehler von gestern dürfen den Healthcheck nicht rot machen. Das Update-Skript wartet deshalb nach dem Start 45 Sekunden, bevor es den Healthcheck aufruft (1:1 aus scripts/update.sh).

Der Exit-Code (0 = gesund, 1 = mindestens ein harter Fehlschlag) wird vom Update-Rollback und vom Watchdog ausgewertet.

Watchdog monitor.sh

scripts/monitor.sh ist ein Crash-Watchdog, der minütlich per Cron läuft. Installation laut systemd/README.md (1:1):

* * * * * /pfad/zum/repo/scripts/monitor.sh

Ablauf bei jedem Lauf (1:1 aus dem Skript):

  1. systemctl is-active --quiet zomboid → Service läuft? Raus, alles gut.
  2. Lockfile ${REPO_ROOT}/.planned-stop vorhanden? → Raus ohne Eingriff.
  3. Sonst: ungeplanter Ausfall → sudo systemctl restart zomboid, 45 Sekunden warten, dann healthcheck.sh:
    • Healthcheck OK → Discord: „Server war abgestuerzt und wurde neu gestartet" (Warn-Farbe)
    • Healthcheck FAIL → Discord: „KRITISCH: Neustart fehlgeschlagen - manuell pruefen!" (Rot) — jetzt ist der Mensch gefragt.

Das .planned-stop-Flag

Das Flag ist eine leere Datei direkt im Repo-Verzeichnis (${REPO_ROOT}/.planned-stop). Wer setzt und entfernt es:

Situation Wer setzt/entfernt es Wirkung
Geplante manuelle Wartung Du per Hand: touch .planned-stop vor dem Stop, rm .planned-stop danach (Anleitung in docs/05-wartung.md) Watchdog startet den absichtlich gestoppten Server nicht neu
Backup/Update per Timer Skripte laufen bei laufendem Server; ein kurzer Stop passiert nur im Update-Fenster

Vergessenes Flag = „Watchdog startet nicht neu" — das ist eines der Standard-Fehlerbilder in Troubleshooting.

Bekannte Eigenheit (Repo-Stand): update.sh selbst setzt während seines Stopfensters KEIN .planned-stop. Theoretisch kann daher der minütliche monitor.sh-Cron den Server mitten im Update-Fenster (zwischen systemctl stop und systemctl start) wieder hochziehen. Heuristik-Empfehlung dieses Wikis: vor manuell angestoßenen Updates touch .planned-stop setzen und es im Anschluss entfernen — so ist das Update-Fenster in jedem Fall watchdog-sicher.

Discord-Alerts

Sendefunktion ist notify() aus scripts/lib/common.sh (1:1): ein curl-POST eines Embeds (Titel, Nachricht, Farbcode, Hostname als Footer, UTC-Zeitstempel) an DISCORD_WEBHOOK_URL.

  • DISCORD_WEBHOOK_URL leer oder nicht gesetzt (Repo-Default in .env.example) → notify() kehrt sofort zurück: alles bleibt stumm, kein Skript bricht ab.
  • Webhook gesetzt, aber curl schlägt fehl → Warnung im Skript-Log, Ablauf läuft weiter.

Welche Ereignisse tatsächlich senden

Vollständige Liste der 11 automatischen notify()-Aufrufe in den Repo-Skripten (1:1; der manuelle Wrapper notify.sh zählt nicht mit und steht unten im Abschnitt „Manuell pingen"):

Ereignis Quelle Discord-Farbe (dezimal, 1:1)
Update-Zyklus gestartet (Server geht gleich offline) update.sh 15105570
Update erfolgreich, Server läuft update.sh 3066993
FEHLER — Rollback auf Pre-Update-Backup update.sh 15158332
Rollback erfolgreich, alter Stand läuft update.sh 3066993
KRITISCH: Rollback-Healthcheck fehlgeschlagen update.sh 15158332
Backup FEHLGESCHLAGEN backup.sh 15158332
„Naechtliches Backup OK" (nur bei Label daily) backup.sh 3066993
„Restore erfolgreich" (mit Backup-Dateiname, nach Healthcheck) restore.sh 3066993
Server war abgestürzt und neu gestartet (Watchdog) monitor.sh 15105570
KRITISCH: Watchdog-Neustart fehlgeschlagen monitor.sh 15158332
„Installation abgeschlossen" (Erstinstallation) install.sh 3066993

Farbcodes zur Orientierung (dezimal aus Skripten, hex umgerechnet): 15105570 = #E67E22 (Orange/Warnung), 3066993 = #2ECC71 (Grün/OK), 15158332 = #E74C3C (Rot/Kritisch). Für eigene Pings: 3447003 = #3498DB (Blau, Default in notify() und notify.sh).

Ehrliche Klarstellung: Die README-Featureliste nennt „Discord-Alerts: Start/Stop/Update/Crash/Backup". Skriptseitig existieren NUR diese 11 Events (Call-Sites, Tabelle oben) — Update-Phasen, Backup, Restore, Installation und Watchdog-Restart. Separate „Server gestartet"/„Server gestoppt"- Notifications sind im Repo-Stand NICHT implementiert; ein normaler make start/make stop sendet nichts.

Manuell pingen

bash scripts/notify.sh "PZ-Server" "Test-Nachricht"        # Default-Farbe
bash scripts/notify.sh "Wartung" "Restart in 10 Min" 15105570

notify.sh ist ein dünner Wrapper um notify() und loggt zusätzlich „Notify gesendet" ins Skript-Log (1:1 aus dem Skript) — auch wenn kein Webhook gesetzt ist und daher nichts rausging. Zum Testen der Kette also immer in Discord prüfen, ob die Nachricht ankam.

RCON-Ansagen an die Spieler (announce.sh)

scripts/announce.sh warnt Spieler in-game vor einem Neustart — ein Countdown in drei Stufen (Zeiten 1:1 aus dem Skript):

Ansage (servermsg via RCON) Wartezeit danach
„Server-Neustart in 15 Minuten (Wartung)" 600 s
„Server-Neustart in 5 Minuten - bitte einloggen sichern!" 240 s
„Server-Neustart in 1 Minute!" 60 s

Insgesamt also rund 15 Minuten Vorwarnung (600 + 240 + 60 s), danach kehrt das Skript zurück und update.sh stoppt den Server.

Zwei Guards (1:1 aus dem Skript):

  • mcrcon nicht installiert → Warnung „In-Game-Warnung uebersprungen", Skript beendet sich mit Exit 0 (Update läuft ohne Ankündigung weiter).
  • RCON_ENABLED nicht true → stiller Exit 0.

Verbindungsaufbau: mcrcon -H 127.0.0.1 -P ${RCON_PORT} -p ${RCON_PASSWORD} (Werte aus .env; Repo-Defaults: RCON_PORT=27015, RCON_ENABLED=true). Fehlgeschlagene RCON-Befehle werden bewusst ignoriert (|| true) — die Ansage ist Komfort, kein Muss.

journalctl-Rezepte

Alle Server-Logs landen im Journal der Unit zomboid. make logs ist genau sudo journalctl -u zomboid -f (1:1 aus dem Makefile). Die üblichen Fragen im Griff:

Frage Befehl
Was passiert gerade? (live folgen) make logs oder sudo journalctl -u zomboid -f
Die letzten 100 Zeilen ansehen sudo journalctl -u zomboid -n 100 --no-pager
Nur Fehler (wie der Healthcheck sie sucht) sudo journalctl -u zomboid --no-pager | grep -iE "OutOfMemory|Exception in thread|FATAL"
Fehler der letzten 5 Minuten sudo journalctl -u zomboid --since "5 min ago" --no-pager
Unit-Status inkl. Neustart-Historie systemctl status zomboid --no-pager
Seit einem Zeitpunkt (z. B. nach Update) sudo journalctl -u zomboid --since "2026-08-15 03:00" --no-pager

Ergänzend schreiben alle Repo-Skripte ihre eigenen Meldungen nach logs/server.log im Repo-Verzeichnis (Logging aus common.sh) — dort steht z. B. die Backup-Größe oder „Update-Zyklus gestartet".

Symptome lesen: was wohin führt

  • Healthcheck rot, Watchdog-Notifications häufen sich → Fehlerbild eingrenzen in Troubleshooting.
  • Server läuft, aber es ruckelt/lagt → das ist Performance, kein Monitoring-Problem: Performance-Guide (Messbefehle für GC, CPU, IO).
  • Metrik-Grundlagen (Retention, Timer, Rhythmus der Automatik) → Wartung-und-Automatik; alle Skripte im Detail → Skripte-Referenz.

Weiter: Wartung-und-Automatik · Troubleshooting · Performance-Guide

Clone this wiki locally