关于 telemetry-inspect
telemetry-inspect 是用于 OrchestKit 的遥测流水线只读健康检查技能,面向排查写入异常和定期核验。它结合文件状态、写入钩子运行情况及协调层数据生成终端或 JSON 报告。
主要功能
- 01检查遥测文件写入活动与文件状态
- 02识别未登记文件和失效写入器
- 03核验文件的 Schema 锁定状态
- 04统计增长趋势并发出警告
- 05检查协调层及钩子触发记录
- 06支持终端报告和 JSON 输出
适用场景
- 01重构钩子前后核验遥测仍正常写入
- 02排查 analytics 数据异常或写入器缺失
- 03定期检查长期项目的遥测健康状况
- 04审计遥测文件的 Schema 覆盖情况
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill telemetry-inspect安装后在 Claude Code 中输入/telemetry-inspect确认已加载。
附带文件references/telemetry-inventory.md
详细介绍
telemetry-inspect
对 OrchestKit 遥测流水线进行一次性健康检查。报告写入器活动、文件大小、架构锁定覆盖情况、孤立文件和增长警告。用于验证流水线是否正常运行,或调试缺失的写入器。
适用场景
- 在进行高风险钩子重构之前或之后,确认遥测仍按预期写入
- 对长期运行的项目进行每周健康检查
analytics输出看起来可疑时,先检查底层数据- 添加新的遥测文件并希望确认它已被纳入检查时
- 审核哪些文件受架构锁定,哪些容易发生偏差
检查内容
- 写入器活动 — 对每个已注册的遥测文件,统计近期写入次数(根据 mtime 扫描)和距上次写入的时间
- 文件健康状况 — 大小(达到 256 KB 时警告,达到 1 MB 时严重警告)、行数、mtime
- 架构锁定状态 — 哪些文件在
lib/telemetry-schemas.ts中有验证器 - 孤立文件检测 —
.claude/{telemetry,logs,state,feedback}/下磁盘上存在但未登记在清单中的文件(可能是陈旧的写入器,或需要架构的新文件),以及清单中写入器钩子已不在src/hooks/src/中的条目(写入器失效 → 孤立) - 增长趋势 — 自会话开始以来每小时增加的字节数(超过 100 KB/hr 时触发警报)
- 协调层(M168) — 来自
sessions.db的实时计数(运行中的会话、持有的锁、待处理的 worktree 链接、技能调用),以及来自coordination-metrics.jsonl的写入吞吐量 - 运行时触发统计 — 哪些钩子实际触发了,数据来自
run-hook.mjs写入~/.claude/analytics/hook-timing.jsonl的单次调用记录。检查项 1–4 回答“该文件是否正在写入?”,此项回答“写入器是否在运行?”——也就是更上游的问题。钩子可能已接入且可访问(闭包门禁在静态层面证明了这一点),但仍从未触发:#2886 发布时恰恰发生了这种情况,尽管有 12 项测试全部通过。
用法
telemetry-inspect
telemetry-inspect --session sess-abc123
telemetry-inspect --json
默认模式:便于在终端查看的 ASCII 报告。--json 会输出结构化结果,适合传递给其他工具或上传。
输出格式(ASCII 模式)
Telemetry Health — 2026-07-09 11:50
────────────────────────────────────
Schema-locked files (7)
.claude/telemetry/pre-compact-decisions.jsonl ◆ 3 lines 1.1 KB ✓ healthy
.claude/telemetry/image-responses.jsonl ◆ 0 lines — ✗ no writes
.claude/logs/decisions.jsonl ◆ 0 lines — ✗ no writes
.claude/logs/subagent-spawns.jsonl ◆ 6 lines 3 KB ✓ healthy
.claude/state/edit-history.jsonl ◆ 94 lines 412 KB ⚠ rotate
.claude/state/ork-metrics-*.json ◆ (N/A) 2.1 KB ✓ healthy
.claude/logs/skill-channels.jsonl ◆ 12 lines 4 KB ✓ healthy
Unlocked telemetry files (14)
.claude/feedback/changelog-decisions.json ○ 4 KB ✗ no schema
.claude/feedback/learned-patterns.json ○ 8 KB ✗ no schema
(...14 more...)
Orphan files (1)
.claude/feedback/skill-usage.json — delisted, writer unwired since #959
Runtime fired-census (7d window)
ALIVE 59 IDLE 3 NEVER 83 UNOBSERVABLE 54
tree 8.75.0 · installed 8.73.0/8.74.0 <-- SKEW: NEVER is not a verdict
never-fired writers (the ones that matter here):
posttool/dirty-file-tracker [PostToolUse] 0 fires, ever
Summary
Pipeline health: GREEN (21/21 expected writers active)
Schema coverage: 7/21 (33%)
Largest file: edit-history.jsonl (412 KB)
Hotspot: edit-history.jsonl +40 KB/hr
实施计划(供运行此技能的 Agent/大模型使用)
- 列出已知文件 — 读取
lib/telemetry-schemas.ts中的SCHEMA_LOCKED清单,获取 7 个锁定路径。再补充技能本地references/telemetry-inventory.md中列出的未锁定路径。 - 对照注册表闭包检查清单中的写入器 — 切勿盲目信任清单:
- 运行
node src/hooks/scripts/validate-registry.mjs(在 OrchestKit 仓库根目录中;如果当前不在 OrchestKit 仓库中,则跳过,不报错),并确认验证通过。 - 对清单中列出的每个写入器(例如
posttool/metrics-bridge),验证源文件是否存在:test -f src/hooks/src/<writer>.ts。 - 任何不是有效
src/hooks/src/文件的清单写入器都是孤立项 — 报告 🔴,绝不能称为“预期为空”。无论新旧,磁盘上的相关文件都是孤立文件,清单条目也已过时(标记待删除)。
- 运行
- 针对每个文件:
- 使用
Glob解析.claude/state/ork-metrics-*.json模式 → 可能匹配多个文件 - 使用
Read并设置limit: 10查看结构,再用Bash wc -l获取行数 - 使用
Bash stat获取修改时间和大小
- 使用
- 健康状态分类:
- 大小 > 1 MB → 严重
- 大小 > 256 KB → 警告
- 修改时间 > 7 天 →“近期无写入”
- 行数为 0 →“无写入”
- 孤立项扫描 — 使用
Bash find .claude/{telemetry,logs,state,feedback} -type f,并与已注册路径交叉核对。任何不在清单中的磁盘文件都是孤立文件。合并步骤 2 中已失效写入器所对应的孤立项。 - 运行时触发情况统计 — 步骤 1–5 要回答“文件是否正在写入?”。本步骤要回答上游问题:“写入器钩子是否会运行?”
- 运行
node src/hooks/scripts/fired-census.mjs --json(仅限 OrchestKit 仓库;其他情况下跳过,不报错——如果~/.claude/analytics/hook-timing.jsonl尚不存在,该命令会以 0 退出并打印统计数据缺失提示)。 - 报告各类别计数(
totals);当versions.skewed为 true 时,逐字报告该行——统计数据由已安装的插件在所有项目中写入,而闭包来自此代码树,因此,对于比已安装版本更新的钩子,NEVER是预期结果,并非问题。 - 交叉核对:对于步骤 2 中清单列出的每个有效文件写入器,查找其统计数据行。状态为
ALIVE但文件行数为 0 的写入器是真实缺陷(它会运行,却没有产生任何内容)。状态为NEVER的写入器属于 #2886 类别——应予呈现,但仅作提示。 - 绝不能仅凭
NEVER判定钩子已失效。UNOBSERVABLE条目(分发器子项)本就不会出现;罕见事件(WorktreeRemove、PreCompact)在这里看起来与损坏的防护条件相同。下结论前先检查防护条件。
- 运行
- 生成报告 — 默认使用 ASCII 表格;传入
--json参数时输出 JSON。
核心逻辑是确定性的,且只读。请勿写入任何遥测文件——此技能仅用于观察。
协调层(M168 #1915)
SQLite 协调层位于 .claude/ 之外,路径为 ~/.local/state/orchestkit/:
| 来源 | 说明 |
|---|---|
sessions.db | 实时会话 / 锁 / 工作树状态(SQLite) |
events.jsonl | 协调事件流(goal_converged、chain_stale 等) |
coordination-metrics.jsonl | sessions.db 写入吞吐量计数器(#1915) |
实时计数 — 数据库文件是标准 SQLite 数据库;使用 sqlite3 读取(仅限只读 SELECT):
DB="$HOME/.local/state/orchestkit/sessions.db"
[ -f "$DB" ] || echo "coordination layer idle (no multi-session activity yet)"
sqlite3 "$DB" "SELECT COUNT(*) FROM sessions WHERE status='running'" # live sessions
sqlite3 "$DB" "SELECT COUNT(*) FROM skill_invocation" # skill invocations
写入吞吐量 — coordination-metrics.jsonl 是只追加文件,其中的 {ts, metric, count} 行由 lib/metrics-emitter.ts 在每次 sessions.db 写入时异步发出。事件速率 ≈ 最近的 sessions_db_write 行:
M="$HOME/.local/state/orchestkit/coordination-metrics.jsonl"
[ -f "$M" ] && tail -200 "$M" | grep -c '"sessions_db_write"'
平稳降级:如果系统中没有 sqlite3,或数据库 / 指标文件不存在,则报告 “协调层处于空闲状态”——绝不报错。与此技能的其他部分一样,这些都是只读观察。
上游 OTel 指标说明
检查 Claude Code 自身的 OTel 指标时(即此技能下游的指标,在你的收集器中以 claude_code.* 表示):
- CC 2.1.129+:
claude_code.pull_request.count现在也会统计通过 MCP 工具(例如 GitHub MCPcreate_pull_request)提交的 PR/MR,而不再只统计通过 Bash 工具运行的 Shell 命令创建的 PR/MR。升级前构建的仪表板会在切换时出现阶跃式增长;请添加注释,不要触发告警。有关区分通过 MCP 和 Shell 创建 PR/MR 的关联模式,请参阅../monitoring-observability/references/metrics-collection.md。 - CC 2.1.161+:
OTEL_RESOURCE_ATTRIBUTES的值现在会作为标签附加到所有指标数据点上,从而支持按维度切片(团队、仓库、环境)。现有仪表板仍可正常使用;新仪表板应使用标签选择器对使用情况进行细分。 - CC 2.1.145+:
claude_code.toolOTel spans 携带agent_id+parent_agent_id,后台子 Agent 的 spans 会嵌套在负责调度的 Agent 工具 span 之下。按parent_agent_id查询即可构建追踪树,从而统计多 Agent 技能(brainstorm、explore、implement)的扇出耗时并归因成本;无需更改架构。 - CC 2.1.174+:
/usage会公开 CC 原生的分组件归因信息——缓存未命中、长上下文、子 Agent,以及过去 24h/7d 内按技能/Agent/插件/MCP 拆分的成本(首先在 VSCode 的 Account & usage 对话框中提供)。请将其作为健康报告中的交叉核对来源:如果 ork 遥测显示某个技能/Agent 处于活动状态,但 CC 归因显示其使用量为零(反之亦然),应将这种差异标记为可能存在写入端缺失或安装过时,而不要单独信任任何一方。 - CC 2.1.202+:由工作流启动的 Agent(一次
/workflows运行)的遥测现在带有workflow.run_id+workflow.name属性,因此可以通过 OTel 重构整个工作流运行——按workflow.run_id对所有 Agent 事件分组,以重建单次运行的扇出,并按workflow.name切片。有关字段表,请参阅../analytics/references/otel-fields.md(“From 2.1.202”);请先过滤select(.["workflow.run_id"] != null),因为普通会话事件不包含这些属性。
相关内容
lib/telemetry-schemas.ts— 架构锁定路径的唯一事实来源analytics— 汇总不同会话间的数据(适用场景不同)- M121“Observability Consolidation”里程碑