架构¶
healthreporter.sys.mjs
包含 FHR 的主要接口,即 HealthReporter
类型。该类型的实例由 data_reporting_service
创建。
providers.sys.mjs
包含许多用于收集应用程序指标的 Metrics.Provider
和 Metrics.Measurement
。如果您正在寻找 FHR 探针,它们就在这里。
存储¶
Firefox 健康报告将数据存储在 3 个位置
指标测量和提供程序状态存储在 SQLite 数据库中(通过
Metrics.Storage
)。服务状态(例如上传文档的 ID)存储在磁盘上的 JSON 文件中(通过 OS.File)。
较少的状态和运行时选项存储在首选项中。
首选项¶
控制 Firefox 健康报告行为的首选项位于 datareporting.healthreport.*
分支中。
服务和数据控制¶
以下首选项控制服务和数据上传的行为。
- service.enabled
控制整个健康报告服务是否运行。整体服务执行数据收集、存储和提交。
这是在构建系统变量之外禁用 Firefox 健康报告的主要开关。例如,如果您使用的是正式的 Firefox 版本并希望禁用 FHR,则应将其设置为 false 以防止 FHR 不仅提交数据,还收集数据。
- uploadEnabled
是否启用数据上传。这是首选项 UI 中复选框反映的首选项。如果禁用此选项,FHR 仍会收集数据,只是不上传它。
- service.loadDelayMsec
应用程序初始启动后,FHR 应等待多长时间(以毫秒为单位)才能初始化。
如果请求 FHR 服务,FHR 可能会比此时间更早初始化。例如,如果用户访问
about:healthreport
,就会发生这种情况。- service.loadDelayFirstRunMsec
在第一次应用程序运行时,FHR 应等待多长时间(以毫秒为单位)才能初始化。
FHR 在第一次应用程序运行时等待的时间比正常时间长,因为首次初始化可能会使用大量的 I/O 来初始化 SQLite 数据库,并且此 I/O 不应干扰首次运行的用户体验。
- documentServerURI
FHR 应与之交互以提交文档的 Bagheera 服务器的 URI。
您通常不需要更改此项。
- documentServerNamespace
FHR 应将文档上传到的文档服务器上的命名空间。
您通常不需要更改此项。
- infoURL
包含有关 FHR、其隐私政策等更多信息的页面的 URL。
- about.reportUrl
在
about:healthreport
中加载的 URL。- about.reportUrlUnified
在
about:healthreport
中加载的 URL。当 UnifiedTelemetry 不是选择加入时,此项用于代替reportUrl
。- service.providerCategories
包含已注册
Metrics.Provider
记录的类别管理器类别的逗号分隔列表。请参阅下文了解提供程序注册的工作原理。
如果禁用了整个服务,则会丢失数据收集。这意味着**本地**数据分析将不可用,因为没有数据可供分析!请记住,即使 Firefox 健康报告未将数据提交到远程服务器,它也可能很有用!
日志记录¶
以下首选项允许您控制 Firefox 健康报告的日志记录行为。
- logging.consoleEnabled
是否将日志消息写入 Web 控制台。默认情况下为 true。
- logging.consoleLevel
FHR 消息必须具有的最低日志级别才能写入 Web 控制台。默认情况下,只有 FHR 警告或错误才会写入 Web 控制台。在正常/预期操作期间,不应生成此类型的消息。
- logging.dumpEnabled
是否通过
dump()
写入日志消息。如果为 true,FHR 将消息写入 stdout/stderr。这通常仅在开发 FHR 时启用。
- logging.dumpLevel
消息必须具有的最低日志级别才能通过
dump()
写入。
状态¶
- currentDaySubmissionFailureCount
客户端在尝试上传最新文档时遇到的提交失败次数。
- lastDataSubmissionFailureTime
上次文档上传失败的时间。
- lastDataSubmissionRequestedTime
上次文档上传尝试的时间。
- lastDataSubmissionSuccessfulTime
上次文档上传成功的时间。
- nextDataSubmissionTime
计划下次数据提交的时间。FHR 不会在此时间之前尝试上传新文档。
- pendingDeleteRemoteData
客户端当前是否有一个挂起的删除远程数据的请求。如果为 true,则客户端将在执行上传之前尝试删除所有远程数据。
FHR 在首选项中存储各种状态。
注册提供程序¶
Firefox 健康报告提供程序通过类别管理器注册。请参阅 HealthReportComponents.manifest
以了解在此目录中定义的提供程序。
本质上,类别管理器接收 JS 类型的名称和要导入的 sys.mjs 的 URI,该 URI 导出此符号。在运行时,将实例化在类别管理器中注册的提供程序。
提供程序通过类别管理器注册,以使注册变得简单且不易出错。任何 XPCOM 组件都可以创建类别管理器条目。因此,可以添加新的数据提供程序,而无需触及核心 Firefox 健康报告代码。此外,类别管理器注册意味着提供程序更有可能在 FHR 的条件下注册,即在 FHR 需要时注册。如果提供程序在应用程序运行时在代码中注册,则其他组件可能会过早实例化 FHR(如果在不合适的时间执行会导致性能下降)或围绕观察者或侦听器的半复杂的代码。类别管理器条目每个提供程序只有一行,并让 FHR 保持控制:它们简单且安全。
文档生成和生命周期¶
FHR 将尝试每隔 24 个墙上时钟小时提交包含数据的 JSON 文档。
在上传时,FHR 将查询数据库以获取过去 180 天的**所有**信息,并将这些数据组合到一个 JSON 文档中。我们尝试使用客户端生成的 UUID 将此 JSON 文档上传到配置的服务器。
在尝试上传之前,生成的 UUID 会存储在本地磁盘上的 JSON 状态文件中。此时,客户端假设具有该 UUID 的文档已成功存储在服务器上。
如果客户端知道其他可能存在于服务器上的文档 UUID,则这些 UUID 会与上传请求一起发送,以便客户端可以请求删除这些 UUID。这有助于确保每个客户端在任何给定时间在服务器上只有一个文档/UUID。
持久化 UUID 的重要性¶
文档 UUID 的存储和更新方式、位置和时间的选择非常重要。除非她非常详细地了解事情为何如此,否则不应尝试更改任何内容。
客户端有意地对忘记生成的 UUID 非常保守。换句话说,一旦生成 UUID,客户端就会故意保留该 UUID,直到它非常确定该 UUID 不再存储在服务器上。我们这样做的原因是因为服务器上的孤立文档/UUID 会导致错误的分析,例如过度报告停止使用的 Firefox 安装数量。
在上传新 UUID 时,我们在上传尝试之前更新状态并将状态文件保存到磁盘,因为如果上传成功但响应从未返回到客户端,我们希望客户端知道已上传的 UUID,以便它以后可以删除它以防止孤立。
我们在本地维护 UUID 列表(而不仅仅是最后一个 UUID),因为多次上传尝试可能会像上一段所述那样失败,我们无法知道哪次(如果有)实际上成功了。最安全的方法是假设每个生成的文档都设法以某种方式上传了。
我们将 UUID 存储在磁盘上的文件中,而不是其他任何地方,因为我们希望存储健壮。我们最初将 UUID 存储在首选项中,这些首选项仅定期刷新到磁盘。显然,写入首选项丢失了。我们切换到直接写入文件以消除此窗口。