docs(log-kit): 添加日志系统改进留档
- 记录背景、已完成内容、文件格式、平台默认配置 - 说明 GameLog 用法与后续待补足项
This commit is contained in:
@@ -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` 才是长期留档重点。
|
||||
|
||||
Reference in New Issue
Block a user