feat: auto-heal pipeline — detect+restart gateway/bot/ejabberd on failure
This commit is contained in:
@@ -1315,6 +1315,20 @@ def api_xmpp_stats():
|
||||
return jsonify({"today": {"sent": 0, "failed": 0, "latency_avg": 0}, "week": {"sent": 0, "failed": 0}})
|
||||
|
||||
|
||||
@app.route("/api/xmpp/autoheal", methods=["GET", "POST"])
|
||||
def api_xmpp_autoheal():
|
||||
"""自愈:检测异常并自动修复。GET=查看状态, POST=执行修复"""
|
||||
try:
|
||||
from xmpp_logger import auto_heal
|
||||
if request.method == "POST":
|
||||
result = auto_heal()
|
||||
return jsonify(result)
|
||||
else:
|
||||
return jsonify({"usage": "POST to trigger auto-heal"})
|
||||
except ImportError:
|
||||
return jsonify({"error": "xmpp_logger not available"}), 500
|
||||
|
||||
|
||||
# 注册提示词管理路由
|
||||
register_routes(app)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"""
|
||||
import json
|
||||
import time as _time
|
||||
import subprocess as _sp
|
||||
from pathlib import Path
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@@ -230,3 +231,46 @@ def health():
|
||||
elif la > 0: result["status"] = "ok"
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def auto_heal():
|
||||
"""自愈:检测并尝试修复 XMPP 通信问题。"""
|
||||
h = health()
|
||||
actions = []
|
||||
|
||||
# 1. LLM Provider 超时 → 重启 Hermes Gateway
|
||||
if h.get("llm_provider", {}).get("status") in ("timeout", "error"):
|
||||
gw = h.get("gateways", {}).get("zhiwei", {})
|
||||
if gw.get("alive"):
|
||||
try:
|
||||
r = _sp.run(["sudo", "-n", "systemctl", "restart", "hermes-gw-pa"],
|
||||
capture_output=True, timeout=30, text=True)
|
||||
ok = r.returncode == 0
|
||||
actions.append({"action": "restart_hermes_gateway", "target": "position-analyst",
|
||||
"success": ok, "detail": "restarted" if ok else r.stderr[:100]})
|
||||
except Exception as e:
|
||||
actions.append({"action": "restart_hermes_gateway", "target": "position-analyst",
|
||||
"success": False, "detail": str(e)[:100]})
|
||||
|
||||
# 2. Bot 无出站 → 重启知微 Bot
|
||||
ba = h.get("bot_activity", {})
|
||||
if ba.get("inbound", 0) > 0 and ba.get("outbound", 0) == 0 and ba.get("errors", 0) > 0:
|
||||
try:
|
||||
r = _sp.run(["sudo", "-n", "systemctl", "restart", "xmpp-zhiwei"], capture_output=True, timeout=30, text=True)
|
||||
actions.append({"action": "restart_zhiwei_bot", "target": "xmpp-zhiwei",
|
||||
"success": r.returncode == 0, "detail": "restarted" if r.returncode == 0 else r.stderr[:100]})
|
||||
except Exception as e:
|
||||
actions.append({"action": "restart_zhiwei_bot", "target": "xmpp-zhiwei",
|
||||
"success": False, "detail": str(e)[:100]})
|
||||
|
||||
# 3. ejabberd → 重启容器
|
||||
if h.get("ejabberd", "") and "Up" not in str(h["ejabberd"]):
|
||||
try:
|
||||
r = _sp.run(["sudo", "-n", "docker", "restart", "ejabberd"], capture_output=True, timeout=30, text=True)
|
||||
actions.append({"action": "restart_ejabberd", "target": "ejabberd",
|
||||
"success": r.returncode == 0, "detail": "restarted" if r.returncode == 0 else r.stderr[:100]})
|
||||
except Exception as e:
|
||||
actions.append({"action": "restart_ejabberd", "target": "ejabberd",
|
||||
"success": False, "detail": str(e)[:100]})
|
||||
|
||||
return {"actions": actions, "status": h.get("status", "unknown")}
|
||||
|
||||
Reference in New Issue
Block a user