Skip to main content
BCC
s48

遥测与诊断

产品化

知道产品怎么被使用

~300 行代码25 个工具OpenTelemetry + profileCheckpoint + logEvent + Doctor 命令 + 最终架构回顾
遥测是产品闭环的最后一环——没有数据就没有迭代方向

A product without metrics is flying blind

You can't optimize what you don't measure.

[ Phase 11: 生产功能 ] · 主题:启动剖析、Doctor、采样遥测与诊断报告


前置知识

  • 需要完成: s47 Native 能力

你将学到

  • 启动剖析:profileCheckpoint 阶段计时与 PHASE_DEFINITIONS 定义
  • Doctor 健康检查:getDoctorDiagnostic 聚合环境/工具/配置检查
  • 采样遥测:internal 全量 vs external 低采样的合规平衡
  • 结构化诊断报告:时间线格式、敏感信息脱敏、可复制模板
  • 性能优化循环:先 Statsig 看 P95 → 针对性 profiling → 验证回归

问题场景

用户说「启动慢」「总报错」,没有数据只能猜。你需要:启动各阶段耗时一键健康检查(Doctor)合规前提下的产品遥测,以及可读的诊断报告方便支持团队与用户自助。

设计决策

决策理由
Checkpoint 剖析performance.mark 对齐各阶段,便于对比版本回归
Doctor 聚合检查Node 版本、API Key、ripgrep、磁盘、Git 等一次性列出,减少往返
采样遥测internal 全量、external 极低采样,平衡信号与隐私/成本
结构化报告统一格式化(时间线、表格、通过/失败),便于粘贴到 issue

启动阶段(示例)

阶段含义
import从入口到主模块 import 完成
init同步初始化逻辑
settings设置加载(可能触盘多次)
total到首次可交互或 main 完成

命名与边界要在团队内固定,否则跨版本不可比。

采样率(教学约定)

  • internal:100%(或接近),用于开发迭代与内测。
  • external:例如 0.5% 随机采样,避免海量终端上报压垮管道。

实际阈值以产品与合规为准,并可通过远程配置调整。

实现要点

1. profileCheckpoint(name)

  • 内部判断 SHOULD_PROFILE:详细模式(环境变量)或命中采样。
  • 使用 performance.mark;可选并记录 memoryUsage() 仅用于深度剖析。
  • 成对 checkpoint 计算 measure 得到阶段耗时。

2. 阶段聚合上送

定义 PHASE_DEFINITIONS[startMark, endMark] → 逻辑名 import_timeinit_timesettings_timetotal_time,单次启动一条事件或多字段。

3. Doctor

  • 调用 getDoctorDiagnostic() 聚合:环境、路径、工具版本、配置错误。
  • UI:Doctor.tsx 分节展示;可复制为文本报告。

4. 诊断报告格式化

  • 时间线:每行 +XXXms checkpoint_name
  • 问题列表:错误码、修复建议链接
  • 敏感信息:API Key 脱敏(只显示前后缀)

运行验证

cd agents/s48-telemetry-diagnostics

# 1. 启用性能剖析启动
PROFILE=1 npm run dev
# → [perf] prefetch_start: 0ms
# → [perf] prefetch_done: 182ms
# → [perf] first_render: 245ms
# → 各阶段耗时一目了然

# 2. 运行诊断命令
npm run dev -- doctor
# → 检测 Node 版本、API Key、Git、rg 等
# → ✓ Node v20.11.0 (>=18 required)
# → ✓ API Key configured (sk-ant-...***...xyz)
# → ✗ ripgrep not found (using fallback)

# 3. 验证敏感信息脱敏
#    → API Key 只显示前后缀:sk-ant-***xyz
#    → 路径中的用户名不暴露

# 4. 验证采样遥测
#    → 遥测事件按采样率发送(非全量)
#    → 离线时静默跳过,不影响使用

对照 Claude Code 表格

概念Claude Code 中的位置说明
启动剖析src/utils/startupProfiler.tsprofileCheckpointPHASE_DEFINITIONSSTATSIG_SAMPLE_RATE = 0.005USER_TYPE === 'ant' 全量
详细模式CLAUDE_CODE_PROFILE_STARTUP内存快照、完整报告
Doctor UIsrc/screens/Doctor.tsx展示 dist-tags、诊断、沙箱等
诊断数据src/utils/doctorDiagnostic.tsgetDoctorDiagnostic聚合 DiagnosticInfo
遥测上送logEvent + Statsig采样逻辑与 metadata 类型约束

深入思考

  1. 为何采样在模块加载时决定? 避免每个函数里随机判断带来的开销与偏差;未采样用户应接近零成本。
  2. checkpoint 重复:同一 mark 名可能多次触发(如 settings 重载),内存快照数组需与 mark 顺序对齐,不能简单用 Map 覆盖。
  3. Doctor 与隐私:报告导出前过滤路径中的用户名、token。
  4. 优化循环:先 Statsig 看 P95 阶段 → 针对性 profiling → 再验证,避免凭感觉改 import。

练习

  1. 实现 profileCheckpoint + printStartupReport,仅在 PROFILE=1 时打印 import_time / total_time
2. 用数学证明:0.5% 采样下,约需多少日活才能以 95% 置信度发现占 1% 会话的启动回归(简化为二项近似,写出思路即可)。 3. 为 Doctor 写 `DiagnosticInfo` 类型:包含 `checks: Array<{ id: string; ok: boolean; detail?: string }>`。 4. 阅读 `startupProfiler.ts` 中 `PHASE_DEFINITIONS`,说明 `total_time` 的起止 mark 为何选 `cli_entry` → `main_after_run`。 5. 设计一个「用户可复制」的诊断模板(Markdown),包含版本、OS、Node、失败项与脱敏后的配置来源。

Phase 11 总结

恭喜完成 生产功能 阶段!你现在掌握了:

  • s44 递进式错误恢复:错误分类、指数退避重试、递进恢复链、熔断器
  • s45 Feature Flags:编译期 DCE、运行时 env、灰度 hash 分桶、用户类型分流
  • s46 打包与分发:esbuild 单文件打包、package.json 发布配置、npm publish 流程
  • s47 Native 能力:四种策略对比、ripgrep 三档降级、detectCapabilities
  • s48 遥测与诊断:启动剖析、Doctor 健康检查、采样遥测、诊断报告

从错误恢复到可观测性,你的 Agent 已具备生产级韧性、发布管控与运维诊断能力。


全课程完成! 从 s01 的第一条用户消息,到 s48 的遥测诊断——你已经从零构建了一个完整的 AI 编程助手。