superlog-debug

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Superlog production debugging

Superlog生产环境调试

When the user is investigating something happening in production, query their actual telemetry before reasoning about the code. Superlog ingests OpenTelemetry traces, logs, and metrics for the user's services — the answer to "why did this 500?" / "is the deploy healthy?" / "what changed?" is almost always in there.
当用户在排查生产环境中发生的问题时,先查询实际遥测数据再分析代码。Superlog会采集用户服务的OpenTelemetry链路追踪、日志和指标数据——诸如“为什么出现500错误?”/“部署是否正常?”/“发生了什么变化?”这类问题的答案几乎都能在这些数据中找到。

When to activate

触发时机

Activate as soon as the user signals they are looking into real production behavior. Examples:
  • "users can't sign in" / "checkout is broken" / "this is 500ing in prod"
  • "is the deploy healthy?" / "did my PR regress anything?"
  • "what's our p95 on /api/foo right now?" / "how many errors in the last hour?"
  • "what's been happening with the worker overnight?"
  • An incident channel message, a Sentry/PagerDuty link, an on-call ping.
Skip when:
  • The work is local only (worktree dev, tests, type errors, lint).
  • The user already pasted the relevant logs / traces / span.
  • The question is purely "how is this code structured?" with no prod angle.
当用户表明正在查看真实生产环境行为时,立即激活。示例场景:
  • “用户无法登录”/“结账功能故障”/“生产环境出现500错误”
  • “部署是否正常?”/“我的PR是否导致了回归问题?”
  • “当前/api/foo接口的p95延迟是多少?”/“过去一小时有多少错误?”
  • “Worker服务整晚的运行情况如何?”
  • 事件频道消息、Sentry/PagerDuty链接、值班呼叫。
以下情况无需激活:
  • 仅本地工作(开发工作区、测试、类型错误、代码检查)。
  • 用户已粘贴相关日志/链路追踪/跨度信息。
  • 问题仅涉及“代码结构如何?”,无生产环境相关角度。

Prerequisite: the Superlog MCP must be installed

前提条件:必须安装Superlog MCP

The tools below are exposed by the Superlog MCP server. If they are not available in the current agent, install it first.
For Claude Code:
claude mcp add --transport http superlog https://api.superlog.sh/mcp
For Codex:
codex mcp add superlog --url https://api.superlog.sh/mcp
codex mcp login superlog
For Cursor and others: copy the
mcpServers
snippet from https://superlog.sh/ → Connect.
After install, restart the agent and authenticate via the OAuth flow the MCP triggers on first use.
以下工具由Superlog MCP服务器提供。如果当前Agent中没有这些工具,请先安装。
针对Claude Code
claude mcp add --transport http superlog https://api.superlog.sh/mcp
针对Codex
codex mcp add superlog --url https://api.superlog.sh/mcp
codex mcp login superlog
针对Cursor及其他工具:从https://superlog.sh/ → Connect页面复制
mcpServers
代码片段。
安装完成后,重启Agent,并通过MCP首次使用时触发的OAuth流程完成认证。

First call every session

每次会话的首次调用

superlog.get_active_project
If it is not the project the user is debugging, switch:
superlog.list_projects
superlog.set_active_project { project_id: "<id>" }
You can also pass
project_id
on any individual call without changing session state. If the user has multiple environments wired as separate projects (e.g.
prod
vs
staging
), confirm which one before querying.
superlog.get_active_project
如果当前项目不是用户要调试的项目,请切换:
superlog.list_projects
superlog.set_active_project { project_id: "<id>" }
你也可以在单个调用中传入
project_id
而不改变会话状态。如果用户将多个环境配置为独立项目(例如
prod
staging
),查询前请确认具体环境。

Tool cheatsheet

工具速查表

