Files
Haocode/core/debug_log.py
T
2026-09-17 16:30:02 +08:00

79 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""统一调试日志 + 调试器窗口控制协议(纯文件通信,与主窗口 UI 零耦合)
日志文件: data/debug_session.log (环境变量 HAOCODE_DEBUG_LOG 可覆盖)
控制文件: data/debug_window.cmd (环境变量 HAOCODE_DEBUG_CMD 可覆盖)
三方写入协议:
[USER] 用户在调试窗口输入框手输的观察情况
[AGENT] 代理(外部脚本/命令行)注入的指令与备注
[APP] 应用自身事件(上下文标签变化/usage/发送/完成/报错/压缩)
[SYS] 调试窗口自身的开关事件
行格式: [YYYY-MM-DD HH:MM:SS.mmm] [TAG] 内容
控制协议: 代理往 debug_window.cmd 写入 "show" 或 "hide"(一行),
app 侧 2s QTimer 轮询并消费(读完即删)。
"""
import os
import threading
import time
_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_DATA_DIR = os.path.join(_ROOT, "data")
DEBUG_LOG_PATH = (os.environ.get("HAOCODE_DEBUG_LOG")
or os.path.join(_DATA_DIR, "debug_session.log"))
DEBUG_CMD_PATH = (os.environ.get("HAOCODE_DEBUG_CMD")
or os.path.join(_DATA_DIR, "debug_window.cmd"))
_lock = threading.Lock()
def _stamp() -> str:
t = time.time()
return (f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t))}"
f".{int(t * 1000) % 1000:03d}")
def debug_log(msg: str, tag: str = "APP") -> None:
"""线程安全追加一条日志(worker 线程亦可调用)。
静默吞掉一切异常——本模块绝不影响主流程。"""
try:
with _lock:
with open(DEBUG_LOG_PATH, "a", encoding="utf-8") as f:
f.write(f"[{_stamp()}] [{tag}] {msg}\n")
except Exception:
pass
def poll_debug_cmd():
"""消费控制文件,返回 'show' / 'hide' / None。由主线程 QTimer 周期调用。"""
try:
if os.path.exists(DEBUG_CMD_PATH):
with open(DEBUG_CMD_PATH, "r", encoding="utf-8") as f:
action = (f.read() or "").strip().lower()
try:
os.remove(DEBUG_CMD_PATH)
except Exception:
pass
if action in ("show", "hide"):
return action
except Exception:
pass
return None
def autostart_debug_window(cfg: dict) -> bool:
"""调试窗口随程序启动:cfg["debug_window_autostart"] 为 true(缺省也是 true
时向控制文件写 "show",主窗口事件循环启动后 2s 轮询即开窗。
纯文件操作(不依赖 Qt),返回是否写入。"""
try:
if not bool(cfg.get("debug_window_autostart", True)):
return False
with open(DEBUG_CMD_PATH, "w", encoding="utf-8") as f:
f.write("show\n")
return True
except Exception:
return False