# 12 错误日志上报 桌面客户端执行失败时,可以把这次的错误日志发给项目维护者,不需要 GitHub 账号。 ## 用户看到什么 1. 完成页出现「有步骤没成功」时,点「上报错误日志」;「反馈问题」窗口里也有这个按钮。 2. 弹出的窗口列出**要发送的全部内容**,原样展示,确认后才发送。不点「确认上报」,什么都不会发出去。 3. 成功后显示报告编号。想删除这份记录,在 GitHub 提 Issue 附上编号。 还没执行过任何步骤时,报告里只有手机型号,客户端不发送,改为提示到 GitHub 反馈(0.2.6 发布当天收到 6 份这样的空报告)。点了「停止」的步骤记为「已停止」,完成页不提示上报。 ## 发送什么 | 内容 | 说明 | |---|---| | 客户端版本、电脑系统 | 比如 `0.2.5`、`Windows 11(AMD64)` | | 手机品牌、型号、系统版本、Android 版本 | 来自检测页 | | 各步骤结果 | 步骤名、成功 / 失败 / 跳过 / 已停止、用时 | | 日志末尾 | 最多 2 万字,和「复制完整诊断」同源 | | 诊断载荷 | 页面骨架、通知权限模式等机器数据,见下一节;骨架只含结构,不含页面文字 | | 安装编号 | 第一次上报时随机生成,存在客户端数据目录的 `install-id`,只用来限频;不取任何设备或电脑标识 | 发送前在客户端替换、服务器收到后再替换一遍:手机序列号 → `<序列号>`,电脑用户目录 → `<用户目录>`,邮箱、11 位手机号、IP 地址 → `<邮箱>` `<手机号>` ``。 不发送:应用列表、通知内容、账号信息、截图、备份文件、失败现场。营销通知清单里显示的软件名只在界面上,不写进日志。 ## 诊断载荷 引擎的机器数据单独收在报告末尾的 `[诊断载荷]` 段,不进界面日志与步骤摘要。目前有两类: - **页面骨架**:渠道页认不出(「应用通知页里没找到这一行」)时附上,用来判断「渠道名到底挂在哪个控件上」。它是 #427 那类「名字只写在 CheckBox 上」的问题自动带出证据的方式,不再等报告者手动导 `uiautomator dump`。 - **通知权限模式**:访问应用通知页把 `POST_NOTIFICATION` 从 `default` 改成 `allow` 时记一行 `appops-changed <包名,逗号分隔>`,用来确认这个副作用在哪些机型上成立(#330)。 下面只说骨架的格式。 骨架**不含任何页面文字**: - 第一行:`骨架 v1 页=<包名/Activity> 目标=<渠道名> 锚=<锚定方式> 节点=<个数> 剪枝=<剪掉的个数> 屏=<宽>x<高>`。 - 之后每个节点一行:`<层级> <控件类型> <左,上,右,下> <标记> [id=<短 id>]`。 - 位置是屏宽、屏高的整数百分比(0–100),不同分辨率之间可以直接比较;层级从页面根算起。 - 标记是固定的字母:`c` 可点、`k` 可勾、`v` 已勾、`s` 可滚、`e` 未启用、`T` 有文字、`D` 有无障碍描述、`N` 文字等于渠道名、`M` 无障碍描述等于渠道名、`P` 只是包含渠道名(名字被拼进了更长的文案)。`T` / `D` 只表示「有没有字」,不表示写了什么。 - `resource-id` 只留 `:id/` 之后的短名,超过 40 字符截断。 - 体积:单份最多 4KB、最多 80 个节点;节点或字节超出时从末尾剪掉,并在第一行的「剪枝」里写明剪掉多少。 - 份数:一次执行(关闭、还原各算一次)最多 2 份。去重按页面结构(控件、位置、状态)判断,同一屏失败多少个渠道都只带第一份,只有换了布局才占第二份。 - 骨架单独收在报告末尾(`[诊断载荷]` 段),不会在「最近失败的完整诊断」里重复;日志只留最后 2 万字,它因为排在末尾不会被早先的步骤挤掉。 骨架目前是日志的一部分;服务端以后支持独立字段 `skeletons`(字符串数组,0–2 项、每项不超过 4096 字符、缺省视为空数组)时,客户端把同一份内容从日志挪过去,不会重复发送。发送前的预览窗口会原样显示骨架,和其他内容一起确认后才发送。 ## 失败现场 某一屏失败(入口没找到、点名要关的开关没找到)时,引擎把那一屏的界面结构原文存到客户端数据目录的 `captures/<任务>-<段>/` 下,同一段只留最新一份。有了它,这一处失败可以回放,不必再要一台同样的手机。 它只在图形客户端跑任务时写(桌面版与手机版同一套;源码态直接跑 `tool/run.py` 一个字节都不写), 不进日志、不随上报发送、不上传,也不自动清理 —— 确认不需要后把数据目录下的 `captures` 整个删掉即可, 源码态可以用 `python3 tool/run.py captures <数据目录>/captures` 看它占了多少地方。原文里有这一屏的界面文字,要贴到公开 Issue 时先自己看一遍,账号页、手机号页那类内容不要贴出去。 ## 版本检查 客户端启动时查一次有没有新版本:先读官网的版本文件 `ahuamiao.com/sites/other/android-ad-cleaner-latest.json`,读不到再查 GitHub 的最新发布。请求里只有客户端版本号(User-Agent),不带手机、电脑信息,也不带安装编号。有新版时左下角提示,点了打开官网下载页;不会自动下载或安装。 ## 服务器怎么存 - 发送到项目维护者自建的服务器,地址写在客户端里(`supabase.ahuamiao.com`)。 - 保存 **90 天**,到期自动删除。 - IP 不保存原文,只保存不可还原的加密哈希,用来限制上报频率;随机安装编号同样只存哈希。 - 上报通道使用单独的低权限账号,只能写入新报告,不能读取任何数据。 ## 频率限制 客户端每小时最多 3 次;服务器另按 IP 和安装编号限频,1 小时内内容完全相同的报告只收一次。超出时提示「上报太频繁,请一小时后再试」。