“sync” Ping

这是一个聚合格式,包含一段时间内发生的每个同步的信息。它每 12 小时提交一次,并在浏览器关闭时提交,但前提是 syncs 属性不为空。Ping 不包含环境块,也不包含 clientId 或 profileGroupId。

syncs 属性中的每个项目都是在同步完成后生成的,无论是成功的同步还是失败的同步,并且包含与同步性能和错误信息相关的度量。

描述 Ping 的有效负载属性的精确格式的 JSON 模式文档可以在 services/sync/tests/unit/sync_ping_schema.json 中找到。

结构

{
  version: 4,
  type: "sync",
  ... common ping data
  payload: {
    version: 1,
    os : { ... }, // os data from the current telemetry environment. OS specific, but typically includes name, version and locale.
    discarded: <integer count> // Number of syncs discarded -- left out if zero.
    why: <string>, // Why did we submit the ping? Either "shutdown", "schedule", or "idchanged".
    uid: <string>, // Hashed FxA unique ID, or string of 32 zeros. If this changes between syncs, the payload is submitted.
    deviceID: <string>, // Hashed FxA Device ID, hex string of 64 characters, not included if the user is not logged in. If this changes between syncs, the payload is submitted.
    sessionStartDate: <ISO date>, // Hourly precision, ISO date in local time
    // Array of recorded syncs. The ping is not submitted if this would be empty
    syncs: [{
      when: <integer milliseconds since epoch>,
      took: <integer duration in milliseconds>,
      didLogin: <bool>, // Optional, is this the first sync after login? Excluded if we don't know.
      why: <string>, // Optional, why the sync occurred, excluded if we don't know.

      // Optional, excluded if there was no error.
      failureReason: {
        name: <string>, // "httperror", "networkerror", "shutdownerror", etc.
        code: <integer>, // Only present for "httperror" and "networkerror".
        error: <string>, // Only present for "othererror" and "unexpectederror".
        from: <string>, // Optional, and only present for "autherror".
      },

      // Optional, excluded if we couldn't get a valid uid or local device id
      devices: [{
        os: <string>, // OS string as reported by Services.appinfo.OS, if known
        version: <string>, // Firefox version, as reported by Services.appinfo.version if known
        id: <string>, // Hashed FxA device id for device
        type: <string>, // broad device "type", as reported by fxa ("mobile", "tv", etc).
        syncID: <string>, // Hashed Sync device id for device, if the user is a sync user.
      }],

      // Internal sync status information. Omitted if it would be empty.
      status: {
        sync: <string>, // The value of the Status.sync property, unless it indicates success.
        service: <string>, // The value of the Status.service property, unless it indicates success.
      },
      // Information about each engine's sync.
      engines: [
        {
          name: <string>, // "bookmarks", "tabs", etc.
          took: <integer duration in milliseconds>, // Optional, values of 0 are omitted.

          status: <string>, // The value of Status.engines, if it holds a non-success value.

          // Optional, excluded if all items would be 0. A missing item indicates a value of 0.
          incoming: {
            applied: <integer>, // Number of records applied
            succeeded: <integer>, // Number of records that applied without error
            failed: <integer>, // Number of records that failed to apply
            failedReasons: [
              name: <string> // Error message trying to apply the record
              count: <integer> // count of how many times this error occurred
            ],
          },

          // Optional, excluded if it would be empty. Records that would be
          // empty (e.g. 0 sent and 0 failed) are omitted.
          outgoing: [
            {
              sent: <integer>, // Number of outgoing records sent. Zero values are omitted.
              failed: <integer>, // Number that failed to send. Zero values are omitted.
              failedReasons: [
              name: <string> // Error message trying to apply the record
              count: <integer> // count of how many times this error occurred
            ],
            }
          ],
          // Optional, excluded if there were no errors
          failureReason: { ... }, // Same as above.

          // Timings and counts for detailed steps that the engine reported
          // as part of its sync. Optional; omitted if the engine didn't
          // report any extra steps.
          steps: {
            name: <string>, // The step name.
            took: <integer duration in milliseconds>, // Omitted if 0.
            // Optional, extra named counts (e.g., number of items handled
            // in this step). Omitted if the engine didn't report extra
            // counts.
            counts: [
              {
                name: <string>, // The counter name.
                count: <integer>, // The counter value.
              },
            ],
          },

          // Optional, excluded if it would be empty or if the engine cannot
          // or did not run validation on itself.
          validation: {
            // Optional validator version, default of 0.
            version: <integer>,
            checked: <integer>,
            took: <non-monotonic integer duration in milliseconds>,
            // Entries with a count of 0 are excluded, the array is excluded if no problems are found.
            problems: [
              {
                name: <string>, // The problem identified.
                count: <integer>, // Number of times it occurred.
              }
            ],
            // Format is same as above, this is only included if we tried and failed
            // to run validation, and if it's present, all other fields in this object are optional.
            failureReason: { ... },
          }
        }
      ],
      // Information about any storage migrations that have occurred. Omitted if it would be empty.
      migrations: [
        // See the section on the `migrations` array for detailed documentation on what may appear here.
        {
          type: <string identifier>,
          // per-type data
        }
      ]
    }],
    // The "node type" as reported by the token server. This will not change
    // from sync to sync, so is reported once per ping. Optional because it
    // will not appear if the token server omits this information, but in
    // general, we will expect all "new" pings to have it.
    syncNodeType: <string>,
    events: [
      event_array // See events below.
    ],
    histograms: { ... } // See histograms below
  }
}

