关于 superlog-onboard
用于为仓库中的所有可运行服务接入 OpenTelemetry,并将追踪、日志和指标发送到 Superlog 的编码技能。它规定使用原生 SDK 启动遥测,并处理项目级公开令牌。
主要功能
- 01盘点可运行应用与服务
- 02配置原生 OpenTelemetry SDK
- 03导出追踪、日志和指标
- 04将应用日志桥接到 OTLP
- 05设置服务与仓库属性
- 06处理 Superlog 公开写入令牌
适用场景
- 01为多服务仓库接入 Superlog
- 02为移动端和边缘服务添加遥测
- 03配置日志与当前跨度关联
- 04检查导出器请求头和接收配置
MCP 相关
此技能指导应用将 OpenTelemetry 追踪、日志和指标导出到 Superlog,并说明遥测导出器使用的端点和公开令牌请求头。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ superloglabs/ skills --skill superlog-onboard安装后在 Claude Code 中输入/superlog-onboard确认已加载。
详细介绍
Superlog 接入
将 OpenTelemetry 跟踪、日志和指标接入用户的项目,使遥测数据流向 Superlog。覆盖仓库中的每个应用和服务,而不仅仅是用户当前所在的应用。
优先使用原生 OpenTelemetry API 和框架文档中说明的引导方式,而不是自定义辅助层。如果遇到特定技术栈的问题,请查阅该语言的 OTel 文档,不要凭猜测。
编辑前,请阅读适用的配套技能:
otel-onboarding-style,了解通用 OTel 风格。otel-python-style,适用于 Python 服务。otel-fastapi-style,适用于 FastAPI 服务。otel-livekit-style,适用于 LiveKit Agent。otel-nextjs-style,适用于 Next.js/Vercel 应用。otel-expo-style,适用于 Expo / React Native 应用。otel-supabase-edge-style,适用于 Supabase Edge Functions。otel-generic-style,适用于其他任何语言(Go、Java/Kotlin、Ruby、Rust、.NET/C#、PHP、Elixir、纯 Node 等);若以上均不适用,则使用此项作为后备方案。
步骤 0 — 端点和公开令牌处理
OTLP 端点始终为 https://intake.superlog.sh,并直接写入引导代码。
Superlog 公开写入令牌以 sl_public_ 开头。它限定于项目、仅可写入,并且有意设计为可安全地包含在应用程序源码中,包括浏览器和移动端构建产物。将其视同 PostHog 项目令牌、Sentry DSN 或 Datadog RUM 客户端令牌:它可以向一个项目发送遥测数据,但无法读取数据、更改设置或访问 Superlog 帐户。
将公开令牌内联为与端点相邻的常量。不要将其放入 .env 文件、部署设置或生成的 shell 命令中;源码级配置是预期的接入方式,也能避免因缺少环境变量导致部署失败。
如果 OTLP 导出器需要请求头,请通过导出器构造函数将公开令牌作为 x-api-key 请求头传入。这是接入失败最常见的原因:令牌有效,但导出器使用了错误的请求头名称(或根本没有发送请求头),因此每个请求都会收到 401,导致安装看似失败,而实际上密钥没有问题。写入端只从两个位置读取令牌——x-api-key: <token>,或 Authorization: Bearer <token>(必须包含字面上的 Bearer 前缀)。请使用 x-api-key;它可以避免 Bearer 前缀陷阱,也能兼容会剥离 Authorization 的代理/SDK。不要使用其他请求头名称(api-key、x-superlog-token、不带 Bearer 的 Authorization: <token>)——这些方式都会返回 401。
将其封装为单行辅助函数,让请求头名称只出现在一个位置,并且定义该辅助函数——绝不要调用未定义的 superlogHeaders:
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}
两个处理路径,无需提问:
提示词中包含公开令牌
如果调用提示词中包含 sl_public_... 令牌,请验证其前缀,并将其内联到你编写的每个遥测引导文件中。不要在聊天中输出完整令牌;它会像其他公开客户端令牌一样显示在代码差异中。
无公开令牌
在本地生成一个公开令牌,立即注册一个注册意向,然后并行继续操作——不要因为注册而阻塞安装。
-
在本地生成一个随机的明文公开摄取令牌,格式为
sl_public_<base64url-ish random bytes>。前缀之后至少使用 32 字节的熵。将明文保存在内存中,以便内联到引导文件中,但绝不要在聊天中完整打印令牌。 -
计算
keyHash = sha256(plaintextToken),结果为小写十六进制;计算keyPrefix = 令牌前缀加上前缀之后的前 6 个令牌字符。 -
使用
Content-Type: application/json,向https://api.superlog.sh/api/signup-intents发送POST请求,请求体如下:{ "keyHash": "<sha256 hex>", "keyPrefix": "<short public token prefix>", "returnTo": null }如果 Agent 运行时提供了返回当前对话的安全返回链接/深层链接,请将其作为
returnTo传入;否则使用null。绝不要在此请求中放入明文令牌。 -
响应中包含
id、signupUrl和expiresAt。在用户的默认浏览器中打开signupUrl(open "$signupUrl"/xdg-open "$signupUrl"/start "" "%signupUrl%"),并在聊天中打印该 URL。简要说明注册标签页已打开(GitHub/Slack 集成会在那里完成),并且安装将在最后检查摄取状态——无需打断用户当前的流程。 -
不要等待注册完成。 使用生成的明文令牌作为引导源,继续执行步骤 1–4。步骤 4 是关卡:它会发送真实遥测数据,并根据响应代码判断用户是否仍需完成注册。
步骤 1 — 列出仓库中的每个应用/服务
在进行任何埋点之前,先全面检查项目。检查工作区清单(pnpm-workspace.yaml、根目录 package.json 中的 workspaces、go.work、Cargo 工作区、Python pyproject.toml 工作区配置,以及 apps/* 和 services/* 约定)。识别每项服务:Web 前端、API、工作进程、后台任务、CLI、示例/演示应用、移动应用、Supabase 和/或服务端函数。移动应用和无服务器/边缘函数都在范围内;不要仅仅因为它们是客户端或生命周期短就跳过。没有运行时入口点的纯类型/配置包可以跳过。不要跳过任何可运行的服务,也不要将其留作“范围之外”:本次运行要为所有内容添加埋点,可能不会有后续操作。
开始前先向用户展示列表,以便他们提出更正。
步骤 2 — 为每项服务安装原生 OTel 并进行引导
使用该语言的原生 OpenTelemetry SDK。 如果存在官方包,不要使用供应商封装或手写辅助工具。例如,“原生”包括:Node 服务使用 @opentelemetry/sdk-node,常规 Next.js/Vercel 应用使用 @vercel/otel(sdk-node 会破坏 Next 的 webpack,且会错过框架引导),Vite/SPA/Expo 使用 @opentelemetry/sdk-trace-web 和兼容浏览器/移动端的导出器,Python 使用 opentelemetry-instrumentation-* 和 opentelemetry-sdk,Go 使用 go.opentelemetry.io/otel。
不要使用通用封装 API。避免使用 sendSuperlogSpan、recordCounter、recordLog、startTelemetrySpan 或 withTelemetry 之类的可复用辅助工具。在模块作用域中获取原生 tracer/meter/logger,并直接使用 SDK 自带的 API。在 TypeScript/JavaScript 中,为有边界的业务 span 使用已发布的 @superlog/otel-helpers withSpan 辅助工具,并将 @superlog/otel-helpers 添加到 package.json;只要该包可以安装,这就是必需的,因为它可避免将整个函数扩展为 startActiveSpan 加 try/catch/finally。对于 OpenInference/供应商埋点能够直接观察到的供应商 SDK 调用,不要使用辅助工具包装。如果边缘运行时确实无法加载上游 OTel SDK,请保持 shim 精简、与供应商无关且遵循 OTel 形式:tracer.startActiveSpan、span.setAttributes、SpanStatusCode、meter.createCounter、histogram.record。
连接全部三种信号——追踪、日志和指标。日志通过 OTLP 发送,而不只是写入 stdout——为所用语言配置 OTel 日志桥接,使应用日志(保留现有日志级别和结构化字段)自动携带当前的 trace_id / span_id。用户现有的日志记录器继续正常工作;你只需在底层添加 OTLP 处理器/处理程序。
日志桥接不可省略,也不能仅靠 SDK 初始化来实现——大多数语言 SDK 和框架封装默认会接入追踪(有时也包括指标),但需要显式配置 LoggerProvider + OTLP 日志导出器 + 日志记录处理器 + 连接到现有日志记录器的桥接。示例:Python 标准库需要 LoggerProvider + OTLPLogExporter + 附加到根日志记录器的 LoggingHandler(还需要 LoggingInstrumentor,才能让现有记录关联追踪);Node 需要 @opentelemetry/sdk-logs + 项目日志记录器(pino/winston/bunyan)的插桩;@vercel/otel 需要 logRecordProcessor(s) 选项——没有它,日志就不会离开进程。配套的风格技能会详细说明各技术栈所需的具体配置——请阅读。
需要主动检查的常见日志桥接错误:
- 处理器附加到了具名日志记录器,但应用使用的是根日志记录器(反之亦然)——没有日志会流出。
- 默认级别过滤器(例如 WARNING)吞掉了用户实际想在 Superlog 中查看的 INFO/DEBUG 日志。
BatchLogRecordProcessor在关闭时未刷新 → 短生命周期 CLI、无服务器和边缘函数会丢弃最后一批日志。将shutdown()/forceFlush()接入运行时的退出钩子。- 保留现有供应商传输(Pino → Logtail、Winston → Datadog 等)完全没问题,也是预期做法——但要确保桥接来自日志记录器,而不是再添加第二个传输,通过不同的格式化器重复发送同一行日志。
- 在任何 span 之外发出的日志不会携带
trace_id/span_id。这是正确且预期的行为;不要为此在日志调用周围创建一次性 span。
引导规则:
- 引导文件必须在导入任何框架之前运行。使用语言/框架文档指定的钩子(
--import标志、instrumentation.ts、在main.py顶部导入等)。 - 在引导源代码中直接写入端点(
https://intake.superlog.sh)和公开的写入令牌。不要读取process.env.OTEL_EXPORTER_OTLP_*,也不要编写任何.env文件。(各技术栈的具体写法请参阅对应的框架风格技能。) - 使用 HTTP OTLP 导出器,不要使用 gRPC。gRPC 会引入原生绑定,导致打包器出错并增加容器配置的复杂度。
- 使用项目现有的包管理器(根据锁文件判断)。
- 优先采用幂等的修改。如果配置文件已存在,应修改而不是覆盖。
- 为每个服务在 OTel 资源上设置资源属性:
service.name、service.version、deployment.environment.name和vcs.repository.url.full——仓库的规范 https URL(例如https://github.com/acme/api)。仓库 URL 尤其重要,可以和service.name一起直接写入 SDK 初始化代码;如果构建平台提供了 slug(Vercel 的VERCEL_GIT_REPO_OWNER/VERCEL_GIT_REPO_SLUG、Railway 的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。可以不设置 SHA,但不能不设置 URL。请严格使用 OTel 语义约定中的键,不要自创git.repo/app.repo_url。 框架规则: - Next.js/Vercel:使用
instrumentation.ts和@vercel/otel的registerOTel(...)进行引导。除非仓库已采用@opentelemetry/sdk-node/NodeSDK引导架构且你正在扩展该架构,否则不要改用这种原始引导方式。仅在自动检测无法覆盖的路由处理程序中使用@opentelemetry/api的追踪器/计量器。registerOTel默认不会导出日志——请使用来自@opentelemetry/exporter-logs-otlp-http的OTLPLogExporter,并传入logRecordProcessor(v1)/logRecordProcessors(v2);否则日志不会离开进程。选项名称须与已安装的@vercel/otel主版本匹配。 - **Expo/React Native:**保留现有的 Expo Go/不支持运行时的保护逻辑。在受支持的构建中,于 Sentry 之前以及应用注册/用户代码运行之前调用
initObservability()。在可观测性模块中内联端点和sl_public_令牌;不要为 Superlog 使用EXPO_PUBLIC_*环境变量。 - **Supabase Edge Functions:**目前,原生 Deno OpenTelemetry 无法在托管的 Supabase Edge 上运行。使用上文所述的轻量级 OTel 形态垫片模式;将导出器端点/请求头放在同一个设置区域,并避免使用 Superlog 专属的函数/文件名。
- **Python/FastAPI:**使用
FastAPIInstrumentor.instrument_app(app)等原生检测方式,而不是用手动中间件替换请求处理逻辑。 - **Python/LiveKit:**跨越关闭回调的生命周期跨度可以使用
start_span+trace.use_span(..., end_on_exit=False),并在关闭回调中结束。有界工作仍应使用装饰器或上下文管理器。
与现有可观测性供应商共存。不要移除 Sentry、Datadog、New Relic、Honeycomb、Logtail、Pino 传输器等。 OTel 与它们并行运行。用户明确希望在迁移期间让两种信号都正常流动;是否移除现有方案不由你决定。
第 3 步 — 在业务操作周围添加自定义跨度、指标和日志
自动检测可以捕获 HTTP 请求收发、数据库查询和框架生命周期。这只是基础,并非全部。阅读项目代码,找出当问题出现时,人工运维人员真正希望看到哪些操作。
追踪
为每项关键业务操作添加一个活动跨度。如果已有自动检测跨度,可以直接使用;但如果某项操作还没有跨度,就添加一个。
-
命名:
domain.verb(order.process、payment.charge、email.send、agent.run、interview.create、job.<type>)。 -
属性:实体 ID(order.id、user.id、workspace.id、tenant.id)、数量、关键布尔分支的结果,以及大模型调用的模型名称/提供方。
-
记录异常:在失败路径中调用
span.recordException(err)+span.setStatus({ code: ERROR })。 -
对于边界明确的 Python 函数,优先使用
@tracer.start_as_current_span("operation.name")——同一个调用既可用作装饰器,也可用作上下文管理器;对于整个函数,通常应使用装饰器形式:@tracer.start_as_current_span("do_work") def do_work(): print("doing some work...")装饰器不适用时(例如只需覆盖部分范围、跨度名称是动态的等),请使用上下文管理器。对于有界工作,不要使用独立的
start_span()+ 手动end()。 -
跳过简单的 getter、纯转换和内部辅助函数——任何没有实际延迟或失败可能性的操作都不必处理。
-
绝不要在属性中放入个人身份信息(PII)(电子邮件、密码、令牌、完整请求正文)。
日志
确保日志采用结构化格式并携带操作上下文。具体来说:跨度内发出的每一行日志到达 Superlog 时,都应带有已填充的 trace_id / span_id,并将所有结构化字段(orderId、userId 等)保留为属性。追踪/跨度上下文可能由日志桥接器或集成原生添加,也可能需要额外处理。
使用日志记录操作过程(“starting batch reconcile”“retrying after 3xx”)和异常事件。仅当操作无法恢复且需要人工干预时,才应发出错误日志。
指标
覆盖业务、性能和成本。关注以下三个类别:
- 业务逻辑计数器。 记录每个有意义的状态转换:已创建、已启动、已完成、已失败、已重试。仅使用低基数维度,例如按租户、渠道、状态统计(绝不使用用户 ID/订单 ID)。
- 性能直方图。 记录用户关心的操作延迟、队列深度、批次大小、负载大小。如果项目已有计时工具(
time.perf_counter代码块、自定义LatencyTracker或"[TIMING]"日志行),请复用——根据这些测量值生成直方图,而不是重复测量。 - 成本,尤其是大模型成本。 如果项目调用 OpenAI / Anthropic / Google / 任何大模型提供商,在可用时优先使用 OpenInference 等提供商插桩,以保持原生 SDK 调用的可读性。不要在产品处理程序中添加定价常量或大模型成本计算;Superlog 会在 UI/查询层根据捕获的提供商/模型/令牌属性集中计算预估成本。避免重复统计提供商插桩已捕获的令牌数。
在模块级获取一次 meter,并在模块级创建 instruments,在热路径中递增。不要为每次调用都创建新的 meter。
步骤 4 — 验证应用仍能正常工作
对每个服务:
-
运行项目自身的开发或构建命令(即
package.json/pyproject/Makefile中已有的命令)。确认应用可以正常启动,且没有可追溯到 OTel 安装的问题。同时运行遥测引导冒烟测试来导入或启动应用,以便初始化 provider 设置、exporter 构造、日志桥接和框架插桩。对于 Python 服务,可以运行类似uv run python -c 'from app.main import app; print(app.title)'的导入/启动命令;对于 Node/Next,使用仓库的构建/启动流程。对于服务,使用 curl 至少访问一个路由,让流量经过插桩;条件允许时,选择会触发已插桩操作的路由,而不只是静态健康检查路由。对于 CLI,运行一个真实命令。如果应用自身启动因此出现问题,就不要交付——这属于回归。 -
通过生产环境发送真实遥测数据,并读取响应码——三个信号都要验证。 这是硬性门槛。驱动运行中的应用,使其实际发出至少一个 span、一条日志和一个指标,然后检查 OTLP exporter 对
/v1/traces、/v1/logs和/v1/metrics的 HTTP 响应。要专门触发日志路径,请访问一个会在已插桩操作内部调用项目 logger 的路由(或运行一个 CLI 命令)。接收端的响应状态就是判断依据:- 三者都返回 2xx → 完成。 注册已确认;继续执行步骤 5。不要再引导用户返回注册标签页。
- 任一返回 401/403 → token 尚未确认。 告诉用户前往步骤 0 中的 URL 完成注册(标签页已经打开)。等待用户确认,然后重新运行冒烟测试并再次检查,直到三者都返回 2xx。401/403 时不要宣布成功。
- 任一返回 5xx、超时或从未发出 POST → 存在真实问题。 继续调试,解决后再进行下一步。如果只看到
/v1/traces,说明日志桥接未接通(最常见原因:从未设置LoggerProvider、处理程序挂在了错误的 logger 上、级别筛选过严、缺少@vercel/otel的logRecordProcessor(s),或关闭时未刷新 batch processor)。如果缺少/v1/metrics,说明 meter provider 或 periodic reader 未接通。
引导程序即使加载成功,但从未发出 POST——或者只发送了 traces,却没有日志/指标——都不算部分成功。继续修复后再进行下一步。
步骤 5 — 交接(给用户的最终消息)
只有在步骤 4 中 /v1/traces、/v1/logs 和 /v1/metrics 都返回 2xx 后,才能进入此步骤。token 已内嵌在引导程序源码中——不要在聊天中把它贴出来。遥测数据正在流入用户的项目;接下来需要部署。
变更内容
3–7 条简短、客观的要点,涵盖:安装的软件包、新建或修改的文件,以及新增的业务跨度/指标。若各服务的变更不同,请按服务分别列出;若变更一致,则合并列出。请说明你有意保留的任何现有可观测性供应商(Sentry、Datadog、Logtail、Pino transports 等),明确它们会继续共存。
部署
现在就引导用户部署;不要只说“按平常方式部署”。根据仓库推断最可能的部署路径,并给出一个具体的下一步操作。
- 如果仓库有直接部署工具/配置(
vercel.json、netlify.toml、fly.toml、wrangler.*、railway.json、render.yaml、Dockerfile、package.json中的部署脚本等),请指出目标平台,并在运行任何生产/公开部署命令前征求确认:“我可以用<command>部署到<target>。要我运行吗?”如果用户同意,就运行并查看结果。 - 如果部署由 CI 在推送/合并时触发,请明确说明,并给出用户需要采取的确切下一步:提交/推送/合并分支,或打开现有托管服务控制面板。遵守以下硬性规则:除非用户在技能运行之外明确要求你执行此任务,否则不要通过此技能提交、推送或创建 PR。
- 如果无法确定生产部署路径,请提供最佳的本地替代方案:启动开发服务器,访问一个已接入监控的路由,并告知用户你使用的确切命令,以及未能找到哪些生产部署信息。
- 部署或本地运行后,至少访问一个已接入监控的路由,以便部署环境也能产生跟踪、日志和指标。
无需配置 Superlog 环境变量:端点和公开令牌都在引导程序源码中。
步骤 6 — MCP 建议
不要再由 Agent 手动操作 GitHub 或 Slack。用户注册意向页面会在认证后处理这两项集成;如果用户通过 GitHub 登录,页面仍会验证该应用是否拥有正确的仓库权限。
建议安装 Superlog MCP 服务,让 Agent(Claude Code、Codex、Cursor 等)下次调试时能直接查询遥测数据——无需切换到控制面板,就能在聊天中搜索日志、获取跟踪数据、查看错误率。
对于 Claude Code(最常见的情况——当前技能就是在这里运行的),可提出代为运行:
claude mcp add --transport http superlog https://api.superlog.sh/mcp
这会修改用户的 Claude Code 配置。运行前必须征求确认(用户可能使用自定义的 MCP 作用域,或想安装到其他位置)。如果用户拒绝,请输出命令,供他们稍后自行运行。
对于用户可能使用的其他 Agent,可以提及,但不要代为运行:
- Codex:
codex mcp add superlog --url https://api.superlog.sh/mcp && codex mcp login superlog - Cursor/其他工具:从 https://superlog.sh/ → Connect 复制
mcpServers代码段。
最后用一句话引导用户部署应用——他们已经准备好发布了。
硬性规则
- 绝不要修改项目根目录之外的文件。
- 绝不要提交、推送或创建 PR。
- 未先展示确切命令和目标并获得用户明确确认,绝不要运行生产/公开部署命令。
- 只可内联
sl_public_公开数据摄取令牌。绝不要内联账户/会话/管理员令牌、私钥或供应商 API 密钥。不要在聊天中输出完整令牌。 - 除非用户要求,否则绝不要移除现有可观测性供应商。
- 使用项目现有的包管理器和日志记录器。
- 语言支持原生 OTel 软件包时,优先使用;不要重新实现 SDK 已提供的遥测处理逻辑。
- 如果开发/构建命令因你的监控埋点而报错,这就意味着失败——请修复或报告问题,不要掩盖错误。