mirror of
https://git.techniverse.net/scriptos/tmserver-docker.git
synced 2026-05-08 07:05:47 +00:00
XAseco-Healthcheck: Automatische Überwachung und Neustart bei Absturz
This commit is contained in:
@@ -47,6 +47,10 @@ COPY assets/bin/RunTrackmaniaServer.sh /opt/tmserver/
|
||||
RUN sed -i 's/\r$//' /opt/tmserver/RunTrackmaniaServer.sh \
|
||||
&& chmod +x /opt/tmserver/RunTrackmaniaServer.sh
|
||||
|
||||
COPY assets/bin/XAsecoHealthcheck.sh /opt/tmserver/
|
||||
RUN sed -i 's/\r$//' /opt/tmserver/XAsecoHealthcheck.sh \
|
||||
&& chmod +x /opt/tmserver/XAsecoHealthcheck.sh
|
||||
|
||||
COPY assets/bin/AdminServ_v2.1.1.zip /var/www/html
|
||||
RUN unzip /var/www/html/AdminServ_v2.1.1.zip -d /var/www/html \
|
||||
&& rm -f /var/www/html/AdminServ_v2.1.1.zip \
|
||||
@@ -192,6 +196,8 @@ ENV XASECO_DB_HOST=mariadb
|
||||
ENV XASECO_DB_NAME=xaseco
|
||||
ENV XASECO_DB_USER=xaseco
|
||||
ENV XASECO_DEDIMANIA_NATION=DEU
|
||||
ENV XASECO_HEALTHCHECK=true
|
||||
ENV XASECO_HEALTHCHECK_INTERVAL=60
|
||||
|
||||
# Debugging
|
||||
ENV PHP_DISPLAY_ERRORS=false
|
||||
|
||||
@@ -900,10 +900,22 @@ if [ "$XMLRPC_READY" = "true" ]; then
|
||||
cd /opt/tmserver/xaseco
|
||||
php aseco.php TMN </dev/null >>aseco.log 2>&1 &
|
||||
XASECO_PID=$!
|
||||
echo "$XASECO_PID" > /tmp/xaseco.pid
|
||||
echo " XAseco gestartet (PID: ${XASECO_PID})"
|
||||
cd /opt/tmserver
|
||||
|
||||
# XAseco Healthcheck / Watchdog starten
|
||||
XASECO_HEALTHCHECK="${XASECO_HEALTHCHECK:-true}"
|
||||
if [ "$XASECO_HEALTHCHECK" = "true" ] && [ -f "/opt/tmserver/XAsecoHealthcheck.sh" ]; then
|
||||
echo "==> Starte XAseco-Healthcheck (Watchdog)..."
|
||||
/opt/tmserver/XAsecoHealthcheck.sh &
|
||||
HEALTHCHECK_PID=$!
|
||||
echo " XAseco-Healthcheck gestartet (PID: ${HEALTHCHECK_PID})"
|
||||
elif [ "$XASECO_HEALTHCHECK" != "true" ]; then
|
||||
echo "==> XAseco-Healthcheck ist deaktiviert (XASECO_HEALTHCHECK=${XASECO_HEALTHCHECK})."
|
||||
fi
|
||||
elif [ "${XASECO_ENABLED:-true}" != "true" ]; then
|
||||
echo "==> XAseco ist deaktiviert (XASECO_ENABLED=${XASECO_ENABLED})."
|
||||
echo "==> XAseco ist deaktiviert (XASECO_ENABLED=${XASECO_ENABLED})."
|
||||
fi
|
||||
else
|
||||
echo " WARNUNG: XMLRPC nicht erreichbar - XAseco und Forced Mods wurden NICHT gestartet."
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
#!/bin/sh
|
||||
|
||||
# ============================================================
|
||||
# XAseco Healthcheck / Watchdog
|
||||
# ============================================================
|
||||
# Ueberwacht den XAseco-Prozess und startet ihn automatisch
|
||||
# neu, wenn er abgestuerzt ist oder die Verbindung zum
|
||||
# TrackmaniaServer verloren hat (kein Overlay mehr sichtbar).
|
||||
#
|
||||
# Pruefungen:
|
||||
# 1) PID-Check: Ist der XAseco-PHP-Prozess noch aktiv?
|
||||
# 2) XMLRPC-Check: Kann XAseco den TM-Server noch erreichen?
|
||||
# (Erkennt haengende Prozesse, die das Overlay verloren haben)
|
||||
#
|
||||
# Umgebungsvariablen:
|
||||
# XASECO_HEALTHCHECK - true/false (Standard: true)
|
||||
# XASECO_HEALTHCHECK_INTERVAL - Pruefintervall in Sekunden (Standard: 60)
|
||||
# SERVER_XMLRPC_PORT - XMLRPC-Port des TM-Servers (Standard: 5000)
|
||||
# ============================================================
|
||||
|
||||
XASECO_DIR="/opt/tmserver/xaseco"
|
||||
HEALTHCHECK_INTERVAL="${XASECO_HEALTHCHECK_INTERVAL:-60}"
|
||||
XMLRPC_PORT="${SERVER_XMLRPC_PORT:-5000}"
|
||||
XASECO_PID_FILE="/tmp/xaseco.pid"
|
||||
RESTART_COUNT=0
|
||||
MAX_CONSECUTIVE_FAILURES=3
|
||||
FAILURE_COUNT=0
|
||||
|
||||
log() {
|
||||
echo "[XAseco-Healthcheck] $(date '+%Y-%m-%d %H:%M:%S') $1"
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# XAseco starten und PID speichern
|
||||
# ============================================================
|
||||
start_xaseco() {
|
||||
cd "$XASECO_DIR"
|
||||
php aseco.php TMN </dev/null >>aseco.log 2>&1 &
|
||||
NEW_PID=$!
|
||||
echo "$NEW_PID" > "$XASECO_PID_FILE"
|
||||
cd /opt/tmserver
|
||||
RESTART_COUNT=$((RESTART_COUNT + 1))
|
||||
FAILURE_COUNT=0
|
||||
log "XAseco gestartet (PID: ${NEW_PID}, Neustart #${RESTART_COUNT})"
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# Pruefen, ob der XAseco-Prozess noch laeuft
|
||||
# ============================================================
|
||||
check_pid() {
|
||||
if [ ! -f "$XASECO_PID_FILE" ]; then
|
||||
return 1
|
||||
fi
|
||||
CURRENT_PID=$(cat "$XASECO_PID_FILE")
|
||||
if [ -z "$CURRENT_PID" ]; then
|
||||
return 1
|
||||
fi
|
||||
# Pruefen ob der Prozess existiert und ein PHP-Prozess ist
|
||||
if kill -0 "$CURRENT_PID" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# XMLRPC-Verbindungscheck: Pruefen, ob der TM-Server noch
|
||||
# erreichbar ist (erkennt verlorene Verbindungen)
|
||||
# ============================================================
|
||||
check_xmlrpc_connection() {
|
||||
php -r '
|
||||
$port = (int)$argv[1];
|
||||
// Testen ob der XMLRPC-Port noch erreichbar ist
|
||||
$fp = @fsockopen("127.0.0.1", $port, $errno, $errstr, 5);
|
||||
if (!$fp) { exit(1); }
|
||||
|
||||
// Handshake lesen
|
||||
$data = @fread($fp, 4);
|
||||
if (strlen($data) < 4) { fclose($fp); exit(1); }
|
||||
$info = unpack("Vsize", $data);
|
||||
$handshake = @fread($fp, $info["size"]);
|
||||
if (strpos($handshake, "GBXRemote") === false) { fclose($fp); exit(1); }
|
||||
|
||||
fclose($fp);
|
||||
exit(0);
|
||||
' "$XMLRPC_PORT" 2>/dev/null
|
||||
return $?
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# XAseco-Log auf aktuelle Fehler pruefen
|
||||
# ============================================================
|
||||
check_xaseco_log() {
|
||||
LOG_FILE="$XASECO_DIR/aseco.log"
|
||||
if [ ! -f "$LOG_FILE" ]; then
|
||||
return 0
|
||||
fi
|
||||
# Letzte 20 Zeilen auf fatale Fehler / Verbindungsabbrueche pruefen
|
||||
LAST_LINES=$(tail -20 "$LOG_FILE" 2>/dev/null)
|
||||
# Typische Fehlermeldungen bei XAseco-Verbindungsverlust
|
||||
if echo "$LAST_LINES" | grep -qi "connection refused\|broken pipe\|server not responding\|transport error\|socket error\|fatal error"; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# Hauptschleife: Regelmaeige Ueberwachung
|
||||
# ============================================================
|
||||
log "Watchdog gestartet (Intervall: ${HEALTHCHECK_INTERVAL}s, XMLRPC-Port: ${XMLRPC_PORT})"
|
||||
|
||||
while true; do
|
||||
sleep "$HEALTHCHECK_INTERVAL"
|
||||
|
||||
# Pruefen ob der TM-Server selbst noch laeuft
|
||||
if ! check_xmlrpc_connection; then
|
||||
log "XMLRPC-Port ${XMLRPC_PORT} nicht erreichbar - TM-Server vermutlich beendet. Watchdog stoppt."
|
||||
break
|
||||
fi
|
||||
|
||||
NEED_RESTART=false
|
||||
REASON=""
|
||||
|
||||
# 1) PID-Check: Prozess noch aktiv?
|
||||
if ! check_pid; then
|
||||
NEED_RESTART=true
|
||||
REASON="Prozess nicht mehr aktiv (PID: $(cat "$XASECO_PID_FILE" 2>/dev/null || echo 'unbekannt'))"
|
||||
fi
|
||||
|
||||
# 2) Log-Check: Fatale Fehler erkannt?
|
||||
if [ "$NEED_RESTART" = "false" ] && ! check_xaseco_log; then
|
||||
FAILURE_COUNT=$((FAILURE_COUNT + 1))
|
||||
log "WARNUNG: Fehler im XAseco-Log erkannt (${FAILURE_COUNT}/${MAX_CONSECUTIVE_FAILURES})"
|
||||
if [ "$FAILURE_COUNT" -ge "$MAX_CONSECUTIVE_FAILURES" ]; then
|
||||
NEED_RESTART=true
|
||||
REASON="Wiederholte Fehler im Log (${FAILURE_COUNT}x)"
|
||||
fi
|
||||
else
|
||||
# Kein Fehler -> Zaehler zuruecksetzen (nur wenn PID OK)
|
||||
if [ "$NEED_RESTART" = "false" ]; then
|
||||
FAILURE_COUNT=0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Neustart durchfuehren
|
||||
if [ "$NEED_RESTART" = "true" ]; then
|
||||
log "NEUSTART ERFORDERLICH: ${REASON}"
|
||||
|
||||
# Alten Prozess sicherheitshalber beenden
|
||||
OLD_PID=$(cat "$XASECO_PID_FILE" 2>/dev/null)
|
||||
if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then
|
||||
log "Beende haengenden Prozess (PID: ${OLD_PID})..."
|
||||
kill "$OLD_PID" 2>/dev/null
|
||||
sleep 3
|
||||
# Falls noch aktiv: SIGKILL
|
||||
if kill -0 "$OLD_PID" 2>/dev/null; then
|
||||
kill -9 "$OLD_PID" 2>/dev/null
|
||||
sleep 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Log rotieren (altes Log sichern fuer Debugging)
|
||||
if [ -f "$XASECO_DIR/aseco.log" ]; then
|
||||
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
|
||||
cp "$XASECO_DIR/aseco.log" "$XASECO_DIR/aseco_crash_${TIMESTAMP}.log"
|
||||
log "Crash-Log gesichert: aseco_crash_${TIMESTAMP}.log"
|
||||
# Maximal 5 Crash-Logs aufbewahren
|
||||
ls -t "$XASECO_DIR"/aseco_crash_*.log 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null
|
||||
fi
|
||||
|
||||
# Kurz warten, damit evtl. Ressourcen freigegeben werden
|
||||
sleep 2
|
||||
|
||||
# XAseco neu starten
|
||||
start_xaseco
|
||||
log "XAseco erfolgreich neugestartet."
|
||||
|
||||
# Nach Neustart etwas laenger warten, damit XAseco sich initialisieren kann
|
||||
sleep 10
|
||||
fi
|
||||
done
|
||||
|
||||
log "Watchdog beendet."
|
||||
@@ -183,6 +183,8 @@ XAseco ist ein Server-Controller für Rekorde, Karma, Jukebox und mehr. Siehe [X
|
||||
| `XASECO_DB_USER` | Datenbank-Benutzername | `xaseco` |
|
||||
| `XASECO_DB_PASSWORD` | Datenbank-Passwort | *(muss gesetzt werden)* |
|
||||
| `XASECO_DEDIMANIA_NATION` | Dedimania-Nation (IOC-Code) | `DEU` |
|
||||
| `XASECO_HEALTHCHECK` | Automatische Überwachung und Neustart von XAseco bei Absturz/Verbindungsverlust | `true` |
|
||||
| `XASECO_HEALTHCHECK_INTERVAL` | Prüfintervall des Healthchecks in Sekunden | `60` |
|
||||
|
||||
> **Hinweis:** Die Server-Zugangsdaten (`SERVER_SA_PASSWORD`, `SERVER_XMLRPC_PORT`) und Dedimania-Daten (`SERVER_LOGIN`, `SERVER_LOGIN_PASSWORD`) werden automatisch aus der bestehenden Konfiguration übernommen.
|
||||
|
||||
|
||||
@@ -77,6 +77,8 @@ Die Konfiguration erfolgt ausschließlich über Umgebungsvariablen in der `.env`
|
||||
| `XASECO_DB_NAME` | Name der XAseco-Datenbank | `xaseco` |
|
||||
| `XASECO_DB_USER` | Datenbank-Benutzername | `xaseco` |
|
||||
| `XASECO_DEDIMANIA_NATION` | Dedimania-Nation ([IOC-Code](https://en.wikipedia.org/wiki/List_of_IOC_country_codes), z.B. `DEU`, `AUT`, `CHE`) | `DEU` |
|
||||
| `XASECO_HEALTHCHECK` | Automatische Überwachung und Neustart bei Absturz | `true` |
|
||||
| `XASECO_HEALTHCHECK_INTERVAL` | Prüfintervall des Healthchecks in Sekunden | `60` |
|
||||
|
||||
### Automatisch übernommene Variablen
|
||||
|
||||
@@ -147,6 +149,37 @@ XASECO_ENABLED=false
|
||||
|
||||
Der TrackMania-Server läuft dann ohne Server-Controller.
|
||||
|
||||
## Healthcheck / Watchdog
|
||||
|
||||
XAseco wird automatisch durch einen Watchdog-Prozess überwacht. Dieser erkennt Abstürze und verlorene Verbindungen (z.B. wenn das Overlay im Spiel verschwindet) und startet XAseco selbstständig neu.
|
||||
|
||||
### Funktionsweise
|
||||
|
||||
Der Watchdog prüft regelmäßig (Standard: alle 60 Sekunden):
|
||||
|
||||
1. **PID-Check:** Läuft der XAseco-PHP-Prozess noch?
|
||||
2. **Log-Check:** Enthält das XAseco-Log fatale Fehler oder Verbindungsabbrüche?
|
||||
3. **XMLRPC-Check:** Ist der TM-Server noch erreichbar?
|
||||
|
||||
Bei erkannten Problemen wird XAseco automatisch beendet und neu gestartet. Crash-Logs werden zur Fehleranalyse unter `data/xaseco/aseco_crash_<TIMESTAMP>.log` gesichert (max. 5 Dateien).
|
||||
|
||||
### Konfiguration
|
||||
|
||||
| Variable | Beschreibung | Standard |
|
||||
|----------|-------------|----------|
|
||||
| `XASECO_HEALTHCHECK` | Watchdog aktivieren/deaktivieren | `true` |
|
||||
| `XASECO_HEALTHCHECK_INTERVAL` | Prüfintervall in Sekunden | `60` |
|
||||
|
||||
```env
|
||||
# Healthcheck deaktivieren
|
||||
XASECO_HEALTHCHECK=false
|
||||
|
||||
# Prüfintervall auf 30 Sekunden verkürzen
|
||||
XASECO_HEALTHCHECK_INTERVAL=30
|
||||
```
|
||||
|
||||
> **Hinweis:** Der Watchdog ist standardmäßig aktiviert und erfordert keine zusätzliche Konfiguration. Bei bestehenden Installationen wird er nach dem nächsten Image-Update automatisch aktiv.
|
||||
|
||||
## Logs
|
||||
|
||||
Die XAseco-Logdatei befindet sich unter:
|
||||
|
||||
Reference in New Issue
Block a user