info

discarded

Ping 可能只包含 "syncs" 数组中的特定数量的条目,目前为 500(由 "services.sync.telemetry.maxPayloadCount" 首选项确定)。超出此范围的条目将被丢弃,并在丢弃计数中记录。

syncs.took

这些值应该是单调的。如果我们无法获得单调的时间戳,则将在有效负载上报告 -1,并且这些值将从引擎中省略。此外,如果该值为 0(由于计时器不准确或立即完成),则该值将从引擎中省略。

uid

此属性包含 FxA 帐户标识符的哈希值,这是一个 32 个字符的十六进制字符串。如果我们无法使用 FxA 进行身份验证并且过去从未进行过身份验证,则它将是一个占位符字符串,由 32 个重复的 0 字符组成。

syncs.why

以下值之一

  • startup:这是浏览器启动后触发的第一个同步。

  • schedule:这是由于自上次同步以来时间过长而触发的同步。

  • score:此同步由同步跟踪器之一的高分值触发,表示自上次同步以来发生了许多更改。

  • user:用户手动触发了同步。

  • tabs:用户打开了已同步的标签侧边栏,这会触发同步。

syncs.status

engine.statuspayload.status.syncpayload.status.service 属性是同步错误代码,列在 services/sync/modules/constants.js 中,并且不会报告成功值。

syncs.failureReason

存储错误信息(如果存在)。始终包含“name”属性,该属性标识错误的类型。类型可以是:

  • httperror:表示我们收到了 HTTP 错误响应代码,但无法更具体地说明错误。包含以下属性

    • code:整数 HTTP 状态代码。

  • nserror:表示提供的错误代码的异常导致同步失败。

    • code:nsresult 错误代码(整数)。

  • shutdownerror:表示同步失败,因为我们在完成之前关闭了。

  • autherror:表示不可恢复的身份验证错误。

    • from:身份验证错误发生的位置,以下值之一:tokenserverfxaccountshawkclient

  • othererror:表示它是我们无法提供更多具体信息的同步错误代码。与 syncStatus 属性一样,它是一个同步错误代码,列在 services/sync/modules/constants.js 中。

    • error:标识存在哪个错误的字符串。

  • unexpectederror:表示某些其他错误导致同步失败,通常是未捕获的异常。

    • error:错误提供的消息。

  • sqlerror:表示我们从数据库查询中收到了 mozIStorageError

    • codeerror.result 属性的值,列在 此处 的常量之一。

syncs.engine.name

不会报告第三方引擎,因此仅允许以下值:addonsbookmarksclientsformshistorypasswordsprefstabs

syncs.engine.validation.problems

对于可以在自身上运行验证的引擎,一个描述已发生的验证错误的对象数组。将排除计数为 0 的项目。每个引擎都将拥有自己的它可能放在 name 字段中的项目集,但数量是有限的。请参阅 services/sync/modules/bookmark_validator.js 中的 BookmarkProblemData.getSummary 以了解示例。

syncs.devices

与该帐户关联的远程设备列表,由客户端集合报告。每个设备的 ID 使用与本地 ID 相同的算法进行哈希。

“sync” Ping 中的事件

同步 Ping 包含与它们包含在主 Ping 中相同的格式的事件,请参阅 事件

作为同步 Ping 的一部分提交的所有事件,这些事件已包含“extra”对象(事件遥测文档中描述的事件数组的第 6 个参数),还可以包含“serverTime”参数,即来自同步服务器的最新 Unix 时间戳(作为字符串)。它位于 X-Weave-Timestamp HTTP 标头中,并且在客户端尚未向服务器发出请求或出于任何其他原因没有它时可能会被省略。它包含在内是为了改善跨多个客户端的流分析。

在此 Ping 中记录的每个事件都将具有 sync 的类别。以下事件已定义,并按事件方法分类。

“sync” Ping 中的直方图

同步 Ping 包含与密码管理器使用情况的度量相关的直方图。这些直方图在主 Ping 中重复。仅当 pwmgr 代码已设置直方图时,它们才会包含在 Ping 中。当前,可以包含的直方图为

