Skip to content

refactor(logging): 新增项目运行态日志分流能力#2199

Open
ShadowLemoon wants to merge 2 commits into
mainfrom
feat/split-log
Open

refactor(logging): 新增项目运行态日志分流能力#2199
ShadowLemoon wants to merge 2 commits into
mainfrom
feat/split-log

Conversation

@ShadowLemoon
Copy link
Copy Markdown
Collaborator

@ShadowLemoon ShadowLemoon commented Apr 25, 2026

  • 在框架层新增项目运行态日志分流能力
  • 保持默认 OneDragon 日志行为不变,由项目显式启用分流
  • 使用 delay=True 减少日志文件提前占用

Summary by CodeRabbit

发布说明

  • 新功能

    • 支持在运行器进程中按需将项目日志与框架日志分离到独立文件,GUI 默认日志保持不变
    • 保持外部添加的日志处理器不被覆盖,支持针对不同日志目标独立设置级别
    • 日志轮转按午夜执行,保留近三份备份,并包含针对 Windows 的重复处理器冲突缓解策略
  • 文档

    • 新增详细日志路由与运行时配置文档,包含期望的文件布局与配置说明

- 在框架层新增项目运行态日志分流能力
- 保持默认 OneDragon 日志行为不变,由项目显式启用分流
- 使用 delay=True 减少日志文件提前占用
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 67ec9cf2-35a2-4510-ac3a-dffc525d63f3

📥 Commits

Reviewing files that changed from the base of the PR and between 3f4b003 and 00d96b2.

📒 Files selected for processing (1)
  • docs/develop/one_dragon/modules/logger.md
✅ Files skipped from review due to trivial changes (1)
  • docs/develop/one_dragon/modules/logger.md

📝 Walkthrough

漫游

引入按运行时划分的日志配置:新增配置驱动的日志工具和文档,提供 configure_project_runtime_logging(...),将项目日志与框架日志分流到独立文件,使用处理程序所有权标记仅移除框架自有处理程序,保留外部附加处理程序。

变更

Cohort / File(s) Summary
文档
docs/develop/one_dragon/modules/logger.md
新增日志路由设计文档,说明运行时日志分流、configure_project_runtime_logging(...) 的用法、处理程序所有权规则、轮转配置与 Windows 并发写入缓解策略。
日志工具实现
src/one_dragon/utils/log_utils.py
重构日志模块:添加 LoggerConfigProjectRuntimeLoggingContext 数据类;引入 configure_logger()get_or_create_logger()get_log_formatter()get_log_file_path()configure_project_runtime_logging();改写 get_logger() 为基于新配置获取;set_log_level() 签名新增可选 logger 参数;实现基于 _HANDLER_OWNER_ATTR 的内部处理程序标记与保护外部处理程序逻辑;默认文件路径解析到 .log/ 工作目录并配置 TimedRotatingFileHandler(午夜轮转、interval=1、backupCount=3、delay=True)。

序列图

sequenceDiagram
    participant App as 应用程序
    participant Config as configure_project_runtime_logging()
    participant ProjLogger as 项目日志记录器
    participant FwLogger as 框架日志记录器
    participant FileHandler as TimedRotatingFileHandler
    participant Console as 控制台处理程序
    participant Context as ProjectRuntimeLoggingContext

    App->>Config: 调用 configure_project_runtime_logging(project_logger_name, project_log_file_path, framework_log_file_path, ...)
    Config->>ProjLogger: get_or_create_logger(project_name) / configure_logger(...)
    Config->>FwLogger: get_or_create_logger(framework_name) / configure_logger(...)
    Config->>FileHandler: 为项目/框架创建带所有权标记的文件处理程序
    FileHandler-->>ProjLogger: 附加至项目日志器(内部所有)
    FileHandler-->>FwLogger: 附加至框架日志器(内部所有)
    alt 控制台启用
        Config->>Console: 创建控制台处理程序
        Console-->>ProjLogger: 可选附加
        Console-->>FwLogger: 可选附加
    end
    Config->>Context: 返回包含 logger 实例与文件路径的 ProjectRuntimeLoggingContext
    Context-->>App: 应用开始后使用返回的项目/框架日志记录器写日志
Loading

预估代码审查工作量

🎯 4 (Complex) | ⏱️ ~45 minutes

🐰 兔子悄声吟:
分流日志如两溪,
框架与项目各自栖,
处理有主不相夺,
夜色轮转留旧迹,
代码静好梦亦甜。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确地概括了本次拉取请求的主要改动:为日志系统增加项目运行态日志分流能力。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/split-log

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/one_dragon/utils/log_utils.py (2)

