set-tg-bot: 3 попытки getMe timeout=15 + backoff 3/6с (t-261016141220)
This commit is contained in:
parent
0f7d63722c
commit
b2391c2b5b
2 changed files with 55 additions and 10 deletions
35
cli.py
35
cli.py
|
|
@ -187,6 +187,9 @@ def main():
|
||||||
p_mcp.add_argument("--list", action="store_true", help="показать тулы шлюза и выйти")
|
p_mcp.add_argument("--list", action="store_true", help="показать тулы шлюза и выйти")
|
||||||
p_mcp.add_argument("--timeout", type=int, default=None, help="таймаут запроса, сек")
|
p_mcp.add_argument("--timeout", type=int, default=None, help="таймаут запроса, сек")
|
||||||
|
|
||||||
|
p_mcs = sub.add_parser("mcp-stats", help="статистика MCP-вызовов по журналу mcp_calls.log (t-261015091108)")
|
||||||
|
p_mcs.add_argument("--tail", type=int, default=10, help="последние N вызовов (0 — только сводка)")
|
||||||
|
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
||||||
if args.cmd == "init":
|
if args.cmd == "init":
|
||||||
|
|
@ -447,6 +450,38 @@ def main():
|
||||||
ap.error("mcp-call: укажи tool (или --list)")
|
ap.error("mcp-call: укажи tool (или --list)")
|
||||||
kw = {"timeout": args.timeout} if args.timeout else {}
|
kw = {"timeout": args.timeout} if args.timeout else {}
|
||||||
print(portal_mcp.call_tool(args.tool, args.arguments, **kw))
|
print(portal_mcp.call_tool(args.tool, args.arguments, **kw))
|
||||||
|
elif args.cmd == "mcp-stats":
|
||||||
|
# t-261015091108: статистика MCP-вызовов из журнала mcp_calls.log
|
||||||
|
import collections
|
||||||
|
log_path = os.path.join(_paths.home(), "mcp_calls.log")
|
||||||
|
if not os.path.exists(log_path):
|
||||||
|
print("(журнала ещё нет — mcp_calls.log пуст, вызовов не было)")
|
||||||
|
return
|
||||||
|
rows = []
|
||||||
|
with open(log_path, encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
rows.append(json.loads(line))
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
by_tool = collections.Counter(r.get("tool", "?") for r in rows)
|
||||||
|
by_level = collections.Counter(r.get("level", "?") for r in rows)
|
||||||
|
fails = sum(1 for r in rows if not r.get("ok"))
|
||||||
|
ms = [r.get("ms", 0) for r in rows if isinstance(r.get("ms"), int)]
|
||||||
|
print(f"всего вызовов: {len(rows)} (ошибок: {fails})")
|
||||||
|
if ms:
|
||||||
|
print(f"время ответа: медиана {sorted(ms)[len(ms)//2]}мс, макс {max(ms)}мс")
|
||||||
|
print("по тулам: " + ", ".join(f"{k}×{v}" for k, v in by_tool.most_common()))
|
||||||
|
print("по уровням: " + ", ".join(f"{k}×{v}" for k, v in by_level.most_common()))
|
||||||
|
if args.tail:
|
||||||
|
print(f"\nпоследние {min(args.tail, len(rows))}:")
|
||||||
|
for r in rows[-args.tail:]:
|
||||||
|
args_s = json.dumps(r.get("arguments", {}), ensure_ascii=False)[:120]
|
||||||
|
print(f"{r.get('ts','?')} [{r.get('level','?')}] {r.get('tool','?')} "
|
||||||
|
f"{'ok' if r.get('ok') else 'FAIL'} {r.get('ms','?')}мс {args_s}")
|
||||||
elif args.cmd == "escalate":
|
elif args.cmd == "escalate":
|
||||||
es.init_db()
|
es.init_db()
|
||||||
eid, to_level = commands.raise_escalation(
|
eid, to_level = commands.raise_escalation(
|
||||||
|
|
|
||||||
|
|
@ -298,17 +298,27 @@ def _apply_tg_command(text: str) -> None:
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
# 1) самотест токена ДО записи: getMe от Telegram
|
# 1) самотест токена ДО записи: getMe от Telegram
|
||||||
try:
|
# (t-261016141XXX: 3 попытки с паузой — таймаут сети не должен ронять привязку)
|
||||||
req = urllib.request.Request(f"https://api.telegram.org/bot{token}/getMe")
|
me = None
|
||||||
with urllib.request.urlopen(req, timeout=10) as r:
|
_last_err = None
|
||||||
me = json.loads(r.read().decode())
|
for _attempt in range(3):
|
||||||
if not (me.get("ok") and (me.get("result") or {}).get("username")):
|
try:
|
||||||
raise RuntimeError(str(me)[:150])
|
req = urllib.request.Request(f"https://api.telegram.org/bot{token}/getMe")
|
||||||
uname = me["result"].get("username") or "bot"
|
with urllib.request.urlopen(req, timeout=15) as r:
|
||||||
except Exception as e:
|
me = json.loads(r.read().decode())
|
||||||
_report(f"❌ TG-токен не принят Telegram (getMe): {e}")
|
if not (me.get("ok") and (me.get("result") or {}).get("username")):
|
||||||
print(f"[set-tg] токен не валиден: {e}", flush=True)
|
raise RuntimeError(str(me)[:150])
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
_last_err = e
|
||||||
|
me = None
|
||||||
|
if _attempt < 2:
|
||||||
|
time.sleep(3 * (_attempt + 1))
|
||||||
|
if me is None:
|
||||||
|
_report(f"❌ TG-токен не принят Telegram (getMe, 3 попытки): {_last_err}")
|
||||||
|
print(f"[set-tg] токен не валиден: {_last_err}", flush=True)
|
||||||
return
|
return
|
||||||
|
uname = me["result"].get("username") or "bot"
|
||||||
# 2) аллоулист: из команды (allowed=…), иначе сохранённый в .env
|
# 2) аллоулист: из команды (allowed=…), иначе сохранённый в .env
|
||||||
allowed = payload.get("allowed") or payload.get("owner_tg") or ""
|
allowed = payload.get("allowed") or payload.get("owner_tg") or ""
|
||||||
if not allowed:
|
if not allowed:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue