From 0265de117a1d697cb3e81d36286eaf7671b673f5 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Wed, 8 Jul 2026 15:21:05 +0800 Subject: [PATCH] =?UTF-8?q?docs(log-kit):=20=E6=B7=BB=E5=8A=A0=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E7=B3=BB=E7=BB=9F=E6=94=B9=E8=BF=9B=E7=95=99=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 记录背景、已完成内容、文件格式、平台默认配置 - 说明 GameLog 用法与后续待补足项 --- Docs/日志系统改进留档.md | 164 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 Docs/日志系统改进留档.md diff --git a/Docs/日志系统改进留档.md b/Docs/日志系统改进留档.md new file mode 100644 index 000000000..ecc2a085a --- /dev/null +++ b/Docs/日志系统改进留档.md @@ -0,0 +1,164 @@ +# 日志系统改进留档 + +## 背景与目的 + +旧日志系统直接订阅 Unity 日志回调,把 `Debug.*` 输出同步写入文件。这个实现有几个明显问题: + +- 每条日志同步 `WriteLine`,并且 `AutoFlush = true`,移动端写盘成本容易造成卡顿。 +- Android 因性能问题被编译条件直接禁用文件日志,真机问题缺少可追踪依据。 +- 日志格式只接近“控制台文本转储”,缺少等级、分类、场景、帧号、线程、会话等排查信息。 +- 文件按天追加,同一天多次启动会混在一起,不利于定位一次具体测试或玩家反馈。 +- `Application.logMessageReceivedThreaded` 可能从多线程进入,但旧实现直接操作同一个 `StreamWriter`,线程安全不足。 + +本次改进目标是建立一套可以在 PC 与 Android 都安全启用的轻量文件日志系统:降低写盘卡顿风险,保留 Unity 日志兼容入口,并为后续业务结构化日志打基础。 + +## 已完成内容 + +核心代码位于 `Assets/Scripts/Framework/LogKit/`: + +- `LogKit.cs` + - 保留运行时自动初始化入口。 + - 继续订阅 `Application.logMessageReceivedThreaded`,捕获旧有 `Debug.Log/Warning/Error`。 + - 新增 `GameLog` 业务日志入口,支持按 `LogCategory` 分类输出。 + - 新增 `LogLevel`、`LogCategory`、`LogEntry`、`LogFormatter`,把日志记录转换为结构化文本行。 + - 应用失焦和退出时触发 flush,降低日志丢失概率。 + +- `FileLogger.cs` + - 从同步写文件改为线程安全队列 + 后台线程批量写入。 + - 关闭每条日志 `AutoFlush`,改为批量 flush。 + - 队列满时丢弃低优先级日志,并记录 dropped count。 + - `Error` 及以上等级优先保留。 + - 按 session 创建日志文件,并支持大小轮转、总大小/文件数量保留。 + - 日志写入器内部异常静默降级,避免日志系统自身递归刷错误。 + +- `LogSettingsProfiles.cs` + - 将平台配置从 `LogKit.cs` 中抽离为轻量 C# profile。 + - 不使用 JSON、StreamingAssets 或 ScriptableObject,避免额外资源加载和 Unity asset 依赖。 + - 当前 profile 包括 `Editor`、`AndroidDevelopment`、`AndroidRelease`、`StandaloneDevelopment`、`StandaloneRelease`。 + +## 日志文件与格式 + +日志目录仍使用 `ConstRef.LogFilePath`,即 `Application.persistentDataPath/LogFile`。 + +文件按启动会话生成,命名格式类似: + +```text +20260708_153012_android_v1.2.0_session-abcd1234.log +``` + +单行日志包含: + +```text +timestamp | level | category | scene | frame | thread | context | message | stack +``` + +说明: + +- `timestamp` 使用 UTC ISO 格式。 +- `category` 可区分 Unity 捕获日志和业务系统日志。 +- 非主线程日志不会读取 Unity 场景和帧号,避免在线程回调中访问 Unity 主线程 API。 +- 普通日志默认不写堆栈;`Error/Exception/Assert` 写入堆栈。 + +## 平台默认配置 + +当前配置集中在 `LogSettingsProfiles.cs`。 + +### Editor + +- 默认不写文件日志。 +- 仍保留 Unity Console 的正常输出。 + +### Android Development + +- 文件日志启用。 +- 最低等级:`Info`。 +- 队列容量:`1024`。 +- 批量写入:`64` 条。 +- Flush 间隔:`1500ms`。 +- 单文件上限:`5MB`。 +- 总保留上限:`30MB`。 +- Session 文件保留:`6` 个。 + +### Android Release + +- 文件日志启用。 +- 最低等级:`Warning`。 +- Console 最低等级:`Warning`。 +- 其余写入参数与 Android Development 保持一致。 + +### Standalone Development / Release + +- 文件日志启用。 +- Development 最低等级:`Info`,Console 最低等级:`Debug`。 +- Release 最低等级:`Info`,Console 最低等级:`Info`。 +- 队列容量:`2048`。 +- 批量写入:`128` 条。 +- Flush 间隔:`1000ms`。 +- 单文件上限:`10MB`。 +- 总保留上限:`100MB`。 +- Session 文件保留:`20` 个。 + +## 如何使用 + +旧代码中的 `Debug.Log/Warning/Error` 不需要立刻迁移,仍会被捕获到文件日志。 + +新代码或关键链路建议使用 `GameLog`: + +```csharp +GameLog.Info(LogCategory.Save, "Auto save completed", "slot=0"); +GameLog.Warn(LogCategory.Resource, "Addressable load slow", "key=Scene/ClinicOut"); +GameLog.Error(LogCategory.Yarn, "Node missing", "node=Start"); +``` + +优先迁移高价值排查链路,而不是一次性替换全项目日志: + +- 存档/读档:`SaveRestoreOrchestrator`、`SaveSystem` +- 对话:`DialogController`、Yarn node 进入/退出 +- 资源:`ResourceSystem`、`SceneResourceLoader` +- 场景:`SceneLoader` +- 维修系统入口:`FixSystemCenter` + +## 已验证内容 + +本次实现后已执行: + +```bash +git diff --check -- Assembly-CSharp.csproj Assets/Scripts/Framework/LogKit +dotnet build Assembly-CSharp.csproj --no-restore +``` + +结果: + +- 空白检查通过。 +- `Assembly-CSharp.csproj` 构建通过,0 个错误。 +- 构建中的 warning 为项目既有 warning,与日志系统改动无关。 + +## 仍需补足 + +后续建议按优先级补足以下内容: + +1. Android 真机压测 + - 在 Android Development build 中压测高频 `Debug.Log`。 + - 对比启用日志前后的帧率和卡顿尖刺。 + - 验证切后台、返回、退出时日志能正常 flush。 + +2. 关键业务链路迁移到 `GameLog` + - 先迁移 Save、Resource、Dialog、Scene 这些排查价值最高的系统。 + - 不建议批量替换所有旧 `Debug.Log`,避免制造无意义 diff。 + +3. 重复日志限流 + - 当前已有队列满时低等级丢弃机制。 + - 仍可补充同一 message 短时间重复出现时的合并策略,减少高频系统刷屏。 + +4. 日志导出入口 + - 增加获取当前日志目录或当前 session 日志路径的 API。 + - 后续可接入设置界面或测试菜单,方便测试人员导出日志。 + +5. 配置开关扩展 + - 当前 profile 是代码内固定配置。 + - 如果未来测试需要临时打开 Release `Info` 日志,可考虑增加启动参数、调试菜单或本地轻量覆盖开关。 + +6. Unity 工程文件同步 + - 本次为了命令行构建验证,手动把 `LogSettingsProfiles.cs` 加入了 `Assembly-CSharp.csproj`。 + - Unity 重新生成工程文件时可能覆盖 `.csproj`,这是 Unity 生成文件的正常行为;源码和 `.meta` 才是长期留档重点。 +