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("--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()
|
||||
|
||||
if args.cmd == "init":
|
||||
|
|
@ -447,6 +450,38 @@ def main():
|
|||
ap.error("mcp-call: укажи tool (или --list)")
|
||||
kw = {"timeout": args.timeout} if args.timeout else {}
|
||||
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":
|
||||
es.init_db()
|
||||
eid, to_level = commands.raise_escalation(
|
||||
|
|
|
|||
|
|
@ -298,17 +298,27 @@ def _apply_tg_command(text: str) -> None:
|
|||
except OSError:
|
||||
pass
|
||||
# 1) самотест токена ДО записи: getMe от Telegram
|
||||
try:
|
||||
req = urllib.request.Request(f"https://api.telegram.org/bot{token}/getMe")
|
||||
with urllib.request.urlopen(req, timeout=10) as r:
|
||||
me = json.loads(r.read().decode())
|
||||
if not (me.get("ok") and (me.get("result") or {}).get("username")):
|
||||
raise RuntimeError(str(me)[:150])
|
||||
uname = me["result"].get("username") or "bot"
|
||||
except Exception as e:
|
||||
_report(f"❌ TG-токен не принят Telegram (getMe): {e}")
|
||||
print(f"[set-tg] токен не валиден: {e}", flush=True)
|
||||
# (t-261016141XXX: 3 попытки с паузой — таймаут сети не должен ронять привязку)
|
||||
me = None
|
||||
_last_err = None
|
||||
for _attempt in range(3):
|
||||
try:
|
||||
req = urllib.request.Request(f"https://api.telegram.org/bot{token}/getMe")
|
||||
with urllib.request.urlopen(req, timeout=15) as r:
|
||||
me = json.loads(r.read().decode())
|
||||
if not (me.get("ok") and (me.get("result") or {}).get("username")):
|
||||
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
|
||||
uname = me["result"].get("username") or "bot"
|
||||
# 2) аллоулист: из команды (allowed=…), иначе сохранённый в .env
|
||||
allowed = payload.get("allowed") or payload.get("owner_tg") or ""
|
||||
if not allowed:
|
||||
|
|
|
|||
Loading…
Reference in a new issue