132-144: 建议改用 pathlib 处理路径。

仓库规范要求使用 pathlib 而非 os.path。当前 get_log_file_path 通过 os.path.isabsos.path.join 进行拼接,可以改成 pathlib.Path,对外仍返回 str,行为保持一致。

♻️ 参考改写
-def get_log_file_path(log_file_path: str | None = None, default_name: str = 'log.txt') -> str:
+def get_log_file_path(log_file_path: str | None = None, default_name: str = 'log.txt') -> str:
     """获取日志文件路径。

     - 未传 `log_file_path` 时,使用工作目录 `.log/` 下的默认文件名
     - 传相对路径/文件名时,仍然放在工作目录 `.log/` 下
     - 传绝对路径时,直接使用
     """
     configured = (log_file_path or '').strip()
     if not configured:
         configured = default_name
-    if os.path.isabs(configured):
-        return configured
-    return os.path.join(os_utils.get_path_under_work_dir('.log'), configured)
+    path = Path(configured)
+    if path.is_absolute():
+        return str(path)
+    return str(Path(os_utils.get_path_under_work_dir('.log')) / path)

并在文件顶部增加:

 import logging
-import os
+from pathlib import Path
 from contextlib import suppress

(如其它处仍依赖 os,可保留该导入。)

As per coding guidelines: “Use pathlib library for path handling instead of os.path”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/one_dragon/utils/log_utils.py` around lines 132 - 144, Replace os.path
usage in get_log_file_path with pathlib: create a Path from the configured
string (after applying (log_file_path or '').strip() and default_name fallback),
check absoluteness with Path.is_absolute(), and when not absolute join it with
the Path returned by os_utils.get_path_under_work_dir('.log') (wrap that in
Path(...)) using / or joinpath; finally return str(...) to preserve the existing
string return type. Ensure the function name get_log_file_path, the default_name
behavior, and os_utils.get_path_under_work_dir call are preserved and that other
imports remain if still needed.

147-152: get_logger 缺少返回值类型注解。

-def get_logger():
+def get_logger() -> logging.Logger:
     """获取框架默认 logger。

As per coding guidelines: “All functions and methods must include type hints”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/one_dragon/utils/log_utils.py` around lines 147 - 152, The function
get_logger currently lacks a return type annotation; update its signature to
include the proper return type hint (the logger type returned by
get_or_create_logger) so it matches the project's typing rules — locate
get_logger and add a return annotation referencing the logger class/type used by
get_or_create_logger (ensure compatibility with LOGGER_NAME and LoggerConfig
usage), and adjust any imports if needed to provide the logger type for the
annotation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/develop/one_dragon/modules/logger.md`:
- Around line 91-122: The documentation currently references two different
import paths for the same runner logging adapter; unify them to the actual
module path used in the project (the module that defines RUNNER_LOGGER_NAME,
RUNNER_LOG_FILE_NAME, RUNNER_FRAMEWORK_LOG_FILE_NAME, the log logger, and
configure_runner_runtime_logging). Update the occurrences of
`script_chainer.win_exe.runner_logging` and
`script_chainer.utils.runner_logging` so they both use the real import path that
contains configure_runner_runtime_logging and log, and ensure the code example
and the explanatory text consistently show that same module path.

---

Nitpick comments:
In `@src/one_dragon/utils/log_utils.py`:
- Around line 132-144: Replace os.path usage in get_log_file_path with pathlib:
create a Path from the configured string (after applying (log_file_path or
'').strip() and default_name fallback), check absoluteness with
Path.is_absolute(), and when not absolute join it with the Path returned by
os_utils.get_path_under_work_dir('.log') (wrap that in Path(...)) using / or
joinpath; finally return str(...) to preserve the existing string return type.
Ensure the function name get_log_file_path, the default_name behavior, and
os_utils.get_path_under_work_dir call are preserved and that other imports
remain if still needed.
- Around line 147-152: The function get_logger currently lacks a return type
annotation; update its signature to include the proper return type hint (the
logger type returned by get_or_create_logger) so it matches the project's typing
rules — locate get_logger and add a return annotation referencing the logger
class/type used by get_or_create_logger (ensure compatibility with LOGGER_NAME
and LoggerConfig usage), and adjust any imports if needed to provide the logger
type for the annotation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 81ce3003-5d7a-45c1-8b45-2f17df9f4e51

📥 Commits

Reviewing files that changed from the base of the PR and between b769423 and 3f4b003.

📒 Files selected for processing (2)
  • docs/develop/one_dragon/modules/logger.md
  • src/one_dragon/utils/log_utils.py

Comment thread docs/develop/one_dragon/modules/logger.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant