diff --git a/gateway/scripts/dashboard.py b/gateway/scripts/dashboard.py index 8dac035..89639a4 100644 --- a/gateway/scripts/dashboard.py +++ b/gateway/scripts/dashboard.py @@ -1487,17 +1487,24 @@ def _collect_kimi_usage(): """SSH 到 Windows 跑 usage_collector_kimi.py,scp 结果回 246。 被 /api/usage/refresh 和 usage auto-timer 共用,保证 Kimi 数据新鲜。 + 注意: Windows 控制台默认 GBK 编码,SSH 输出需容错解码(bytes + errors=replace), + 否则中文日志会让 text=True 的 UTF-8 解码抛异常,导致 scp 步骤不执行。 """ log.info("usage: starting Kimi collector via SSH") kimi_cmd = [ "ssh", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10", "-o", "BatchMode=yes", "hmo@192.168.1.16", - r'"C:\Users\hmo\AppData\Local\Programs\Python\Python310\python.exe" "D:\F\NewI\opencode\daily-workspace\projects\AgentsMeeting\gateway\scripts\usage_collector_kimi.py"' + r'cmd /c "set PYTHONIOENCODING=utf-8 && C:\Users\hmo\AppData\Local\Programs\Python\Python310\python.exe D:\F\NewI\opencode\daily-workspace\projects\AgentsMeeting\gateway\scripts\usage_collector_kimi.py"' ] - proc2 = subprocess.run(kimi_cmd, capture_output=True, text=True, timeout=60) + proc2 = subprocess.run(kimi_cmd, capture_output=True, timeout=60) log.info(f"usage: Kimi done (rc={proc2.returncode})") if proc2.returncode != 0 and proc2.stderr: - log.warning(f"usage_kimi stderr: {proc2.stderr[-300:]}") + # Windows 输出可能是 GBK,容错解码 + try: + err_text = proc2.stderr.decode("utf-8", errors="replace") + except Exception: + err_text = repr(proc2.stderr[-300:]) + log.warning(f"usage_kimi stderr: {err_text[-300:]}") # scp Kimi 结果回 246 scp_cmd = [ @@ -1515,12 +1522,16 @@ def _collect_sensenova_usage(): sn_cmd = [ "ssh", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10", "-o", "BatchMode=yes", "hmo@192.168.1.16", - r'"C:\Users\hmo\AppData\Local\Programs\Python\Python310\python.exe" "D:\F\NewI\opencode\daily-workspace\projects\AgentsMeeting\gateway\scripts\usage_collector_sensenova.py"' + r'cmd /c "set PYTHONIOENCODING=utf-8 && C:\Users\hmo\AppData\Local\Programs\Python\Python310\python.exe D:\F\NewI\opencode\daily-workspace\projects\AgentsMeeting\gateway\scripts\usage_collector_sensenova.py"' ] - proc4 = subprocess.run(sn_cmd, capture_output=True, text=True, timeout=90) + proc4 = subprocess.run(sn_cmd, capture_output=True, timeout=90) log.info(f"usage: SenseNova done (rc={proc4.returncode})") if proc4.returncode != 0 and proc4.stderr: - log.warning(f"usage_sensenova stderr: {proc4.stderr[-300:]}") + try: + sn_err = proc4.stderr.decode("utf-8", errors="replace") + except Exception: + sn_err = repr(proc4.stderr[-300:]) + log.warning(f"usage_sensenova stderr: {sn_err[-300:]}") scp4 = subprocess.run([ "scp", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10", "hmo@192.168.1.16:D:/F/NewI/opencode/daily-workspace/projects/AgentsMeeting/gateway/temp/usage_stats_sensenova.json",