fix: detect system_event_logout for real WeChat status
Previously only looked for WeChat send OK/error in last 200 log lines. system_event_logout was missed, so dashboard showed 正常 when session was actually dead. Now: - Greps full webhook log for system_event_login/logout - Logout after login => logged_out status - WeChat send timeout (Hermes error) also counts as failure
This commit is contained in:
@@ -613,7 +613,7 @@ def _augment_wechat_status(entry):
|
||||
r = subprocess.run(["tail", "-200", webhook_log],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
lines = r.stdout.strip().split("\n") if r.stdout else []
|
||||
last_ok, last_err, last_login = None, None, None
|
||||
last_ok, last_err, last_login, last_logout = None, None, None, None
|
||||
for line in reversed(lines):
|
||||
ts_match = re.match(r"^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})", line)
|
||||
ts = ts_match.group(1) if ts_match else None
|
||||
@@ -621,17 +621,32 @@ def _augment_wechat_status(entry):
|
||||
last_ok = ts
|
||||
elif "WeChat send error" in line and ts and not last_err:
|
||||
last_err = ts
|
||||
if "system_event_login" in line and ts and not last_login:
|
||||
last_login = ts
|
||||
if last_ok and last_err and last_login:
|
||||
if last_ok and last_err:
|
||||
break
|
||||
# Login/logout events: search full log (not just tail -200)
|
||||
try:
|
||||
for ev, key in (("system_event_logout", "last_logout"), ("system_event_login", "last_login")):
|
||||
er = subprocess.run(["grep", ev, webhook_log],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
ev_lines = [l for l in er.stdout.strip().split("\n") if l.strip()]
|
||||
if ev_lines:
|
||||
m = re.match(r"^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})", ev_lines[-1])
|
||||
if m:
|
||||
if key == "last_login":
|
||||
last_login = m.group(1)
|
||||
else:
|
||||
last_logout = m.group(1)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
ok_dt = err_dt = None
|
||||
ok_dt = err_dt = logout_dt = None
|
||||
if last_ok:
|
||||
ok_dt = datetime.strptime(last_ok, "%Y-%m-%d %H:%M:%S")
|
||||
entry["session_age_hours"] = round((now - ok_dt).total_seconds() / 3600, 1)
|
||||
if last_err:
|
||||
err_dt = datetime.strptime(last_err, "%Y-%m-%d %H:%M:%S")
|
||||
if last_logout:
|
||||
logout_dt = datetime.strptime(last_logout, "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# Check docker logs for recent login (catches fresh logins before webhook sees them)
|
||||
# Check webhook log for login event
|
||||
@@ -642,7 +657,18 @@ def _augment_wechat_status(entry):
|
||||
except ValueError:
|
||||
pass
|
||||
dlogin_dt = _docker_login_check()
|
||||
if err_dt and login_dt and login_dt > err_dt:
|
||||
# Logout is the most authoritative signal: if logout happened after the last login, session is dead
|
||||
if logout_dt and login_dt and logout_dt > login_dt:
|
||||
entry["login_ok"] = False
|
||||
h = round((now - logout_dt).total_seconds() / 3600, 1)
|
||||
entry["message"] = "已掉线" if h < 1 else f"已掉线 {h:.0f}h"
|
||||
entry["status"] = "logged_out"
|
||||
elif logout_dt and dlogin_dt and logout_dt > dlogin_dt:
|
||||
entry["login_ok"] = False
|
||||
h = round((now - logout_dt).total_seconds() / 3600, 1)
|
||||
entry["message"] = "已掉线" if h < 1 else f"已掉线 {h:.0f}h"
|
||||
entry["status"] = "logged_out"
|
||||
elif err_dt and login_dt and login_dt > err_dt:
|
||||
entry["login_ok"] = True
|
||||
entry["session_age_hours"] = round((now - login_dt).total_seconds() / 3600, 1)
|
||||
h = entry["session_age_hours"]
|
||||
@@ -1757,10 +1783,20 @@ def api_wechat_status():
|
||||
result["last_ok_at"] = ts
|
||||
elif "WeChat send error" in line and ts and not result["last_err_at"]:
|
||||
result["last_err_at"] = ts
|
||||
if "system_event_login" in line and ts and not result.get("last_login_at"):
|
||||
result["last_login_at"] = ts
|
||||
if result["last_ok_at"] and result["last_err_at"] and result.get("last_login_at"):
|
||||
if result["last_ok_at"] and result["last_err_at"]:
|
||||
break
|
||||
# Login/logout events: search full log (not just tail -200)
|
||||
try:
|
||||
for ev, key in (("system_event_logout", "last_logout_at"), ("system_event_login", "last_login_at")):
|
||||
er = subprocess.run(["grep", ev, webhook_log],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
ev_lines = [l for l in er.stdout.strip().split("\n") if l.strip()]
|
||||
if ev_lines:
|
||||
m = re.match(r"^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})", ev_lines[-1])
|
||||
if m:
|
||||
result[key] = m.group(1)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1772,12 +1808,14 @@ def api_wechat_status():
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
ok_dt = err_dt = None
|
||||
ok_dt = err_dt = logout_dt = None
|
||||
try:
|
||||
if result["last_ok_at"]:
|
||||
ok_dt = datetime.strptime(result["last_ok_at"], "%Y-%m-%d %H:%M:%S")
|
||||
if result["last_err_at"]:
|
||||
err_dt = datetime.strptime(result["last_err_at"], "%Y-%m-%d %H:%M:%S")
|
||||
if result.get("last_logout_at"):
|
||||
logout_dt = datetime.strptime(result["last_logout_at"], "%Y-%m-%d %H:%M:%S")
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
@@ -1790,7 +1828,15 @@ def api_wechat_status():
|
||||
login_dt = datetime.strptime(result["last_login_at"], "%Y-%m-%d %H:%M:%S")
|
||||
except ValueError:
|
||||
pass
|
||||
if err_dt and login_dt and login_dt > err_dt:
|
||||
if logout_dt and login_dt and logout_dt > login_dt:
|
||||
result["online"] = False
|
||||
h = round((now - logout_dt).total_seconds() / 3600, 1)
|
||||
result["message"] = "已掉线" if h < 1 else f"已掉线 {h:.0f}h 前"
|
||||
elif logout_dt and dlogin_dt and logout_dt > dlogin_dt:
|
||||
result["online"] = False
|
||||
h = round((now - logout_dt).total_seconds() / 3600, 1)
|
||||
result["message"] = "已掉线" if h < 1 else f"已掉线 {h:.0f}h 前"
|
||||
elif err_dt and login_dt and login_dt > err_dt:
|
||||
result["online"] = True
|
||||
result["session_age_hours"] = round((now - login_dt).total_seconds() / 3600, 1)
|
||||
h = result["session_age_hours"]
|
||||
|
||||
Reference in New Issue
Block a user