关于 otel-instrument-feature
用于在现有项目的新业务操作中添加 OpenTelemetry 插桩的技能。它帮助开发者规划跨度、指标和日志,遵循项目惯例并验证遥测数据。
主要功能
- 01检查现有 OTel 配置
- 02跨度、指标和日志指南
- 03低基数指标维度
- 04PII 与错误处理规范
- 05端到端遥测验证
适用场景
- 01为新 HTTP 路由或任务插桩
- 02为 Agent 工具添加遥测
- 03为业务操作选择指标
- 04验证发出的 OTLP 信号
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ superloglabs/ skills --skill otel-instrument-feature安装后在 Claude Code 中输入/otel-instrument-feature确认已加载。
详细介绍
使用 OpenTelemetry 为新功能添加埋点
在即将编写或刚刚完成用户项目中的一项新业务操作时,使用此技能。“新功能”指的是出现问题时,人工操作人员会希望之后能够查找的任何内容:新的 HTTP 路由、RPC 处理程序、GraphQL 解析器、后台作业、队列消费者、cron 任务、CLI 子命令、Agent 工具、定时工作流,或表示面向用户流程中一个重要步骤的任何模块级函数。
仅添加纯粹用于连线的代码(例如纯辅助函数、类型或配置)不会触发此技能。添加接收请求、执行操作并产生副作用或响应的代码则会触发。
步骤 0 — 确认 OTel 已完成接入
在添加埋点之前,先查找现有的初始化设置。常见迹象包括:telemetry.ts / observability.ts / instrumentation.ts / init_observability() 模块、@vercel/otel registerOTel(...)、NodeSDK/sdk-node 设置、Python LoggerProvider + OTLPLogExporter、superlogHeaders(...),或内联的 https://intake.superlog.sh 端点及 sl_public_ 令牌。
如果找不到初始化设置,不要在新功能文件中自行创建。告知用户项目仍需接入 OTel,这属于 superlog-onboard 技能的工作;然后继续实现功能,并仅在初始化设置的位置留下一个简短的 TODO(不要在每个 span/metric/log 调用点都留下 TODO)。不要因此阻塞工作。
如果存在初始化设置,编写代码前先阅读适用的配套技能:
otel-onboarding-style— 通用 OTel 风格与属性约定。otel-python-style— Python。otel-fastapi-style— FastAPI。otel-livekit-style— LiveKit agents。otel-nextjs-style— Next.js / Vercel。otel-expo-style— Expo / React Native。otel-supabase-edge-style— Supabase Edge Functions。otel-generic-style— 其他所有情况(Go、Java、Ruby、Rust、.NET、PHP、Elixir、纯 Node 等)。
遵循项目的本地惯例。如果你正在编辑的文件已使用 @superlog/otel-helpers 中的 withSpan,就继续使用它;如果它直接使用 tracer.startActiveSpan,就继续使用这种方式。不要在现有风格之外引入第二种风格。
步骤 1 — 确定新功能需要什么
编写埋点代码前,逐项检查以下清单。每个问题的答案都可以是“否”,并说明原因——这没有问题,但要逐项作答。
Span — 几乎总是需要
使用一个 span 包裹该操作,其名称采用 domain.verb 格式(order.submit、interview.create、email.send、job.reconcile、agent.run、voice.session、llm.generate_copy)。span 应位于功能的入口处,而不是辅助函数内部。
仅当现有自动埋点(HTTP 服务器入口、DB 查询、框架生命周期)已完整覆盖该操作,且操作本身没有额外的、具有业务意义的工作时,才跳过自定义 span。如有疑问,就添加 span——自动埋点几乎从来不会为领域操作提供正确的名称或属性。
在 span 上设置以下属性(仅设置可用属性,不含个人身份信息):
- 操作人员会据此搜索的实体 ID:
tenant.id、workspace.id、org.id、user.id、order.id、job.id、request.id。仅使用有界 ID——绝不要使用原始邮箱、电话号码或完整请求正文。 - 有界分类维度:
outcome(success/failure/skipped)、channel、kind、route、action。 - 有助于解释延迟的计数和大小:
batch.size、items.count、payload.bytes。 - 对于尚未被提供商埋点覆盖的 LLM 调用点:
gen_ai.provider.name、gen_ai.request.model、app.gen_ai.use_case、app.gen_ai.call_site。不要重复添加 OpenInference/提供商埋点已捕获的属性。
发生错误时,记录异常并将 span 状态设为错误。然后重新抛出异常——不要吞掉异常。
指标(Metric)——如果这是有意义的状态转换,或其延迟值得关注,则添加
分为三类。判断新功能适用哪些类别:
- 业务计数器——记录每个有意义的结果:
orders.submitted、jobs.completed、emails.delivered、interviews.started、payments.failed。添加低基数维度标签(tenant.id、outcome、channel)。绝不使用原始用户 ID 或订单 ID 作为标签。 - 性能直方图——如果人们会关注延迟长尾,则记录操作时长。如果 SDK 提供现成的跨度计时数据,就复用它,避免重复测量;否则,使用
time.perf_counter/performance.now()在与跨度相同的边界处计时。 - 成本——仅用于 LLM 调用点,且仅当提供方的埋点尚未记录令牌用量时。使用
unit="tokens"的llm.tokens.input/llm.tokens.output计数器。不要添加llm.cost_usd或任何应用侧定价指标——Superlog 会根据提供方、模型和令牌数据集中计算成本。
在模块作用域获取 meter 并创建仪器。绝不要在热路径中创建 meter 或仪器。
日志(Log)——如果人们需要叙述性记录,则添加
使用日志记录叙述性信息(例如“开始批量对账”“5xx 后进行第 2 次重试,共 3 次”),以及需要关注的异常事件。使用项目现有的 logger——不要引入新的日志库,也不要用辅助函数封装日志调用。
error 级别的日志必须表示该操作无法恢复,除非进行人工干预。可恢复的情况应使用 warn 或更低级别。
如果启动引导中的日志桥接配置正确,在跨度内发出的日志会自动附带 trace_id / span_id。不要为了强制关联而在日志调用外创建一个用完即弃的跨度。
属性与指标维度
跨度属性可以是高基数的(具体 ID、计数)。指标维度则不可以——应将其限制在有界范围内。如果你想给指标添加 order.id 或 request.id 标签,这些数据应放在跨度上,而不是计数器中。
第 2 步——在实现功能的同时编写埋点
在新操作的入口点添加跨度。不要在操作内部的每个辅助函数中零散地添加微跨度——一个命名清晰且属性丰富的跨度,胜过五个泛泛的跨度。只有当存在值得单独追踪的实际子操作时(例如外部 API 调用、延迟不明显的数据库事务,或 parse / validate / dispatch 等独立阶段),子跨度才有用。
在操作成功和失败的边界处添加带有 outcome 标签的计数器。若需要关注延迟长尾,则添加直方图。在长时间运行的叙述性流程开始、结束时,以及出现异常的分支中添加日志。
不要在单个调用点周围添加向后兼容垫片、功能标志或“遥测开/关”切换。未注册任何提供方时,SDK 已有无操作路径;这就是所需的唯一开关。
不要自行发明 recordCounter、sendSuperlogSpan、withTelemetry、trackEvent 等辅助 API。使用原生 OTel API(或在 TS/JS 中使用已发布的 @superlog/otel-helpers 里的 withSpan,前提是本地代码风格已在使用它)。
第 3 步 — 验证新功能是否产生了你声称的数据
通过项目的常规入口端到端运行该功能——用 curl 调用路由、调用 CLI 子命令、将任务加入队列,或触发 Agent 工具。使用模拟 tracer 的单元测试不算;目标是看到真实的 OTLP 载荷离开进程。
如果开发服务器记录了 OTLP 导出器活动(或项目有调试导出器),请确认:
- 你添加的 span 显示了你声称的名称和属性。
- 你添加的计数器至少递增了一次。
- 操作内部发出的日志行已到达,且其中填充了
trace_id/span_id。
如果引导流程使用了生成的 sl_public_ 令牌,且注册尚未完成,接收端将返回 401/403——这是预期行为。你要关注的信号是“SDK 生成了载荷并尝试发送”,而不是“接收端接受了载荷”。
如果只有 span 出现,而指标和日志没有出现,则说明引导流程存在连接配置缺口。这是 superlog-onboard 的问题,不属于此技能——请告知用户并继续开发功能。
硬性规则
- 绝不在 span 属性、指标维度或日志字段中放入 PII:不得包含电子邮件、电话号码、密码、令牌、完整请求正文或明文消息内容。
- 绝不使用原始用户/订单/请求 ID 标记指标。这些信息应放在 span 上。
- 绝不自行发明遥测包装器 API;请使用原生 OTel SDK 和本地风格约定。
- 绝不单独创建一个临时 span,只为让日志行携带
trace_id。请改为修复桥接,或接受日志未关联 trace 的情况。 - 绝不在调用点添加 LLM 成本计算或定价表。Superlog 会集中计算成本。
- 不要因缺少引导流程而阻塞功能开发——只留一条 TODO,并告知用户运行
superlog-onboard。