关于 otel-onboarding-style
定义服务 OpenTelemetry 埋点规范的技能,涵盖信号、资源属性、错误、HTTP 框架和 LLM 提供商,帮助统一遥测配置方式。
主要功能
- 01原生 OpenTelemetry API 指引
- 02资源与环境属性规范
- 03Trace、日志和指标实践
- 04HTTP 与错误埋点
- 05LLM 提供商遥测指引
适用场景
- 01为服务配置遥测
- 02建立按操作划分的 RED 信号
- 03添加与 Trace 关联的结构化日志
- 04埋点受支持的 LLM 提供商
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ superloglabs/ skills --skill otel-onboarding-style安装后在 Claude Code 中输入/otel-onboarding-style确认已加载。
详细介绍
OTel 接入规范
使用原生 OpenTelemetry API。不要自行发明辅助 API。
在 TypeScript/JavaScript 中,对于范围明确的业务 Span,使用已发布的 @superlog/otel-helpers withSpan
辅助函数;如果 package.json 中尚未包含 @superlog/otel-helpers,请将其添加进去。
只要可以安装该包,就必须使用它。withSpan 用于替代将整个函数改写为
tracer.startActiveSpan(...) 加上 try / catch / finally 的做法。对于
OpenInference/提供方检测可以直接观测到的提供方 SDK 调用,不要使用辅助函数进行包装。
应该:
const tracer = trace.getTracer("mugline.api");
const meter = metrics.getMeter("mugline.api");
const ordersSubmitted = meter.createCounter("orders.submitted");
await withSpan("order.submit", async (span) => {
span.setAttributes({
"tenant.id": tenantId,
"order.id": orderId,
outcome: "success",
});
ordersSubmitted.add(1, { "tenant.id": tenantId, outcome: "success" });
}, { tracer });
不应该:
await sendSuperlogSpan(...);
recordCounter(...);
withTelemetry(...);
命名
- 文件/函数应与提供方无关:
telemetry.ts、observability.ts、initTelemetry()、initObservability()。 - 仅在端点/密钥设置注释或 PR 说明中使用 Superlog 一词。
- Span 名称应符合惯例且基数较低:
checkout.process、voice.session、llm.generate_copy。 - 优先使用具有语义的产品操作 Span 名称,而非提供方传输名称。
llm.generate_copy或llm.voice_response通常比llm.anthropic.messages.create更有用。
端点和公开令牌
在引导源代码中直接内联端点和 Superlog 公开摄取令牌。该令牌以
sl_public_ 开头,限定于单个项目且仅可写,适合放在浏览器/移动端/服务器源代码中,
安全性类似 PostHog 项目令牌或 Sentry DSN。
SUPERLOG_ENDPOINT = "https://intake.superlog.sh"
SUPERLOG_PUBLIC_TOKEN = "sl_public_…"
不要自行编造旧名称,例如 SUPERLOG_API_KEY 或 SUPERLOG_INTAKE_URL,
即使是文档或注释中的占位文本也不行。在配对流程进行期间,请在源代码中使用生成的
sl_public_ 令牌;在注册意向流程将其关联到用户项目之前,摄取操作可能会拒绝该令牌。
通过导出器构造函数的 endpoint / headers 选项,显式将内联值传递给 SDK。
不要通过隐式读取 OTEL 环境变量来配置 Superlog;缺少环境变量是本规范要避免的
主要接入失败原因。
令牌应放在 x-api-key 请求头中。摄取端仅接受
x-api-key: <token> 或 Authorization: Bearer <token>(必须包含字面前缀 Bearer )——
优先使用 x-api-key。即使令牌有效,使用其他请求头名称也会导致每个请求都返回 401;
这是仅次于缺少环境变量的第二常见接入失败原因。定义一个单行辅助函数,
将请求头名称集中在一处:
function superlogHeaders(token: string): Record<string, string> {
return { "x-api-key": token };
}
def superlog_headers(token: str) -> dict[str, str]:
return {"x-api-key": token}
如果仓库可以从多个路径调用遥测初始化,请保护提供方/导出器设置,避免重复导入、测试、 热重载或框架回调安装重复的处理器或日志处理程序。对于可正常启动的单入口点应用, 保持实现简单。
当值可用时,请包含标准资源属性:
service.name、service.version、deployment.environment.name,以及下方的 VCS
属性。
环境标记
尽可能为每个信号添加运行时环境标记。优先在 OTel 资源上设置一次
deployment.environment.name,使其传播到追踪、日志和指标。根据现有平台环境变量推断环境,
例如 NODE_ENV、VERCEL_ENV、RAILWAY_ENVIRONMENT_NAME、
FLY_APP_NAME/发布元数据、ENVIRONMENT、APP_ENV 或 PYTHON_ENV;
将明显的值规范化为基数较低的名称,例如 local、development、preview、staging 和
production。
如果某个运行时/导出器路径无法为所有可观测信号附加资源属性,请手动将相同的低基数环境值
添加到自定义 Span 属性、日志记录和指标数据点。除非仓库已有标准,否则不要创建
env、environment 或 app.environment 等独立属性名称;在 SDK 允许的情况下,
统一使用 deployment.environment.name。
VCS 资源属性
为每个已插桩服务在 OTel 资源上设置 vcs.repository.url.full。其值应为仓库规范的 https URL(例如 https://github.com/acme/api)——即用户会粘贴到浏览器中的同一个 URL,而不是 SSH URL,也不是本地工作树路径。这一点至关重要:它能让 Superlog 将遥测数据关联回事实来源。可以在 SDK 初始化时将此字符串与 service.name 一起硬编码;如果构建环境已提供仓库标识(例如 VERCEL_GIT_REPO_OWNER + VERCEL_GIT_REPO_SLUG、RAILWAY_GIT_REPO_OWNER + RAILWAY_GIT_REPO_NAME),则优先从环境变量读取,以免分叉或重命名导致信息不一致。
还应尽力设置 vcs.ref.head.revision(提交 SHA)。从运行时/构建平台已注入的任意环境变量中读取:
VERCEL_GIT_COMMIT_SHA、RAILWAY_GIT_COMMIT_SHA、GITHUB_SHA、
SOURCE_COMMIT、GIT_COMMIT、HEROKU_SLUG_COMMIT 等。不要在运行进程中通过 shell 调用
git——许多生产镜像中没有 git 或工作树。如果没有可用的环境变量来源,请省略该属性;不提供 SHA 没关系,不提供 URL 则不行。
请严格使用 vcs.repository.url.full 和 vcs.ref.head.revision 这两个名称——它们是 OTel 语义约定中的键。不要另行发明 git.repo 或 app.repo_url 之类的属性。
信号
每个已插桩服务的基线目标,是按软件组件采集 RED 指标:操作次数、错误次数和操作耗时。必须满足以下两点:
- 每个信号都要设置
service.name,以便按服务汇总 RED 指标。 - 每个不同的工作单元都要生成独立的 span/指标序列,并带有低基数操作标识符,例如 HTTP 路由模板、队列处理器名称、定时任务名称、RPC 方法等。必须能够按操作查询 RED 指标,而不只是按服务查询。
如果某个服务没有针对其主要工作(入站 HTTP 请求、队列处理器、定时任务、后台循环等)按操作生成这三项指标的机制,则该服务的接入尚未完成。
- 链路追踪:所有关键操作都要有带相关属性的 span。每个服务的每个入站工作单元至少要有一个 span——通常由 HTTP/框架自动插桩生成,否则就在请求/处理器入口处手动接入
withSpan(或对应语言中的等效机制)。 - 日志:采用结构化格式,简洁明了,通过 OTLP 转发,并与 trace/span 关联。
- 指标:为关键操作采集低基数计数器/直方图。
- 尽可能包含租户/组织/项目相关信息。
- 除非仓库已将原始用户 ID 或请求 ID 视为有界的类租户 ID,否则不要将其放入指标标签。
HTTP 和框架插桩
为每项服务安装与其语言和框架对应的标准 OpenTelemetry HTTP/服务器插桩(例如,Node 中的
@opentelemetry/instrumentation-http 加上框架包,Python 中的 opentelemetry-instrumentation-fastapi/-django/-flask 等),并在缺少时将其添加到 package.json/pyproject.toml。这会填充 http.server.request.duration、http.request.method 和 http.response.status_code,让 RED 无需按路由编写代码即可正常工作。
如果服务使用的框架或运行时没有可用的自动插桩(自定义服务器、特殊运行时、通过非 HTTP 传输的 RPC、后台工作器循环),则应在入口点手动接入 span,确保每个工作单元都生成一个带有 http.* 或适用于该操作的属性及状态的 span。不要以服务“只有业务 span”为由跳过此步骤——这类 span 无法提供按服务划分的 RED 指标。
错误
每个表示工作单元的跨度都必须以一致的方式报告失败,以便能够推导错误计数:
- 捕获到异常时,调用
span.recordException(err)和span.setStatus({ code: SpanStatusCode.ERROR, message })(或该语言中的 等效写法)。HTTP 5xx 通常由自动插桩处理;但对于已处理的错误和手动接入的跨度,仍需执行这些操作。 - 在业务跨度和对应的指标数据点上设置
"success"或"error"的outcome属性,这样无需按状态码关联数据,单个低基数维度就能将 RED 拆分为成功与错误。 - 对于已知的错误类别,还要将
error.type设为简短的低基数字符串(例如"timeout"、"validation"、"upstream_5xx")。不要使用异常消息,因为其取值范围不受限制。 - 不要在
withSpan回调中悄悄吞掉异常;记录后重新抛出,这样外围跨度和调用方都能感知失败。
大模型指标
如果应用使用大模型,首先查看是否已有供应商插桩能够捕获模型、供应商、令牌和错误跨度。在 JavaScript/TypeScript 中,对于受支持的 SDK,优先使用 OpenInference 包,例如
@arizeai/openinference-instrumentation-anthropic。保持实际的供应商调用原生且易读。
const response = await client.messages.create({
model,
max_tokens: 100,
messages,
});
每个供应商调用点仍需提供足够的遥测信息,以便解答使用情况相关的问题。如果供应商插桩支持捕获模型、供应商和令牌跨度,就由它负责。不要在每个应用调用点重复这些属性,也不要在产品处理程序中加入供应商定价表或成本计算。Superlog 会在 UI/查询层根据捕获的供应商、模型和令牌数据,集中计算大模型的估算成本。
llmInputTokens.add(inputTokens, {
"tenant.id": tenantId,
"gen_ai.provider.name": "anthropic",
"gen_ai.request.model": model,
"app.gen_ai.use_case": "voice.initial_greeting",
"app.gen_ai.call_site": "_callMugCopyLlm",
outcome: "success",
});
仅当供应商插桩无法捕获令牌用量时,才使用计数器统计累加总量:
llm.tokens.inputllm.tokens.output
令牌计数器使用 unit="tokens" 或 SDK 中的等效写法。如果 OpenInference/供应商插桩已经捕获令牌用量,就不要为了保持一致而重复添加令牌计数器。对于常规大模型调用,不要添加 llm.cost_usd 或类似的应用侧成本指标;成本应由 Superlog 的集中定价层处理。
使用直方图表示延迟/耗时分布。
对于大模型供应商/模型/令牌属性,优先使用当前的 gen_ai.* 语义约定风格属性名称;对于用例和调用点等有界应用维度,使用 app.gen_ai.*。避免另行发明 llm.* 属性,除非代码仓库已统一采用这些属性。
如果应用调用 OpenAI、Anthropic 和 Google 的服务,则应为这三者全部添加插桩。
冒烟检查
当代码仓库中有合适的位置时,应添加持久的冒烟检查入口,例如 README、TESTING 指南、脚本、npm 命令、pytest 或已检入的命令说明。
冒烟检查应明确验证:在存在 OTel 环境变量的情况下,启动/导入过程能够顺利完成,从而确保供应商配置、导出器构造、日志桥接和框架插桩均可无错误地初始化。然后,在条件允许时,执行一次实际的插桩跨度/日志/指标操作,或尝试进行 OTLP 导出。通用健康检查路由只能证明服务器能够响应;应优先选择能够经过所添加插桩的操作。