"""SSH 上去看 llm_settings + enrichment_loop 状态(v2: 不用复杂 quote)""" import os import sys import paramiko HOST = "207.57.129.228" PORT = 19717 USER = "root" PASS = os.environ.get("REMOTE_PASS", "") if not PASS: print("REMOTE_PASS not set", file=sys.stderr) sys.exit(1) c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect(HOST, port=PORT, username=USER, password=PASS, timeout=30, allow_agent=False, look_for_keys=False) print("✓ 连上\n") def run(label, cmd, timeout=30): print(f"\n=== {label} ===") print(f"$ {cmd[:200]}{'...' if len(cmd) > 200 else ''}") try: si, so, se = c.exec_command(cmd, timeout=timeout) out = so.read().decode(errors="replace") err = se.read().decode(errors="replace") rc = so.channel.recv_exit_status() except Exception as e: print(f"[exception] {type(e).__name__}: {e}") return if out.strip(): print(out.rstrip()) if err.strip(): print(f"[stderr] {err.rstrip()}") print(f"-> rc={rc}") # 1) 写一个 shell 文件到远程,然后用 bash file.sh 调(避开 quote) # 把 SQL 都拼到 /tmp/check_llm.sh shell_script = r"""#!/bin/bash set -a . /srv/news/.env set +a cd /srv/news echo "--- llm_settings ---" docker compose exec -T postgres psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" \ -c "SELECT id, enabled, chat_model, image_model, interval_sec, updated_at FROM llm_settings;" echo "--- worker asyncio tasks ---" docker compose exec -T worker python <<'PYEOF' import asyncio async def main(): for t in asyncio.all_tasks(): if not t.done(): print(f'name={t.get_name()!r} done={t.done()}') asyncio.run(main()) PYEOF echo "--- worker 日志(enrich 关键字) ---" docker compose logs --tail=500 worker 2>&1 | grep -iE "enrich|llm_settings|enrichment_loop|Traceback" | head -40 """ # 写入远程 si, so, se = c.exec_command("cat > /tmp/check_llm.sh <<'EOFCAT'\n" + shell_script + "\nEOFCAT", timeout=10) so.read() se.read() so.channel.recv_exit_status() print("✓ shell 脚本已写入 /tmp/check_llm.sh\n") # 执行 run("llm_settings + asyncio + 日志", "bash /tmp/check_llm.sh", timeout=60) c.close() print("\n✓ 完成")