All query tools default to the active project and to the last 1 hour. Override with
range: { since, until }
— both accept ISO-8601 (
"2026-05-28T14:00:00Z"
) or ClickHouse expressions (
"now() - INTERVAL 30 MINUTE"
).
ToolUse for
superlog.list_services
Confirm which services emitted telemetry in the window
superlog.query_logs
Search log bodies; filter by
service
,
severity
,
resource_attrs
,
log_attrs
superlog.query_traces
Find slow/errored spans; filter by
service
,
span_name
,
min_duration_ms
,
status_code
,
span_attrs
superlog.query_metrics
Pull recent metric points by
metric_name
+
service
superlog.list_alerts
/
get_alert
Check existing alerts that may already cover what the user is seeing
superlog.list_dashboards
/
get_dashboard
Find an existing dashboard for the affected surface before building queries from scratch
所有查询工具默认使用当前活跃项目和过去1小时的数据。可通过
range: { since, until }
覆盖时间范围——
since
until
均支持ISO-8601格式(
"2026-05-28T14:00:00Z"
)或ClickHouse表达式(
"now() - INTERVAL 30 MINUTE"
)。
工具适用场景
superlog.list_services
确认在指定时间窗口内哪些服务发送了遥测数据
superlog.query_logs
搜索日志内容;可按
service
severity
resource_attrs
log_attrs
过滤
superlog.query_traces
查找缓慢/出错的跨度;可按
service
span_name
min_duration_ms
status_code
span_attrs
过滤
superlog.query_metrics
metric_name
+
service
获取近期指标数据
superlog.list_alerts
/
get_alert
检查是否已有覆盖用户当前问题的告警
superlog.list_dashboards
/
get_dashboard
在从头构建查询前,先查找针对受影响服务的现有仪表盘

query_logs
tips

query_logs
使用技巧

  • severity
    matches the stored OTel severity text case-insensitively. Use the short forms the SDKs actually emit —
    "ERROR"
    ,
    "WARN"
    ,
    "INFO"
    ,
    "DEBUG"
    not
    "WARNING"
    , which matches nothing because the stored text is
    WARN
    . Filter aggressively — error-only is usually the right starting point during an incident.
  • search
    is a case-insensitive substring match on the log body. Cheap and effective for finding a stack trace or a specific message.
  • log_attrs
    filters per-record attributes (e.g.
    event.name
    , custom structured fields the app sets on each log).
  • resource_attrs
    filters service-level attributes from the OTel resource (e.g.
    deployment.environment.name=production
    ,
    service.version=1.42.0
    ). Use the current OTel semconv keys —
    deployment.environment.name
    superseded the old
    deployment.environment
    , and apps on recent SDKs only emit the new one. Each entry also accepts an optional
    op
    of
    eq
    (default),
    neq
    , or
    not_contains
    .
  • The response includes a
    resource_attrs
    map per log, so you can read service / env / version off the result without a second call.
  • Logs emitted outside any span will have empty
    trace_id
    /
    span_id
    strings — that is expected, not a bug. Don't conclude the trace pipeline is broken just because some logs lack trace context.
  • severity
    对存储的OTel级别文本进行不区分大小写匹配。请使用SDK实际输出的短格式——
    "ERROR"
    "WARN"
    "INFO"
    "DEBUG"
    ——不要使用
    "WARNING"
    ,因为存储的文本是
    WARN
    ,无法匹配。过滤时要精准——事件排查期间通常应从仅查看错误日志开始。
  • search
    是对日志内容的不区分大小写子串匹配,简单高效,可用于查找堆栈跟踪或特定消息。
  • log_attrs
    用于过滤单条日志记录的属性(例如
    event.name
    、应用为每条日志设置的自定义结构化字段)。
  • resource_attrs
    用于过滤OTel资源的服务级属性(例如
    deployment.environment.name=production
    service.version=1.42.0
    )。请使用最新的OTel语义规范键——
    deployment.environment.name
    已取代旧的
    deployment.environment
    ,使用最新SDK的应用仅会输出新键。每个条目还可选择
    op
    参数,包括
    eq
    (默认)、
    neq
    not_contains
  • 响应结果中每条日志都包含
    resource_attrs
    映射,因此无需二次调用即可查看服务/环境/版本信息。
  • 在任何跨度之外发送的日志,其
    trace_id
    /
    span_id
    字段为空——这是正常现象,并非bug。不要仅因部分日志缺少链路上下文就断定链路追踪管道出现故障。

query_traces
tips

