诊断持久性:在重新启动后保存检查结果

诊断持久性功能可在设备重启时自动捕获和存储检查数据。这可用于保留可写入 Inspect 的任何内容。

概览

  • 开发中的自动收集:在 eng 和 userdebug build 中,系统中的所有检查数据都会在重启后自动保留。无需任何配置。

  • 正式版 (user) build 需要进行隐私权配置:在正式版设备上,持久性检查数据必须在产品的 previous_boot 流水线(例如,在 go/previous-boot-pipeline 中)中明确列入许可名单,并接受隐私权审核。

  • 可在反馈和崩溃报告中使用:在生成反馈或崩溃报告时,反馈会自动提取持久性检查数据,并将其纳入快照归档(以 inspect.previous_boot.json 形式)。

用户 build 上的字段收集

在正式版 (user) build 中,出于用户隐私保护考虑,诊断数据渗漏受到限制。如需在生产设备上保留特定的 Inspect 属性或树,您必须将选择器添加到产品的 previous_boot 管道中,并完成隐私权审核。

持久性的隐私权要求在功能上与 go/tq-feedback-privacy 相同。

1. 识别检查选择器

确定所需属性或节点的精确检查选择器。 您可以使用 ffx inspect 在正在运行的设备或模拟器上检查组件。

2. 向 previous_boot 流水线添加了选择器

在产品代码库的流水线目录中,为组件创建或更新选择器配置:

  1. 在产品的 previous_boot 流水线下创建组件目录:

    //vendor/*/privacy/pipelines/previous_boot/<component_name>/inspect/
    
  2. 添加一个 .cfg 文件(例如 <component_name>.cfg),其中包含要保留的确切选择器:

    core/my_component:root/my_node:error_count
    core/my_component:root/my_node:last_failure_reason
    
  3. 更新相应的 BUILD.bazel 或流水线列表,以纳入新配置。

3. 提交以接受隐私权审核

请参阅 go/tq-feedback-privacy。

访问持久性数据

反馈报告和概览

当在重新启动后生成反馈报告或崩溃快照时,反馈会自动从持久性存储中检索上一次启动的检查数据。生成的快照包含:

  • inspect.previous_boot.json:上一次启动时的完整或过滤后的检查 JSON 树。

技术架构和行为

在底层,诊断持久性作为一种按计划运行的事件驱动型流水线快照服务运行:

┌───────────────────────────┐
│ Archivist                 │
│ ArchiveAccessor           │
│ .previous_boot pipeline   │
└─────────────┬─────────────┘
              │ Snapshot query
              ▼
┌───────────────────────────┐   writes active snapshot
│ Diagnostics Persistence   ├───► /cache/active/active.json
│                           │     /cache/active/metadata.json
│ • Periodic (every 300s)   │
│ • Low battery trigger     │   on reboot: rotate
│ • Wait for update check   ├───► /cache/previous_boot/active.json
└─────────────┬─────────────┘     /cache/previous_boot/metadata.json
              │ Serves via FIDL
              ▼
┌───────────────────────────┐
│ PreviousBootDataProvider  │
│ (e.g. Feedback component) │
└───────────────────────────┘

1. Archivist previous_boot 流水线

持久性连接到 fuchsia.diagnostics.ArchiveAccessor.previous_boot。 Archivist 会动态应用为流水线配置的许可名单选择器,或者在存在 DISABLE_FILTERING.txt 时(例如在 eng 和 userdebug build 中)绕过过滤。

2. 快照触发器

持久性使用以下两种触发器记录活跃的系统快照:

  • 周期性间隔:每 $N$ 秒运行一次(由 fuchsia.diagnostics.persist.PersistencePeriodSeconds 配置,默认值为 300 秒)。

  • 低电量触发器:连接到 fuchsia.power.battery.BatteryManager 以监控电池状态。如果电池电量降至 fuchsia.diagnostics.persist.LowBatteryThresholdPercent(默认值为 10%)或更低,系统会立即捕获快照,以保留即将关停之前的状态。

3. 从有效轮替到之前启动的轮替

  • 有效快照和元数据会保存到 /cache/active/active.json 和 /cache/active/metadata.json。

  • 在启动时,持久性会以原子方式清理 /cache/previous_boot 并将 /cache/active 移至 /cache/previous_boot。

  • 持久性数据仅保留在单个上一个启动周期内。

4. 软件更新检查门控

为了防止在更新过程中出现持续的崩溃循环,Persistence 会向 fuchsia.update.Listener 注册,并保留提供之前的启动数据,直到首次启动后软件更新检查完成为止。在 eng 和 userdebug build 中,可以跳过此检查 (skip_update_check: true)。

组装配置

可以在产品组装配置中的 diagnostics.persistence 部分下自定义持久性参数:

  • persistence_period_seconds(整数,默认值:300):ArchiveAccessor.previous_boot 上定期快照之间的时间间隔(以秒为单位)。

  • low_battery_threshold_percent(整数,默认值:10):触发立即拍摄主动快照的电池电量百分比阈值。

  • skip_update_check(布尔值,默认值:用户 build 为 false,userdebug/eng build 为 true):如果为 true,则在发布之前的启动数据之前,不会等待启动后更新检查。在 user build 上始终为 false。

常见问题解答

持久性是否适用于延迟节点?

可以。由于 Persistence 通过 ArchiveAccessor 向 Archivist 请求快照,因此 Archivist 会在每次拍摄快照时主动评估与流水线的有效选择器匹配的所有延迟节点。

.persist 配置文件去哪儿了?

旧版 .persist 文件和按标记提取调度已替换为 Archivist previous_boot 流水线。组件不再发布单独的 .persist 文件,也不再重新导出实时检查层次结构中 core/diagnostics/persistence:root/persist 下的持久性数据。所有之前的启动检查都统一到一个直接提供给反馈的快照文件中。