事件

在不同的 Firefox 项目中,都需要一种机制来以面向事件的格式记录、存储、发送和分析应用程序的使用情况。事件遥测指定了一种通用的事件数据格式,从而允许更广泛地共享数据处理工具。在制品版本和更快的构建工作流程中都支持添加事件。

对于记录到 Firefox 遥测中的事件,我们还提供了一个 API,它不透明地处理存储并提交到我们的服务器。

重要

Firefox 中每个新的或更改的数据收集都需要来自数据管理员的 数据收集审查

序列化格式

事件以 “事件” Ping 的形式作为数组提交,例如:

[
  [2147, "ui", "click", "back_button"],
  [2213, "ui", "search", "search_bar", "google"],
  [2892, "ui", "completion", "search_bar", "yahoo",
    {"querylen": "7", "results": "23"}],
  [5434, "dom", "load", "frame", null,
    {"prot": "https", "src": "script"}],
  // ...
]

每个事件都采用以下形式:

[timestamp, category, method, object, value, extra]

其中各个字段为:

  • timestamp: Number,正整数。这是记录事件时相对于主进程启动时间的时间(以毫秒为单位)。

  • category: String,标识符。类别是事件的组名称,有助于避免名称冲突。

  • method: String,标识符。描述发生的事件类型,例如 clickkeydownfocus

  • object: String,标识符。这是事件发生的物体,例如 reload_buttonurlbar

  • value: String,可选,可能是 null。这是一个用户定义的值,提供事件的上下文。

  • extra: Object,可选,可能是 null。这是一个 {"key": "value", ...} 形式的对象,键和值都需要是字符串,键是标识符。这用于需要更丰富上下文的事件。

限制

每个标记为标识符的 String(事件 namecategorymethodobject 以及 extra 的键)都限制为由字母数字 ASCII 字符 ([a-zA-Z0-9]) 以及中缀下划线('_' 字符,不能是第一个或最后一个字符)组成。category 也允许中缀句点('.' 字符,只要它们不是第一个或最后一个字符)。

对于 Firefox 遥测实现,一些字段受长度限制:

  • category: 最大字节长度为 30

  • method: 最大字节长度为 20

  • object: 最大字节长度为 20

  • value: 最大字节长度为 80

  • extra: 最大键数为 10

    • 每个额外的键名称:最大字符串长度为 15

    • 每个额外值:最大字节长度为 80

如果超过指定长度,则只会截断 valueextra 的值。任何其他超过限制的 String 都将被报告为错误,并且操作将中止。

YAML 定义文件

记录到 Firefox 遥测中的任何事件都必须在记录之前进行注册。对于作为 Firefox 的一部分发布的任何代码,都会在 Events.yaml 中发生。

定义文件中的探针以固定深度的三级结构表示。第一级包含类别名称(将多个事件组合在一起),第二级包含事件名称,事件属性列在事件名称下。例如:

# The following is a category of events named "browser.ui".
browser.ui:
  click: # This is the event named "click".
    objects: ["reload-btn"] # List the objects for this event.
    description: >
      Describes this event in detail, potentially over
      multiple lines.
    # ... and more event properties.
  # ... and more events.
# This is the "dom" category.
search:
  # And the "completion" event.
  completion:
    # ...
    description: Recorded when a search completion suggestion was clicked.
    extra_keys:
      distance: The edit distance to the current search query input.
      loadtime: How long it took to load this completion entry.
  # ...

类别和事件名称受 上面指定的限制

以下事件属性有效:

  • methods (可选,字符串列表):有效的事件方法。如果未设置,则默认为 [eventName]

  • objects (必需,字符串列表):有效的事件对象。

  • description (必需,字符串):事件及其语义的描述。

  • release_channel_collection (可选,字符串):可以设置为 opt-in(默认值)或 opt-out

  • record_in_processes (必需,字符串列表):可以记录事件的进程列表。当前支持的值为:

    • main

    • content

    • gpu

    • all_children(在所有子进程中记录)

    • all(在所有进程中记录)。

  • bug_numbers (必需,数字列表):与该事件相关的 Bugzilla 错误编号列表。

  • notification_emails (必需,字符串列表):该事件所有者的电子邮件列表。这用于数据审查的联系方式,并可能用于发送电子邮件警报。

  • expiry:有两个属性可以指定过期时间,至少需要设置一个:

    • expiry_version (必需,字符串):事件过期时的版本号,例如 "50""never"。类型为“N”的版本号会自动转换为“N.0a1”,以便在开发渠道中使事件过期。对于永不过期的事件,可以使用值 never

  • extra_keys (可选,对象):指定 extra 参数的有效键和描述的对象 - 请参阅上面的示例。

  • products (必需,字符串列表):可以在其上记录事件的产品列表。当前支持的值为:

    • firefox - 在 Firefox 桌面版中收集,并通过 Firefox 遥测提交。

    • thunderbird - 在 Thunderbird 中收集,并通过 Thunderbird 遥测提交。