PWMGR_BLOCKLIST_NUM_SITES PWMGR_FORM_AUTOFILL_RESULT PWMGR_LOGIN_LAST_USED_DAYS PWMGR_LOGIN_PAGE_SAFETY PWMGR_NUM_PASSWORDS_PER_HOSTNAME PWMGR_NUM_SAVED_PASSWORDS PWMGR_PROMPT_REMEMBER_ACTION PWMGR_PROMPT_UPDATE_ACTION PWMGR_SAVING_ENABLED

直方图是具有以下 6 个属性的对象:- min - 最小桶大小 - max - 最大桶大小 - histogram_type - counts - 表示直方图中桶内容的数组 - ranges - 具有计算出的桶大小的数组

sendcommand

记录 Sync 将远程“命令”写入另一个客户端。这些命令导致另一个客户端执行某些操作,例如重置该客户端上的 Sync 或打开新的 URL。

  • object:正在写入的特定命令。

  • value:未使用(即 null

  • extra:具有以下属性的对象

    • deviceID:标识正在将命令发送到的设备的 GUID。

    • flowID:唯一标识此命令调用的 GUID。此 GUID

      对于发送到每个设备的标签都相同。

    • streamID:唯一标识此命令调用的特定目标的 GUID。

      此 GUID 对于发送到每个设备的标签都是唯一的(Firefox 79 中新增)。

    • serverTime:(可选)如上所述,最新的服务器时间戳。

processcommand

记录 Sync 处理了之前由其他客户端发送的远程“命令”。从逻辑上讲,这是 sendcommand 的“另一端”。

  • object:正在处理的特定命令。

  • value:未使用(即 null

  • extra:具有以下属性的对象

    • flowID:一个唯一标识此命令调用的 GUID。该值

      对于此 GUID 将与通过 sendcommand 发送到客户端的 flowID 相同。

    • streamID:唯一标识此命令调用的特定目标的 GUID。

      特定目标。此 GUID 的值将与通过 sendcommand 发送到客户端的 streamID 相同(Firefox 79 中新增)。

    • reason:一个字符串值,可以是 "poll""push""push-missed"

      表示处理命令的原因说明。

    • serverTime:(可选)如上所述,最新的服务器时间戳。

The migrations Array

应用程序服务开发人员正在对 Firefox Sync 和相关数据存储代码的部分进行氧化,这通常需要将旧存储迁移到新的数据库和/或格式。

当发生此类迁移时,下次提交 Sync ping 时,将在此列表中报告一条记录。

由于每个数据存储的格式可能大不相同,因此我们不尝试在此处提出通用表示形式,并且目前计划允许每个迁移记录独立变化(至少目前是这样)。这些记录将通过其 "type" 字段进行唯一识别。

它们每个迁移只应出现一次(也就是说,我们宁愿不报告记录也不要报告多次)。

migrations.type: "webext-storage"

这表示已从基于 Kinto 的旧版扩展程序存储数据库迁移到新的 webext-storage Rust 实现。

它包含以下字段

  • type:始终为字符串 "webext-storage"

  • entries:源(旧版)数据库中的条目/首选项数量,包括我们无法读取的条目。有关此记录中 entriesextensions 之间区别的信息,请参见下文。

  • entriesSuccessful:我们已成功迁移到目标数据库中的条目/首选项(见下文)的数量。

  • extensions:在源(旧版)数据库中至少有一个首选项的不同扩展程序的数量。

  • extensionsSuccessful:在目标(已迁移)数据库中至少有一个首选项的不同扩展程序的数量。

  • openFailure:一个布尔标志,如果我们在之前遇到读取错误,则为 true。这可能表示完全损坏,或者像 rusqlite 这样的底层库中的错误。

注意:“entries” 与 “extensions”

上面详细介绍的 webext-storage 迁移记录包含两者的计数

  • 检测到的“entries”数量与成功迁移的数量。

  • 检测到的“extensions”数量与成功迁移的数量。

这可能看起来是多余的,但它们指的是不同的(但相关的)事物。此处的区别与两个数据库存储扩展程序存储数据的方式有关

  • 旧版数据库为每个 (extension_idpreference_namepreference_value) 三元组存储一行。这些被称为 entries

  • 相反,新数据库为每个扩展程序存储一行,它是一个包含 extension_id 以及包含所有首选项数据的字典的配对,因此等效于扩展程序。

(以上描述是对事物的某种简化视图,因为它忽略了每个数据库存储的一些与迁移无关的值)

也就是说,entries 表示每个单独的首选项设置,而 extensions 表示给定扩展程序的首选项的集合。

由于差异可能指向迁移代码的不同类型的问题,因此提供了这两种计数。