如何在Madeira中查看与过滤日志:LogStore与LogTail实时日志完全指南
【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu + Wine + DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira
在Madeira(运行 x86-64 Windows PC 游戏的 iOS 模拟器)中,查看日志是排查游戏启动失败、JIT 报错、Wine 崩溃的关键手段。Madeira 内置了一套实时日志系统:后台的LogTail逐行追踪日志文件,LogStore负责去重、分级、过滤,最终在应用界面的日志控制台里实时滚动显示。本文将带你快速上手:打开日志控制台、看懂颜色分级、理解自动过滤规则、找到日志文件并拉取历史日志,让你像老玩家一样快速定位问题。
实时日志系统的工作原理:LogTail 负责"追",LogStore 负责"理"
整个日志链路可以拆成两个核心模块,源码位于应用目录:
- LogTail.swift—— 后台"追文件"的读取器。它监听
madeira-log.txt的大小变化,有新字节就读取、切行,再把每一行回调出去。 - LogStore.swift—— 内存中的"日志仓库"(单例
LogStore.shared)。它接收每一行原始日志,做签名归一化、去重合并、级别识别,并批量刷新到界面。
Wine / DXMT / FEX-Emu 写入 │ dprintf / wine_log_write ▼ madeira-log.txt(Documents 目录) │ 文件监听 + 250ms 轮询兜底 ▼ LogTail(后台队列) │ 逐行回调 ▼ LogStore(过滤 → 签名 → 计数 → 批量刷新) ▼ 界面日志控制台(实时滚动列表)💡 两条腿走路:
LogTail同时用文件事件监听和每 250 毫秒一次的轮询作为兜底,因为 iOS 上跨进程的文件追加有时会让事件监听漏掉写入(见 LogTail.swift 的注释)。
如何打开日志控制台并实时查看日志
日志控制台内置在 Madeira 的主界面中,无需任何额外配置,打开应用即可看到:
- 启动 Madeira,进入主界面(竖屏模式);
- 在操作按钮区域下方,即可看到实时滚动的日志控制台,每一行包含:时间戳、级别标记、最近一条日志内容;
- 界面中的"Clear Log"按钮可一键清空当前显示并截断日志文件。
日志列表的实现位于 ContentView.swift(logConsole视图),清空按钮在 ContentView.swift:
Button("Clear Log") { logStore.clear() }📌小提示:横屏游戏模式下界面会隐藏日志区以全屏显示游戏,如需观察日志请切换到竖屏界面。
日志级别与颜色速查表:一眼分辨信息、成功、错误
LogStore把每条日志归为 4 个级别,并用不同颜色在界面中区分(LogStore.swift 与 ContentView.swift):
| 级别 | 颜色 | 含义 | 典型场景 |
|---|---|---|---|
INFO | 🔵 蓝色 | 普通信息 | 启动流程、配置加载、"Running full Wine sequence..." |
OK | 🟢 绿色 | 操作成功 | "JIT is fully functional!"、Metal 层注册成功 |
ERR | 🔴 红色 | 错误,重点关注 | "JIT not enabled"、FEX 测试失败、未处理异常 |
DBG | ⚪ 灰色 | 调试信息 | FEX-Emu 内部日志、trace 类消息 |
级别不是靠猜的——LogPattern.swift 会扫描行内容自动推断:出现fatal、unhandled、c0000005(访问冲突)等字样直接判定为错误级;出现success、ok则判定为成功级。🔍排查问题时优先滚动查看红色ERR行,它们几乎总是问题的直接线索。
自动去重与过滤:为什么你看到的日志"行数变少了"
Wine + FEX 运行时日志量极大,如果逐行堆在界面上,列表会瞬间滚没。LogStore用两个机制替你过滤:
1. 签名去重(Signature)
LogPattern.swift 会把日志行归一化成"签名":剥掉时间戳、线程号(如0024:),把十六进制地址替换成0x?、把长数字折叠成#。语义相同的行会被合并成一条,并显示出现次数徽章(如×42)。例如:
0024:trace:file:NtWriteFile = SUCCESS (52) ↓ 归一化后 T:trace:file:NtWriteFile = SUCCESS (#)这意味着你看到的一行×128,背后是 128 次相同事件——对定位"哪个模块在疯狂重试"非常有用。
2. 噪音黑名单
LogStore.swift 中的shouldDropLine会直接丢弃对排障无意义的噪音行,例如 Wine 的文件系统 trace(trace:file:WriteFile、SysCall NtWriteFile)和 FEX 的 IR 分发日志。这些"放大器"日志本身就是日志写入触发的,保留只会淹没真正的信号。
另外还有限流保护:内存中最多保留200 条不同签名(超出后淘汰最旧的),单行超长时缓冲区会在 1MB 处截断(LogTail.swift),确保界面对游戏帧率的影响被压到最低。
性能细节:为什么运行游戏时日志刷新会变慢
你可能注意到,Wine 运行时日志显示似乎"变钝了"。这其实是刻意设计(LogStore.swift):
- 平时:界面每200ms批量刷新一次;
- Wine 运行期间(
uiPaused = true):改为1.5s刷新,避免 SwiftUI 列表重绘拖累游戏的帧率节奏。
后台读取不受影响,日志照常完整写入文件,只是上屏更慢。🎮 这是"文件记录优先、界面显示次之"的取舍。
日志文件在哪里:拉取 madeira-log.txt 与历史轮转
日志持久化在沙盒 Documents 目录下(LogStore.swift):
- 当前日志:
Documents/madeira-log.txt - 上一轮日志:
Documents/madeira-log.prev.txt
Madeira 采用轮转而非删除策略:每次启动时,上一轮的madeira-log.txt会改名保存为madeira-log.prev.txt,再创建空的新日志文件。注释里写得很清楚——运行一次 Wine 会话成本很高且不一定能复现,上一轮的日志"值得花一个文件的磁盘"(LogStore.swift)。
📥实战技巧:开发调试时用设备日志拉取命令把Documents/madeira-log.txt拉到 Mac 上离线分析;如果"这次能跑、下次就挂",记得同时拉取.prev.txt对比两轮差异。
相关配置项:按需调整日志行为
两个开关会影响日志行为,默认值可在 ConfigCatalog.generated.swift 中查到:
| 配置项 | 默认 | 作用 |
|---|---|---|
MADEIRA_UI_LOG_IDLE | 1 | 界面空闲时暂停日志解析(省电),设为0可关闭暂停 |
MADEIRA_LOG_VIA_STDERR | 1 | Swift 侧日志复用 Wine 已指向该文件的 stderr 句柄,保证写入顺序一致 |
相关入口:wine_set_ui_log_callback/jit_set_log_callback把 Swift 与 JIT 层的日志也汇入同一条链路(LogStore.swift)。
常见问题速答
Q:日志区一片空白,是不是坏了?A:先确认没有处于"空闲暂停"状态,再检查游戏是否真的开始产生输出;也可以直接拉取madeira-log.txt看文件里有没有内容。
Q:为什么同一句话只有一行,却带个×N徽章?A:签名去重在起作用,N是合并的次数。想看清原始内容,界面显示的是"最近一次"的原文(lastRaw)。
Q:清空日志会影响文件吗?A:会。clear()同时清空界面条目并把madeira-log.txt截断为空(LogStore.swift),拉取到的日志会与之对应。
Q:横屏玩游戏时怎么看日志?A:横屏游戏模式隐藏了日志区,切换回竖屏主界面即可查看实时控制台。
相关文件导航
- 日志仓库与去重过滤:app/Madeira/LogStore.swift
- 后台文件追踪器:app/Madeira/LogTail.swift
- 签名归一化与级别推断:app/Madeira/LogPattern.swift
- 日志控制台界面与清空按钮:app/Madeira/ContentView.swift
- 构建与开发文档:docs/BUILDING.md
- 架构总览:ARCHITECTURE_ANALYSIS.md
掌握LogStore 的分级去重与LogTail 的实时追踪,你就拥有了 Madeira 排障的第一块拼图:先看红色ERR,再看×N高频签名,最后拉取madeira-log.txt做离线复盘——三步定位绝大多数游戏启动问题。🚀
【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu + Wine + DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考