query_traces
使用技巧

  • HTTP status codes are in
    span_attrs
    , not in
    status_code
    .
    OTel's
    status_code
    is the semantic OK/ERROR/UNSET — and by OTel HTTP semconv, only 5xx server responses auto-flip a span to ERROR. To find 4xx responses, use:
    span_attrs: [{ key: "http.response.status_code", value: "404" }]
  • The
    status_code
    filter takes the enum form (
    STATUS_CODE_OK
    ,
    STATUS_CODE_ERROR
    ,
    STATUS_CODE_UNSET
    ), but the value the response returns on each span is the title-case form (
    "Ok"
    ,
    "Error"
    ,
    "Unset"
    ) — don't try to equality-match the response against the enum.
  • For "slow X requests" use
    service
    +
    span_name
    +
    min_duration_ms: 1000
    .
  • For route-level filtering use
    span_attrs
    with
    http.route
    (the template, e.g.
    /api/users/:id
    ) — not the raw URL, which has high cardinality.
  • For database calls, filter by an HTTP-style client span pointing at the DB host, or by
    db.system
    if the app's instrumentation emits it (some SDKs don't — check
    span_attrs
    on a sample span first).
  • Each returned span includes both
    span_attrs
    and
    resource_attrs
    , so you can read the service version, env, and instance off the result directly.
  • HTTP状态码在
    span_attrs
    中,而非
    status_code
    。OTel的
    status_code
    是语义化的OK/ERROR/UNSET——根据OTel HTTP语义规范,只有5xx服务器响应会自动将跨度标记为ERROR。要查找4xx响应,请使用:
    span_attrs: [{ key: "http.response.status_code", value: "404" }]
  • status_code
    过滤器接受枚举形式(
    STATUS_CODE_OK
    STATUS_CODE_ERROR
    STATUS_CODE_UNSET
    ),但响应结果中每个跨度返回的是标题格式(
    "Ok"
    "Error"
    "Unset"
    )——不要尝试将响应结果与枚举值进行相等匹配。
  • 要查找“缓慢的X请求”,请使用
    service
    +
    span_name
    +
    min_duration_ms: 1000
  • 要按路由过滤,请使用
    span_attrs
    搭配
    http.route
    (路由模板,例如
    /api/users/:id
    )——不要使用原始URL,因为其基数过高。
  • 对于数据库调用,可按指向数据库主机的HTTP风格客户端跨度过滤,或按
    db.system
    过滤(如果应用的 instrumentation 会输出该字段——部分SDK不会,需先查看样本跨度的
    span_attrs
    )。
  • 返回的每个跨度都包含
    span_attrs
    resource_attrs
    ,因此可直接从结果中查看服务版本、环境和实例信息。

query_metrics
tips

query_metrics
使用技巧

  • Always pass
    metric_name
    (and usually
    service
    ). The call works without them but returns whatever was most recently written, which is rarely what you want.
  • Each returned point has
    kind
    (
    gauge
    /
    sum
    /
    histogram
    /
    summary
    ),
    metric_name
    ,
    unit
    ,
    service
    , plus the per-point
    attributes
    (the series dimensions — route, status, tenant, etc.) and
    resource_attrs
    . Use
    attributes
    to disambiguate which series a point belongs to.
  • gauge/sum points carry a scalar
    value
    . histogram/summary points have no scalar value: they carry
    count
    and
    sum
    instead (and histograms also carry
    min
    /
    max
    ). So for a histogram, average =
    sum / count
    , and
    value
    is
    null
    — that's expected, read
    count
    /
    sum
    /
    min
    /
    max
    .
  • For rates, pull the underlying counter over two time windows and diff yourself rather than expecting the MCP to compute it. For latency percentiles, build a dashboard widget (the dashboard query layer reconstructs histogram quantiles); the raw
    query_metrics
    points won't give you p95 directly.
  • 务必传入
    metric_name
    (通常还要传入
    service
    )。不传入这些参数时调用也能运行,但返回的是最近写入的任意数据,几乎不会是你需要的内容。
  • 返回的每个数据点都包含
    kind
    gauge
    /
    sum
    /
    histogram
    /
    summary
    )、
    metric_name
    unit
    service
    ,以及每个数据点的
    attributes
    (系列维度——路由、状态、租户等)和
    resource_attrs
    。使用
    attributes
    可明确数据点所属的系列。
  • gauge/sum类型的数据点携带标量
    value
    histogram/summary类型的数据点没有标量值:它们携带
    count
    sum
    (直方图还携带
    min
    /
    max
    )。因此对于直方图,平均值 =
    sum / count
    ,而
    value
    null
    ——这是正常现象,请查看
    count
    /
    sum
    /
    min
    /
    max
  • 如需计算速率,请在两个时间窗口内获取基础计数器数据并自行计算差值,不要依赖MCP计算。如需延迟百分位数,请构建仪表盘组件(仪表盘查询层会重建直方图分位数);原始
    query_metrics
    数据点无法直接提供p95值。