注意

文件中定义的 categorymethodobject 的组合必须唯一。

API

公共 JS API

从 Firefox 132 开始(请参阅 错误 1863031),Firefox 桌面版中的事件 使用 Glean API 记录

注意

存储、提交和查询事件可能很昂贵。您有责任确保您不会提交过多事件。当您的新事件进入 Nightly 时,请咨询数据组织,了解它们是否过于“健谈”。

内部 API

Services.telemetry.snapshotEvents(dataset, clear, eventLimit);
Services.telemetry.clearEvents();

这些函数仅供遥测内部或测试使用。

此外,当事件 Ping 事件限制达到(1000 条事件记录)时,会通知 event-telemetry-storage-limit-reached 主题。这仅用于内部或测试。

事件摘要

在任何未过期的已注册事件上调用 recordEvent 将累积到 标量,以便轻松分析采用率和使用模式。即使事件类别未启用。

标量对于静态注册的事件(位于 Events.yaml 中的事件)为 telemetry.event_counts,对于动态注册的事件(通过 registerEvents 注册的事件)为 telemetry.dynamic_event_counts。这些是 键控标量,其中键的格式为 category#method#object,值是 recordEvent 使用 categorymethodobject 的组合调用次数。

这两个标量每个进程默认具有 500 个键的限制。

示例

// telemetry.event_counts summarizes in the same process the events were recorded

// Let us suppose in the parent process this happens:
Services.telemetry.recordEvent("interaction", "click", "document", "xuldoc");
Services.telemetry.recordEvent("interaction", "click", "document", "xuldoc-neighbour");

// And in each of child processes 1 through 4, this happens:
Services.telemetry.recordEvent("interaction", "click", "document", "htmldoc");

如果 interaction.click.document 是静态注册的,则这将导致父进程标量 telemetry.event_counts 具有键 interaction#click#document 且值为 2,而内容进程标量 telemetry.event_counts 具有键 interaction#click#document 且值为 4

所有动态注册的事件最终都会进入动态进程 telemetry.dynamic_event_counts(注意名称不同),无论事件是在哪个进程中记录的。从上面的示例中,如果 interaction.click.document 是使用 registerEvents 注册的,则动态进程标量 telemetry.dynamic_event_counts 将具有键 interaction#click#document 且值为 6

测试

涉及事件遥测的测试通常遵循以下三步形式

  1. Services.telemetry.clearEvents(); 为了最大程度地减少先前代码和测试的影响。

  2. runTheCode(); 这是测试的一部分,您在其中调用旨在收集事件遥测的代码。

  3. TelemetryTestUtils.assertEvents(expected, filter, options); 这将检查事件遥测记录的事件与您提供的预期事件列表。如果您只需要检查记录的事件数,则可以使用 TelemetryTestUtils.assertNumberOfEvents(expectedNum, filter, options);。这两个实用程序都具有 有用的内联文档

版本历史

  • Firefox 134:删除 operating_systemsbug 1925369)。

  • Firefox 132:recordEvent|registerEvents 弃用和移除(请参阅 bug 1863031)。

  • Firefox 79:删除 geckoview 支持(请参阅 bug 1620395)。

  • Firefox 52:初始事件支持(bug 1302663)。

  • Firefox 53:默认情况下禁用事件记录(bug 1329139)。

  • Firefox 54:添加子进程事件(bug 1313326)。

  • Firefox 56:添加了对从附加组件记录新探针的支持(bug 1302681)。

  • Firefox 58

    • 忽略为类别重新注册现有事件,而不是失败(bug 1408975)。

    • 删除了对 expiry_date 属性的支持,因为它未使用(bug 1414638)。

  • Firefox 61

    • 启用对在工件构建和构建加速工作流中添加事件的支持(bug 1448945)。

    • 添加事件汇总(bug 1440673)。

  • Firefox 66:将 cpp_guard 替换为 operating_systemsbug 1482912)`