Repository navigation
fix(logging): 按 loguru 契约传递占位符和异常信息 - #1139
Conversation
loguru 使用 {} 格式化,标准 logging 的 %s 占位符会原样输出,exc_info
关键字也不会附加堆栈。统一改为 {} 与 logger.opt(exception=True),并新增
静态 unit guard 防止回归。
验证:新增 guard 5 passed;ruff check/format/import 检查通过;
verify_engineering_contracts 通过。完整 unit/integration 未在当前 Windows
环境运行。
xerrors
left a comment
There was a problem hiding this comment.
独立语义审查通过。审查基于完整 PR 差异及与当前 main c792eabca 的无冲突合并候选,PR head 为 9e80d5e2d97227d539b27b84eaabc0f557003cc3。17 个生产模块的修改均限于 loguru 调用,没有误改标准 logging 或业务控制流;独立 Reviewer 对旧源码的负控发现 55 处违规,真实 loguru sink 也确认插值和 traceback 得到修复。没有未解决的可行动问题。
维护者验证:
- 合并候选完整后端 unit:3644 passed、11 skipped,JUnit 已回读;跳过项不计为通过。
- 新日志契约测试:5 passed。
- 工程 verifier 通过;验证器单测 56 项通过。
- Ruff lint、format、import 检查全部通过;文档构建和补丁检查通过。
- CodeQL 已通过;合并前继续等待现有 CI 的服务集成和系统 E2E,不用本地 unit 结果替代它们。
实际命令(在独立检出执行,未更改主工作区、未重启业务服务):
python3 scripts/ci/verify_engineering_contracts.py
python3 -m unittest scripts.ci.test_verify_engineering_contracts
git diff --cached --check
/home/zwj/workspace/projects/Yuxi-v1/backend/.venv/bin/ruff check backend/yuxi backend/test/unit/server/test_loguru_logging_contract.py
/home/zwj/workspace/projects/Yuxi-v1/backend/.venv/bin/ruff format backend/yuxi backend/test/unit/server/test_loguru_logging_contract.py --check
/home/zwj/workspace/projects/Yuxi-v1/backend/.venv/bin/ruff check --select I backend/yuxi backend/test/unit/server/test_loguru_logging_contract.py
node docs/node_modules/vitepress/bin/vitepress.js build docs完整 unit 使用现有 Compose API 镜像,但放在无网络、没有业务数据挂载的一次性容器中,确保读取的是 PR 与当前 main 的合并候选:
docker run --rm --network none --group-add 1001 --entrypoint /bin/sh --mount type=bind,source=/tmp/yuxi-pr1139-merge-20261102,target=/repo --mount type=bind,source=/tmp/yuxi-pr1139-evidence,target=/evidence --workdir /repo/backend -e PYTHONPATH=/repo/backend -e PYTHONDONTWRITEBYTECODE=1 main-api:0.8.0.beta6 -c 'uv run --no-sync --group test pytest test/unit -m "not slow" -q -o cache_dir=/tmp/pytest-cache --junitxml=/evidence/unit.xml'首次执行因容器与宿主 UID 不一致,JUnit 报告写入失败,未计为通过;修正临时报告目录组权限后,上述完整集合重新执行并成功落盘。未在本地运行真实外部模型、完整服务集成或 E2E;后两者以当前 CI 结果为准。纯日志调用修复不改变业务状态、权限或持久化。
|
合并前补充验证:当前 CI 与 CodeQL 均已成功, 本地 API 镜像 unit 的 11 项 skip 均因镜像缺 Docker Compose CLI;已对同一合并候选在宿主执行以下命令,207 passed、0 skipped,覆盖这些部署配置检查: PYTHONPATH=/tmp/yuxi-pr1139-merge-20261102/backend /home/zwj/workspace/projects/Yuxi-v1/backend/.venv/bin/python -m pytest backend/test/unit/config -q -o cache_dir=/tmp/yuxi-pr1139-config-cache --junitxml=/tmp/yuxi-pr1139-evidence/config.xml远端其余 skip 如实保留:
合并候选 tree 为 |
问题
项目统一使用 loguru,但部分调用仍按标准
logging的习惯传递%s占位符和exc_info=True。loguru 使用{}格式化,%s会原样留在日志中;exc_info不是 loguru 的异常参数,logger.error(..., exc_info=True)不会输出堆栈。受影响日志覆盖 Run 派发、lease 续租、后台作业、取消恢复和 Langfuse 清理,排障时丢失run_id、job_id、turn_id、phase与 traceback。复现:
改动
%s/%d/%i/%f/%r占位符改为{}。logger.error/warning(..., exc_info=True)改为logger.opt(exception=True).error/warning(...)。sandbox_runner与tool_error_guard中标准logging的%s用法。%占位符与exc_info关键字;同时提供负向样例和标准 logging 不误报样例。docs/develop-guides/decisions/implemented/2026-11-02-loguru-logging-contract.md。验证
已执行:
风险
仅日志文本与异常堆栈变化,不改变业务状态、接口、持久化或事件顺序。新增 guard 会阻止后续 loguru 调用重新引入标准 logging 约定。