Files
aibis-dream/Docs/日志系统改进留档.md
T
dingyuntian 0265de117a docs(log-kit): 添加日志系统改进留档
- 记录背景、已完成内容、文件格式、平台默认配置
- 说明 GameLog 用法与后续待补足项
2026-07-08 15:21:05 +08:00

6.2 KiB
Raw Blame History

日志系统改进留档

背景与目的

旧日志系统直接订阅 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 分类输出。
    • 新增 LogLevelLogCategoryLogEntryLogFormatter,把日志记录转换为结构化文本行。
    • 应用失焦和退出时触发 flush,降低日志丢失概率。
  • FileLogger.cs

    • 从同步写文件改为线程安全队列 + 后台线程批量写入。
    • 关闭每条日志 AutoFlush,改为批量 flush。
    • 队列满时丢弃低优先级日志,并记录 dropped count。
    • Error 及以上等级优先保留。
    • 按 session 创建日志文件,并支持大小轮转、总大小/文件数量保留。
    • 日志写入器内部异常静默降级,避免日志系统自身递归刷错误。
  • LogSettingsProfiles.cs

    • 将平台配置从 LogKit.cs 中抽离为轻量 C# profile。
    • 不使用 JSON、StreamingAssets 或 ScriptableObject,避免额外资源加载和 Unity asset 依赖。
    • 当前 profile 包括 EditorAndroidDevelopmentAndroidReleaseStandaloneDevelopmentStandaloneRelease

日志文件与格式

日志目录仍使用 ConstRef.LogFilePath,即 Application.persistentDataPath/LogFile

文件按启动会话生成,命名格式类似:

20260708_153012_android_v1.2.0_session-abcd1234.log

单行日志包含:

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 最低等级:InfoConsole 最低等级:Debug
  • Release 最低等级:InfoConsole 最低等级:Info
  • 队列容量:2048
  • 批量写入:128 条。
  • Flush 间隔:1000ms
  • 单文件上限:10MB
  • 总保留上限:100MB
  • Session 文件保留:20 个。

如何使用

旧代码中的 Debug.Log/Warning/Error 不需要立刻迁移,仍会被捕获到文件日志。

新代码或关键链路建议使用 GameLog

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");

优先迁移高价值排查链路,而不是一次性替换全项目日志:

  • 存档/读档:SaveRestoreOrchestratorSaveSystem
  • 对话:DialogController、Yarn node 进入/退出
  • 资源:ResourceSystemSceneResourceLoader
  • 场景:SceneLoader
  • 维修系统入口:FixSystemCenter

已验证内容

本次实现后已执行:

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 才是长期留档重点。