Investigation playbooks

排查指南

"Is X broken in prod right now?"

“当前生产环境中X是否故障?”

  1. list_services
    over the last 30 minutes — is the service even reporting? Silence is a signal.
  2. query_logs
    with
    service: "<svc>"
    ,
    severity: "ERROR"
    , last 30 minutes. Quote a sample stack trace verbatim to the user.
  3. query_traces
    with
    service: "<svc>"
    ,
    status_code: "STATUS_CODE_ERROR"
    and/or
    span_attrs
    filtering on
    http.response.status_code
    to catch 4xx.
  4. If errors cluster on a route, pull the slowest recent traces for that route and read
    SpanAttributes
    for the failing operation (DB statement, downstream URL, exception message).
  1. 在过去30分钟内调用
    list_services
    ——服务是否在上报数据?无数据本身就是一个信号。
  2. 调用
    query_logs
    ,参数为
    service: "<svc>"
    severity: "ERROR"
    、时间范围过去30分钟。将样本堆栈跟踪原封不动地告知用户。
  3. 调用
    query_traces
    ,参数为
    service: "<svc>"
    status_code: "STATUS_CODE_ERROR"
    ,和/或通过
    span_attrs
    过滤
    http.response.status_code
    以捕获4xx错误。
  4. 如果错误集中在某条路由,请获取该路由最近的最慢链路追踪,并查看
    SpanAttributes
    以找出失败操作(数据库语句、下游URL、异常消息)。

"This endpoint is slow"

“该接口响应缓慢”

  1. query_traces
    with
    service
    , plus either
    span_name
    or
    span_attrs: [{ key: "http.route", value: "/api/foo" }]
    , plus
    min_duration_ms: 1000
    , last hour.
  2. Sort/eyeball the slowest spans and expand
    span_attrs
    (and
    resource_attrs
    for service version / env). Look for: long DB calls (high duration with
    http.host
    pointing at the DB or
    db.system
    set), downstream HTTP fanout, queue waits.
  3. If you find a slow child operation, re-query that span name directly to see if it is globally slow or just slow on this route.
  1. 调用
    query_traces
    ,参数为
    service
    ,加上
    span_name
    span_attrs: [{ key: "http.route", value: "/api/foo" }]
    ,再加上
    min_duration_ms: 1000
    ,时间范围过去1小时。
  2. 对最慢的跨度进行排序/查看,并展开
    span_attrs
    (以及
    resource_attrs
    查看服务版本/环境)。查找:长时间数据库调用(高延迟且
    http.host
    指向数据库或设置了
    db.system
    )、下游HTTP扇出、队列等待。
  3. 如果发现缓慢的子操作,请直接查询该跨度名称,查看是全局缓慢还是仅该路由缓慢。

"Did my deploy regress anything?"

“我的部署是否导致了回归问题?”

  1. Note the deploy timestamp (ask the user if not obvious).
  2. query_logs
    severity: "ERROR"
    for the affected service across two equal windows: one before, one after. Compare counts and unique error signatures.
  3. query_metrics
    for the request rate, error rate, and latency metrics over both windows.
  4. query_traces
    status_code: "STATUS_CODE_ERROR"
    post-deploy, scoped by
    resource_attrs: [{ key: "service.version", value: "<new-version>" }]
    if the app tags releases. The returned spans carry
    resource_attrs
    , so you can confirm which version emitted each error.
  1. 记录部署时间(如果不明确,请询问用户)。
  2. 针对受影响服务,在部署前后两个相等的时间窗口内调用
    query_logs
    ,参数为
    severity: "ERROR"
    。比较错误数量和唯一错误特征。
  3. 在两个时间窗口内调用
    query_metrics
    获取请求率、错误率和延迟指标。
  4. 如果应用会标记版本,在部署后调用
    query_traces
    ,参数为
    status_code: "STATUS_CODE_ERROR"
    ,并通过
    resource_attrs: [{ key: "service.version", value: "<new-version>" }]
    过滤。返回的跨度包含
    resource_attrs
    ,因此可确认每个错误由哪个版本产生。

