跳转到内容
Telemetry
浏览文档
指南更新于 2026年7月30日由 Telemetry 编辑团队和产品团队审核阅读约需 6 分钟

让编程智能体使用这篇文档

打开 Claude Code、Codex、Cursor 或其他编码代理的集中提示包,然后将其适应此处介绍的工作流程。

本页内容
  1. 当这个模式适合时
  2. 定义客户合同
  3. 实施应用程序拥有的端点
  4. 应用四个服务器端控件
  5. 认证
  6. 允许名单
  7. 速率限制
  8. 添加可信上下文
  9. 选择移动交付行为
  10. 查询并验证结果
  11. 需要规划的故障模式
  12. 主要参考文献

安全的移动应用遥测代理

移动应用程序分发到您无法控制的设备。任何编译到 React Native 包、Swift 应用程序、Kotlin 应用程序或 Flutter 二进制文件中的内容最终都可以被检查。请勿在应用程序中传送 Telemetry API 密钥、传送到应用程序的远程配置值或客户端可读的环境文件。

相反,将一个小事件发送到您的应用程序拥有的经过身份验证的端点。该端点验证固定合同,添加受信任的服务器上下文,并使用服务器端密钥转发事件。

移动端代理示意图:应用将事件发送至自己的 API,API 验证身份、校验允许的事件并限制请求速率,再转发至 Telemetry。

移动端代理示意图:应用将事件发送至自己的 API,API 验证身份、校验允许的事件并限制请求速率,再转发至 Telemetry。 移动应用不会收到 Telemetry 的摄取密钥。

当这个模式适合时

使用移动代理来获取产品里程碑、有限性能测量、同步结果、受控错误类别和发布质量信号。示例包括:

  • 本地到服务器同步达到最终结果后 mobile_sync_completed
  • mobile_screen_ready 用于一小组命名屏幕和测量的持续时间。
  • 服务器确认持久结果后mobile_purchase_flow_completed
  • mobile_api_request_completed 用于采样、分类的依赖性结果。

这不能替代崩溃符号、设备日志、分布式跟踪或精确的审计分类帐。移动交付受到连接、后台执行限制、应用程序终止、同意和客户端时钟质量的影响。将专业诊断保留在其专业系统中,并仅发送 SQL 分析所需的结果。

定义客户合同

客户端应从事件名称和字段的版本列表中进行选择。它不应选择 Telemetry 表名、发送任意属性包或转发异常消息。

{
  "event_name": "mobile_sync_completed",
  "event_version": 1,
  "event_id": "0196f37e-6e83-7b75-9d04-6b8283b35f74",
  "occurred_at": "2026-07-30T18:42:11.150Z",
  "status": "success",
  "duration_ms": 842,
  "item_count": 12,
  "network_type": "wifi"
}

保持尺寸有界。优先选择受控的 screen_name 而不是原始路由,优先选择 error_type 枚举而不是异常字符串,优先选择粗略的 network_type 而不是网络标识符。请勿包含访问令牌、设备广告标识符、联系人数据、消息内容、文件路径、剪贴板数据、自由格式搜索文本或原始 URL。

event_id支持重试重复数据删除。 occurred_at 记录客户端观察,但代理还应添加服务器接收的时间戳。使用服务器时间戳进行新鲜度和摄取监控,因为设备时钟可能是错误的。

实施应用程序拥有的端点

以下 TypeScript 草图显示了边界。将身份验证和速率限制调整为 API 已使用的框架。

const allowedEvents = {
  mobile_sync_completed: {
    statuses: new Set(["success", "failed", "cancelled"]),
    maximumDurationMs: 300_000,
    maximumItemCount: 10_000,
  },
} as const;

