MetaTrader5-Docker-Image/scripts/check-stack.sh

101 lines
4.1 KiB
Bash
Raw Permalink Normal View History

2026-11-07 05:32:23 +00:00
#!/bin/bash
# check-stack.sh – Statusprüfung DIESES Stacks (MT5, MCP, Trader, Telegram)
# Läuft im Stack-Ordner auf dem Server; Werte kommen aus deploy.conf.
#
# scripts/check-stack.sh ausführlich
# scripts/check-stack.sh -q nur Fehler/Warnungen (cron/Deploy)
# Exit-Code: 0 = ok, 1 = mindestens ein Fehler (Warnungen zählen nicht)
cd "$(dirname "$0")/.." || exit 1
source ./deploy.conf
QUIET=0; [ "${1:-}" = "-q" ] && QUIET=1
FAIL=0
SYMBOL="${CHECK_SYMBOL:-XAUUSD}"
BASE="http://127.0.0.1:$MCP_PORT"
if [ -t 1 ]; then G=$'\e[32m'; R=$'\e[31m'; Y=$'\e[33m'; B=$'\e[1m'; N=$'\e[0m'; else G=; R=; Y=; B=; N=; fi
pfx() { [ $QUIET -eq 1 ] && echo "[$STACK_KEY] "; }
ok() { [ $QUIET -eq 1 ] || echo " ${G}OK${N} $*"; }
warn() { echo " ${Y}WARN${N} $(pfx)$*"; }
fail() { echo " ${R}FAIL${N} $(pfx)$*"; FAIL=1; }
jget() { python3 -c "import json,sys
try: v=json.load(sys.stdin)
except Exception: print('${2:-}'); sys.exit()
for k in '$1'.split('.'):
v = v.get(k) if isinstance(v, dict) else None
print('${2:-}' if v is None else v)"; }
cid() { docker compose ps -q "$1" 2>/dev/null | head -1; }
[ $QUIET -eq 1 ] || echo "${B}== $STACK_NAME ==${N}"
# 1. Container
for svc in "$MT5_SVC" "$MCP_SVC" "$TRADER_SVC"; do
id=$(cid "$svc")
if [ -z "$id" ]; then fail "Dienst $svc: kein Container"; continue; fi
st=$(docker inspect -f '{{.State.Status}}{{if .State.Health}}/{{.State.Health.Status}}{{end}}' "$id")
case "$st" in running/healthy|running) ok "Dienst $svc: $st" ;; *) fail "Dienst $svc: $st" ;; esac
done
# 2. Bridge + Konto
H=$(curl -s -m 10 "$BASE/health")
[ "$(echo "$H" | jget connected)" = "True" ] && ok "MCP $BASE: Bridge verbunden" \
|| fail "MCP $BASE: keine Verbindung zu MT5 (${H:-keine Antwort})"
A=$(curl -s -m 15 "$BASE/account")
if [ -n "$(echo "$A" | jget login)" ]; then
ok "Konto $(echo "$A" | jget login) @ $(echo "$A" | jget server): Balance $(echo "$A" | jget balance)" \
"Equity $(echo "$A" | jget equity) $(echo "$A" | jget currency)"
else
fail "Konto: $(echo "$A" | jget detail "${A:-keine Antwort}")"
fi
# 3. Kurs
T=$(curl -s -m 15 "$BASE/tick/$SYMBOL")
if [ -n "$(echo "$T" | jget bid)" ]; then
ok "$SYMBOL → $(echo "$T" | jget symbol): bid $(echo "$T" | jget bid) ask $(echo "$T" | jget ask)"
else
fail "Kurs $SYMBOL: $(echo "$T" | jget detail "${T:-keine Antwort}")"
fi
# 4. Positionen
P=$(curl -s -m 15 "$BASE/positions" | jget count)
if [ -z "$P" ]; then fail "Positionen: keine Antwort"
elif [ "$P" -gt 0 ]; then warn "Offene Positionen: $P"
else ok "Offene Positionen: 0"; fi
# 5. Trader-Lebenszeichen (Docker-Zeitstempel = UTC, unabhängig von Zeitzonen)
TID=$(cid "$TRADER_SVC")
if [ -n "$TID" ]; then
LAST=$(docker logs --timestamps --since 10m "$TID" 2>&1 | grep -E "\[(LIVE|DRY)\] Balance" | tail -1)
if [ -n "$LAST" ]; then
AGE=$(( $(date +%s) - $(date -d "$(echo "$LAST" | awk '{print $1}')" +%s 2>/dev/null || echo 0) ))
MODE=$(echo "$LAST" | grep -oE "LIVE|DRY" | head -1)
[ "$AGE" -le 120 ] && ok "Trader lebt ($MODE), letztes Lebenszeichen vor ${AGE}s" \
|| fail "Trader: letztes Lebenszeichen vor ${AGE}s"
else
fail "Trader: keine Balance-Zeile in den letzten 10 min"
fi
# 6. Telegram
START=$(docker inspect -f '{{.State.StartedAt}}' "$TID")
CHAN=$(docker logs --since "$START" "$TID" 2>&1 | grep -oE "Active channels: [^|]*" | tail -1)
[ -n "$CHAN" ] && ok "Telegram: $CHAN" || fail "Telegram: keine 'Active channels'-Meldung seit Start"
ERRS=$(docker logs --since 60m "$TID" 2>&1 \
| grep -ciE "AUTH_KEY|EOFError|SessionPasswordNeeded|PhoneNumber|Traceback|disconnected|server closed")
[ "$ERRS" -gt 0 ] && warn "Telegram/Trader: $ERRS Fehlerzeile(n) in der letzten Stunde"
fi
if [ -f "$DIAG_FILE" ]; then
DAGE=$(( $(date +%s) - $(stat -c %Y "$DIAG_FILE") ))
[ "$DAGE" -le 900 ] && ok "Diagnose: vor ${DAGE}s geschrieben, $(jget total_messages < "$DIAG_FILE") Nachricht(en)" \
|| fail "Diagnose: seit ${DAGE}s nicht geschrieben ($DIAG_FILE)"
else
warn "Diagnose: $DIAG_FILE fehlt"
fi
[ $QUIET -eq 1 ] || { [ $FAIL -eq 0 ] && echo "${G}${B}Alles in Ordnung.${N}" || echo "${R}${B}Fehler – siehe oben.${N}"; }
exit $FAIL