"What was this service doing overnight?"

“该服务整晚的运行情况如何?”

  1. list_services
    with the overnight
    range
    to confirm continuous reporting.
  2. query_logs
    severity: "ERROR"
    then
    severity: "WARN"
    across the window — read for clusters and time-of-day patterns.
  3. query_metrics
    on the service's key business counters to spot drops or spikes.
  1. 使用整晚的
    range
    调用
    list_services
    ,确认服务持续上报数据。
  2. 在整晚时间窗口内调用
    query_logs
    ,先查看
    severity: "ERROR"
    ,再查看
    severity: "WARN"
    ——查找错误集群和时段模式。
  3. 调用
    query_metrics
    获取服务关键业务计数器数据,查看是否有下降或峰值。

"Are users hitting this code path?"

“用户是否在使用该代码路径?”

  1. query_traces
    with
    service
    +
    span_name
    (or
    span_attrs
    filtering on a custom business attribute like
    feature.flag
    or
    tenant.id
    ).
  2. If counts are zero, double-check the span name and attribute keys against the source — typos here are the #1 cause of false negatives.
  1. 调用
    query_traces
    ,参数为
    service
    +
    span_name
    (或通过
    span_attrs
    过滤自定义业务属性,如
    feature.flag
    tenant.id
    )。
  2. 如果计数为零,请对照源代码再次检查跨度名称和属性键——拼写错误是导致假阴性的首要原因。

Output discipline

输出规范

  • Lead with the finding, not the methodology. "47 ERROR logs in
    api
    in the last 15 min, all
    TimeoutError
    from
    db.query
    " beats a paragraph about which tool you called.
  • Quote real evidence: timestamps, trace IDs, span IDs, exact error messages. The user should be able to pivot from your answer into the Superlog UI for any of them.
  • State the window: "in the last 30 min" / "since 14:00 UTC". A finding without a window is not actionable.
  • Distinguish zero from unknown. "Zero matching spans" means the query ran and returned nothing — call that out explicitly. "I couldn't query because the active project isn't this service's project" is a different sentence; say so.
  • Don't over-recommend. If telemetry shows the service is healthy, say so plainly and stop. Don't manufacture a "next step" to look busy.
  • 先给出结果,再说明方法。“过去15分钟内
    api
    服务有47条ERROR日志,均为来自
    db.query
    TimeoutError
    ”比描述你调用了哪些工具的段落更有效。
  • 引用真实证据:时间戳、链路ID、跨度ID、准确的错误消息。用户应能从你的回答直接跳转到Superlog UI查看详情。
  • 说明时间范围:“过去30分钟内”/“自UTC时间14:00起”。没有时间范围的结果不具备可操作性。
  • 区分零结果与未知情况。“无匹配跨度”表示查询已执行且未返回任何结果——请明确指出。“无法查询,因为当前活跃项目不是该服务的项目”是另一种情况,请如实说明。
  • 不要过度推荐。如果遥测数据显示服务正常,请直接说明并停止。不要为了显得忙碌而编造“下一步操作”。

Pairing with other context

与其他上下文结合使用

The Superlog MCP only sees what the user's apps export as OpenTelemetry. It does not see:
  • Row-level database state — query the DB directly (or via a Postgres/MySQL MCP if installed).
  • Cloud-provider host/container logs that never made it into the OTel pipeline (CloudWatch, GCP Logging, Fly logs, Railway logs, etc.).
  • Queue depth (SQS, RabbitMQ, …) unless the app explicitly emits a metric for it.
  • Anything the app simply never instrumented.