export async function postMobileTelemetry(request: Request) {
  const actor = await authenticateApplicationRequest(request);
  if (!actor) return new Response("unauthorized", { status: 401 });

  await enforceRateLimit({
    accountId: actor.accountId,
    deviceSessionId: actor.deviceSessionId,
  });

  const body = await readBoundedJson(request, { maximumBytes: 4096 });
  const policy = allowedEvents[body.event_name as keyof typeof allowedEvents];

  if (
    !policy ||
    body.event_version !== 1 ||
    !isUuid(body.event_id) ||
    !policy.statuses.has(body.status) ||
    !isIntegerInRange(body.duration_ms, 0, policy.maximumDurationMs) ||
    !isIntegerInRange(body.item_count, 0, policy.maximumItemCount)
  ) {
    return new Response("invalid event", { status: 422 });
  }

  await telemetry.log("mobile_sync_completed", {
    event_id: body.event_id,
    event_version: 1,
    occurred_at: parseBoundedClientTimestamp(body.occurred_at),
    received_at: new Date().toISOString(),
    status: body.status,
    duration_ms: body.duration_ms,
    item_count: body.item_count,
    network_type: normalizeNetworkType(body.network_type),
    account_id: actor.accountId,
    app_platform: actor.platform,
    app_version: actor.appVersion,
    environment: process.env.APP_ENV ?? "development",
  });

  return new Response(null, { status: 202 });
}

API 决定Telemetry 事件名称。它从受信任的服务器状态派生身份、平台、环境和任何授权上下文,而不是从客户端接受这些值。如果端点支持多个事件,请为每个事件提供独立的模式和测试装置。

应用四个服务器端控件

认证

需要 API 的其余部分使用相同的签名应用程序会话或安装凭据。 CORS 不是移动安全边界,仅自定义标头并不能证明谁发送了请求。

允许名单

拒绝未知的事件名称、字段、枚举值、超大字符串、无效数字、未来时间戳和超出小尺寸限制的正文。允许名单既是隐私控制又是基数控制。

速率限制

通过经过身份验证的帐户和适当的安装或会话标识符进行限制。还施加了全球上限。当客户端超出限制时,返回正常的应用程序错误,而不会无限期地重试。

添加可信上下文

代理应添加帐户标识符、服务器接收时间、环境和经过验证的应用程序版本(如果这些值可用)。如果帐户标识符在您的上下文中敏感,请在收集之前对其进行一致的假名化,并记录谁可以反转映射。

选择移动交付行为

对于 React Native 和 Flutter,请使用已经负责经过身份验证的 API 请求的平台 HTTP 客户端。对于本机 iOS 和 Android,请使用应用程序使用的相同 URLSession 或 HTTP 堆栈。端点和事件契约在不同平台上应该保持相同。

当离线交付很重要时,保持一个小的有界队列。限制项目数量和寿命,丢弃超出记录窗口的事件,并使用带有抖动的指数退避。不要让分析重试延迟产品操作。在尝试中保留相同的 event_id ,以便服务器可以进行重复数据删除。

有些结果最好由服务器发出。购买、订阅更改、访问策略决策或完成的导入仅在后端提交后才具有权威性。让服务器直接发出这些结果,而不是信任客户端断言。

查询并验证结果

发送一个合成的成功、失败、取消、无效负载、未经身份验证的请求、限速突发、离线重试和重复的 event_id。然后检查有界样本:

SELECT
  received_at,
  event_id,
  app_platform,
  app_version,
  status,
  duration_ms,
  item_count
FROM mobile_sync_completed
ORDER BY received_at DESC
LIMIT 50;

在推出之前,请验证:

  1. 提供的应用程序二进制文件和 JavaScript 捆绑包不包含 Telemetry API 密钥。
  2. 未知的事件和字段会被拒绝,而不是默默地转发。
  3. 不存在原始异常文本、URL、用户输入、凭据和设备标识符。
  4. 重试保留一个 event_id,并且重复交付不会增加结果计数。
  5. 仪表板在比率和百分位数旁边显示样本计数。
  6. 同意、保留、删除和帐户删除行为符合应用程序策略。

需要规划的故障模式

将代理视为尽力可观测性,除非该事件是单独设计的持久业务工作流程的一部分。通常应记录 Telemetry 超时并对其进行限制,而不会导致移动产品操作失败。监控代理拒绝率、转发失败、队列寿命和事件新鲜度,以便静默检测中断看起来不像产品使用率下降。

不要自动接受任意客户端事件以“使调试更容易”。这将端点变成未经审核的数据收集表面。仅在查看其目的、类型、基数、隐私分类和删除要求后才添加新的版本化字段或事件。

主要参考文献

相关产品功能

记录稳定的事件名称、类型明确的字段,以及经过隐私审核的上下文。

内容责任与技术参考

Telemetry 编辑团队负责维护本文;产品团队审核功能行为、示例和适用范围。

查看编辑规范