s48
Telemetry & Diagnostics
Production知道产品怎么被使用
~300 lines of code25 toolsOpenTelemetry + 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_time、init_time、settings_time、total_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.ts | profileCheckpoint、PHASE_DEFINITIONS;STATSIG_SAMPLE_RATE = 0.005;USER_TYPE === 'ant' 全量 |
| 详细模式 | CLAUDE_CODE_PROFILE_STARTUP | 内存快照、完整报告 |
| Doctor UI | src/screens/Doctor.tsx | 展示 dist-tags、诊断、沙箱等 |
| 诊断数据 | src/utils/doctorDiagnostic.ts — getDoctorDiagnostic | 聚合 DiagnosticInfo |
| 遥测上送 | logEvent + Statsig | 采样逻辑与 metadata 类型约束 |
深入思考
- 为何采样在模块加载时决定? 避免每个函数里随机判断带来的开销与偏差;未采样用户应接近零成本。
- checkpoint 重复:同一 mark 名可能多次触发(如 settings 重载),内存快照数组需与 mark 顺序对齐,不能简单用 Map 覆盖。
- Doctor 与隐私:报告导出前过滤路径中的用户名、token。
- 优化循环:先 Statsig 看 P95 阶段 → 针对性 profiling → 再验证,避免凭感觉改 import。
练习
- 实现
profileCheckpoint+printStartupReport,仅在PROFILE=1时打印import_time/total_time。
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 编程助手。