If the MCP returns nothing for a service, don't conclude the service is silent — first check whether telemetry is reaching ingest at all. A missing/misconfigured exporter, a wrong
service.name
, or a project-mismatched ingest key all show up as "MCP sees nothing" even when the service is alive and noisy at the host level. The
superlog-onboard
skill covers the install side if the user needs to fix that.
One specific failure to rule out first: every ingest request is 401-ing even though the token is valid. The token is sent under the wrong header name. Ingest reads the token only from
x-api-key: <token>
or
Authorization: Bearer <token>
(literal
Bearer 
prefix required); anything else —
api-key
,
x-superlog-token
, or
Authorization: <token>
without
Bearer 
— returns 401 on every request, so the install looks broken when the key is actually fine. A quick way to confirm the key works independently of the app's exporter config:
bash
curl -i -X POST https://intake.superlog.sh/v1/traces \
  -H "x-api-key: sl_public_..." \
  -H "content-type: application/json" --data '{"resourceSpans":[]}'
Superlog MCP只能看到用户应用导出的OpenTelemetry数据。它无法看到:
  • 数据库行级状态——请直接查询数据库(或通过已安装的Postgres/MySQL MCP查询)。
  • 未进入OTel管道的云服务商主机/容器日志(CloudWatch、GCP Logging、Fly日志、Railway日志等)。
  • 队列深度(SQS、RabbitMQ等),除非应用明确导出了相关指标。
  • 应用从未进行instrumentation的任何内容。
如果MCP未返回某服务的任何数据,不要直接断定服务无数据上报——首先检查遥测数据是否已到达采集端。导出器配置缺失/错误、
service.name
错误、采集密钥与项目不匹配等情况,都会导致“MCP无数据”,即使服务在主机层面正常运行并产生大量日志。如果用户需要修复此类问题,可使用
superlog-onboard
技能。
首先需要排除的一个特定故障:即使令牌有效,所有采集请求仍返回401。这是因为令牌发送时使用了错误的头名称。采集端仅从
x-api-key: <token>
Authorization: Bearer <token>
(必须包含字面量
Bearer 
前缀)读取令牌;其他任何形式——
api-key
x-superlog-token
或不带
Bearer 
前缀的
Authorization: <token>
——都会导致每次请求返回401,因此即使密钥正确,安装也会看起来失败。快速确认密钥是否独立于应用导出器配置生效的方法:
bash
curl -i -X POST https://intake.superlog.sh/v1/traces \
  -H "x-api-key: sl_public_..." \
  -H "content-type: application/json" --data '{"resourceSpans":[]}'

2xx → key is valid; the app is sending the wrong header. Fix the exporter to use x-api-key.

返回2xx → 密钥有效;应用发送了错误的头。请修改导出器使用x-api-key。

401 → the token itself is wrong/revoked.

返回401 → 令牌本身错误/已撤销。

undefined
undefined

Hard rules

硬性规则

  • Read-only by default.
    query_*
    and
    list_*
    calls are safe.
    create_alert
    ,
    update_dashboard
    ,
    delete_*
    , etc. mutate the user's account — never invoke those without an explicit ask, and even then confirm the exact change first.
  • Don't echo full ingest tokens or secrets that show up in span/log attributes back to chat. Truncate if you must reference them.
  • Don't switch the active project silently. If you call
    set_active_project
    , tell the user you did and why.
  • Match the scope of the question. A user asking "is prod ok?" wants a 2-line answer, not a 12-query sweep. Escalate depth only as the investigation requires it.
  • 默认只读
    query_*
    list_*
    调用是安全的。
    create_alert
    update_dashboard
    delete_*
    等操作会修改用户账户——除非用户明确要求,否则不要调用这些操作;即使有明确要求,也要先确认具体变更内容。
  • 不要回显跨度/日志属性中出现的完整采集令牌或密钥到聊天中。如果必须引用,请截断。
  • 不要静默切换活跃项目。如果调用
    set_active_project
    ,请告知用户你已执行该操作及原因。
  • 匹配问题范围。用户询问“生产环境是否正常?”时,需要的是两行以内的回答,而非12次查询的详细结果。仅在排查需要时才增加深度。