关于 traceway
Traceway CLI 的只读技能,帮助排查异常、性能问题并查询可观测性数据,适用于使用 Traceway 的开发与运维人员。支持从仪表板链接和通知定位记录;也可配合 Traceway MCP 服务使用。
主要功能
- 01只读查询 Traceway 数据
- 02异常根因调查
- 03延迟与性能诊断
- 04从链接和通知定位记录
适用场景
- 01调查异常组中的具体事件
- 02追踪端点延迟升高的原因
- 03依据仪表板链接查找遥测记录
MCP 相关
可连接 Traceway MCP 服务;服务与 CLI 使用同一 API 语义,技能知识也可作为资源提供。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tracewayapp/ traceway --skill traceway安装后在 Claude Code 中输入/traceway确认已加载。
附带文件performance.md
详细介绍
Traceway
通过终端中的 traceway CLI 操作 Traceway 实例。参数的第一个词决定执行流程:
| 调用方式 | 流程 |
|---|---|
/traceway login | 登录:如果尚未安装 CLI,则先安装,然后进行身份验证并选择项目 |
/traceway debug <issue ref or bug description> | 调试:定位问题并调查其根本原因 |
/traceway perf <endpoint or symptom> | 性能:根据常见瓶颈清单,诊断延迟或运行缓慢的根本原因 |
/traceway <anything else> | 查询:通过 CLI 读取数据,回答可观测性问题 |
/traceway(无参数) | 询问用户想做什么:登录、调试问题,还是运行查询 |
CLI 正在积极开发中。如果本文档中记录的标志未出现在
traceway <command> --help中,请以二进制文件为准。 如果已连接tracewayMCP 服务,请优先使用其工具,而不是通过 shell 调用 CLI:它们封装了相同的 API,语义也相同,并且本技能的知识可通过其资源获取。该服务就是同一个二进制文件(traceway mcp)。 本技能只读取数据。如需进行更改(归档问题、确认或解决页面、暂停警报、运行监控、撰写事后复盘),用户需要安装单独的traceway-writeCLI 和traceway-write技能。 当用户询问 Traceway 某部分的工作原理(计划、升级流程、状态页、警报规则、影响评分等)时,请使用traceway-learn技能。它是完整的产品指南。
基本规则(适用于所有流程)
- 读取是安全的:任何
list/show/query子命令都可以自由运行;它们绝不会更改服务器状态。 - 此 CLI 只读:
traceway没有任何修改命令,登录也只能读取数据。如需更改(归档问题、确认页面、暂停警报、编辑事后复盘),需要单独的traceway-writeCLI 和traceway-write技能。“查看这个错误”意味着读取它,绝不更改它。 - 输出:管道输出默认为 JSON(TTY 上显示表格)。优先使用 JSON +
jq,并使用--fields a,b,c精简响应。用于初步排查时,将--page-size保持在 10 到 20。 - 时间范围:查询始终要限定时间范围;询问“现在”的问题默认使用
--since 1h,其他情况默认使用--since 24h。--since接受s、m、h、小写Nd(不接受1w,也不接受7d2h)。绝对时间范围通过--from/--to指定(RFC3339)。 - 退出代码:0 表示正常;1 表示通用错误/API 错误;2 表示用法错误;3 表示连接错误;4 表示身份验证错误;5 表示未找到;6 表示速率受限;7 表示服务器 5xx 错误。错误会在 stderr 上输出
{"error":"<stable_id>","message":"...","hint":"...","exit_code":N};请根据error字段进行分支处理。 - 退出代码为 4(身份验证错误)时,不要自行运行
traceway login;请切换到登录流程,让用户输入凭据。 - 切勿猜测修复方案:如果遥测数据无法解释故障,不要凭猜测更改行为。应添加下次能解释故障的检测埋点,并说明仍有哪些未知之处。请参阅调试流程中的“证据不足时”。
解析仪表板 URL
用户会在任何工作流中粘贴仪表板 URL(https://<instance>/<route>)作为参考。根据路由类型进行解析:
| URL 路径 | 标识内容 | 获取方式 |
|---|---|---|
/issues/<hash> 和 /issues/<hash>/events | 异常组(hash = 16 位十六进制字符) | traceway exceptions show <hash> |
/issues/<hash>/<occurrenceId>(UUID) | 组内的一个发生记录 | traceway exceptions occurrence <occurrenceId> --recorded-at <t>,其中 t 是 URL 的 ?t= 参数。直接且快速;还会返回该发生记录的 sessionId 和会话录制。没有 URL?从 traceway exceptions show <hash> 的发生记录中获取 recordedAt |
/endpoints/<endpoint> | 端点组;该片段是经过 URL 编码的端点名称(GET%20%2Fapi%2Fusers%2F%3Aid 即 GET /api/users/:id) | 解码后,运行 traceway endpoints list --search "<decoded name>"(该组没有 ID;endpoints show 用于单个请求,见下一行) |
/endpoints/<endpoint>/<endpointId> | 该端点的一个请求(事务) | traceway endpoints show <endpointId> --recorded-at <t>(t = URL 的 ?t= 参数)。返回请求、其 span 时间线,以及任何关联的异常/消息 |
/tasks/<task> | 后台任务组 | 没有用于查询任务组的 CLI;如需查询单次运行,请使用下一行 |
/tasks/<task>/<taskId> | 单次任务运行 | traceway tasks show <taskId> --recorded-at <t>(t = URL 的 ?t= 参数) |
/sessions/<sessionId> | 会话(期间触发的异常;回放仅在仪表板中提供) | traceway sessions show <sessionId> --started-at <t>。URL 中没有 ?t=;使用会话的开始时间、URL 的 from=,或关联发生记录的 recordedAt(它位于时间范围内)。发生记录通过 sessionId 引用会话 |
/ai-traces/<traceName> | AI 跟踪组 | 没有用于查询跟踪组的 CLI;如需查询单个跟踪,请使用下一行 |
/ai-traces/<traceName>/<traceId> | 单个 AI 跟踪 | traceway ai-traces show <aiTraceId> --recorded-at <t>(使用 URL 中的 UUID,而不是 32 位十六进制跟踪 ID)(t = URL 的 ?t= 参数);返回 token/成本统计数据和对话 |
/logs | 日志页面(其筛选条件不会保存在 URL 中) | 使用从用户描述中获取的标志运行 traceway logs query |
/issues、/endpoints、/metrics、/ | 列表和仪表板页面 | 对应的 list / query 命令 |
时间范围:大多数仪表板 URL 都包含 ?preset=<p> 或 ?from=<iso>&to=<iso>(在页面间保持不变);应遵循这些参数,而不是使用默认时间范围。
preset值5m 30m 60m 3h 6h 12h 24h 3d 7d直接映射到--since;CLI 没有月单位,因此将1M映射为--since 30d,将3M映射为--since 90d。from/to是 ISO 时间戳;通过--from/--to传入,若缺少Z(或正确的时区偏移量),则补上,因为 CLI 要求使用 RFC3339 格式。- 没有时间参数表示页面使用的是默认时间范围;根据基本规则选择
--since。
preset/from/to 为列表/分组视图设置时间范围。详情 URL 还会包含 ?t=<iso>,表示单条记录经过 URL 编码的时间戳。该 t 值正是按 ID 查询命令所需的 --recorded-at(会话则使用 --started-at)。接下来请参阅“按 ID 快速查询”。
快速按 ID 查询(始终传入时间戳)
按 ID 查询详情的命令(exceptions occurrence、endpoints show、tasks show、ai-traces show、sessions show、traces show)必须传入记录的时间戳(--recorded-at;对于会话则传入 --started-at)。遥测表按天分区:传入时间戳后,查询范围会限定在一个较小的窗口内,ClickHouse 只需扫描少量分区;不传则服务会扫描所有分区(冷加载时很慢)。正因如此,这个标志是必填的,切勿省略。时间戳可以是近似值(在 ±24 小时内),如果没有现成的时间戳,也可以找回或估算;请参阅下文的“没有时间戳时”。
时间戳的来源,按优先顺序排列:
- 仪表板 URL:
?t=<iso>参数就是记录的recordedAt;对其进行 URL 解码后原样传入。(会话没有t;请使用会话开始时间、from=,或关联事件的recordedAt。) - 已获取的列表/分组:每个
exceptions show事件都带有recordedAt。记录 ID 时一并记录其recordedAt,然后再深入查询。 - 通知:见下文。
持有 ID 时的查询顺序:先找出其 recordedAt(从 URL、分组或通知中获取),再调用带有该时间戳的按 ID 查询命令。
没有时间戳时
该标志是必填项,因此必须提供一个值,但可以是近似值。查询窗口是你所传入时间戳的前后 ±24 小时(traces show 为 ±48 小时);如果记录不在此窗口内,服务会退回到不设范围的扫描。因此,时间戳只要在实际时间的一天之内,查询就能保持快速;即使估算错误,仍会返回正确记录,只是速度较慢。按以下顺序确定时间戳:
- 从 API 中找回时间戳。 如果你知道某个事件的哈希(例如,粘贴的
/issues/<hash>/<occurrenceId>未带?t=),运行traceway exceptions show <hash>,读取该事件的recordedAt。哈希端点不需要时间戳。通过exceptions list获取的分组firstSeen/lastSeen可界定其事件发生时间(lastSeen≈ 最近一次事件的时间)。 - 根据上下文估算。 通知发送时间、问题的
firstSeen/lastSeen,或 URL 中的preset/from时间范围,都能让估算值落在 ±24 小时内。这足以快速查询。 - 询问用户。 如果没有任何信息能确定时间(例如只有一个事件/端点 ID,没有哈希、时间或可供找回信息的列表),就询问大致发生时间(“大约是什么时候触发的?一天之内即可”),并传入该时间。问题发生已久时,不要随便填“现在”这类占位值;这会使分区裁剪失效,也可能完全超出 ±24 小时的窗口。
解析通知
Traceway 通知(电子邮件 / Slack / webhook)有两种形式。阅读正文以区分:异常通知包含 Hash: 和 Exception ID:;性能通知(延迟、apdex、影响)会标明端点和阈值,且不含哈希。Webhook 载荷还包含一个精确标明规则类型的 ruleType 字段。两种通知的解析方式各不相同。
异常通知
正文中包含直接快速查询所需的所有信息。其中包括:
Hash: <16-hex>— 异常分组 →traceway exceptions show <hash>。Exception ID: <uuid>— 具体事件。Occurred at: 2006-01-02 15:04:05 UTC— 事件时间戳。转换为 RFC3339:将空格替换为T,并将UTC替换为Z(→2006-01-02T15:04:05Z)。View details: <url>— 深层链接;当服务器设置了APP_BASE_URL时,格式为https://<instance>/issues/<hash>,否则为裸路径/issues/<hash>。
因此,收到通知后,直接查询该事件(速度快),然后复用同一时间戳进行后续查询:
traceway exceptions occurrence <Exception ID> --recorded-at <Occurred at → RFC3339> --output json
# the result carries traceId, relatedEntity and sessionId → traces show / endpoints show / sessions show below
性能通知(端点变慢或达到严重级别)
这些通知由延迟/吞吐量规则触发,而非错误。没有哈希值、异常 ID,也没有可供获取的事件。Webhook 中的 ruleType(或主题措辞)会说明通知类型:
| 规则类型 | 主题/正文格式 | 深层链接 |
|---|---|---|
endpoint_p95_threshold / endpoint_p99_threshold | <endpoint> 的 P95 延迟为 1250ms ·“过去 N 分钟内达到 1250ms(阈值:1000ms)” | /endpoints?from=<iso>&to=<iso> |
apdex_drop | Apdex dropped to 0.62 (threshold: 0.80) ·“过去 N 分钟内的 N 个请求中” | /endpoints?from=<iso>&to=<iso> |
impact_score_critical|high|medium | Endpoint <endpoint> impact became critical ·“影响分数:0.82。原因:” | /endpoints?from=<iso>&to=<iso> |
metric_threshold | Metric <name> is <value> (threshold: gt 100) | /metrics?preset=1h |
正文提供的信息:端点名称(从主题/正文中解析;它不是单独的字段)、指标/百分位数、当前值、阈值和回看时间范围。/endpoints?from=&to= 链接仅显示触发时间前后约 3 分钟的窗口,因此应将触发时间视为问题开始时间的提示,而非事件时间范围。
要进行排查,请直接转交给性能流程,并限定到该端点,同时以触发时间作为时间锚点:
# 1. confirm the alert against current stats for that endpoint
traceway endpoints list --search "<endpoint>" --since 1h --output json | jq '.data[0] | {p50_ms: (.p50Duration / 1e6), p95_ms: (.p95Duration / 1e6), p99_ms: (.p99Duration / 1e6), count, impact, impactReason}'
# 2. is this an accepted baseline? check whether an operator marked it slow
traceway endpoints slow "<endpoint>" --output json # {offsetMs, reason}; offsetMs 0 = not marked
# 3. find when it crossed the threshold, then a slow trace (see Flow: Performance)
traceway endpoints chart --metric-type p95 --since 6h --interval-minutes 15 --output json
第 2 步很重要:impact_score_* 或 apdex_drop 告警已考虑偏移,但 endpoint_p95_threshold / endpoint_p99_threshold 会基于原始延迟触发,不受任何慢速标记影响,因此,已被标记为慢速的端点可能会因其运营人员已接受的延迟而触发告警。参见 performance.md 中的“考虑用户标记为慢速的端点”。
流程:登录
1. 检查是否已安装
traceway version
如果显示版本号,请跳过安装,直接进行身份验证。
2. 如果尚未安装,请进行安装
在 POSIX 系统(Linux、macOS)上,使用安装脚本:
curl -fsSL https://cli.tracewayapp.com/install.sh | sh
如果无法使用该脚本,请手动安装:预构建二进制文件位于 tracewayapp/traceway releases page 的 cli/vX.Y.Z 标签下(最新版本可能是 Backend 版本,请筛选 CLI 标签):
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m); [ "$ARCH" = "aarch64" ] && ARCH=arm64
URL=$(curl -s "https://api.github.com/repos/tracewayapp/traceway/releases?per_page=20" \
| grep -o "https://[^\"]*traceway_[^\"]*_${OS}_${ARCH}\.tar\.gz" | head -1)
TMP=$(mktemp -d)
curl -sL "$URL" | tar -xz -C "$TMP"
install -m 755 "$TMP/traceway" ~/.local/bin/traceway && rm -rf "$TMP"
确保 ~/.local/bin 位于 PATH 中(或安装到 /usr/local/bin)。备用方案:从源代码构建(需要 Go):
git clone https://github.com/tracewayapp/traceway && cd traceway/cli
go build -o bin/traceway ./cmd/traceway && install -m 755 bin/traceway ~/.local/bin/traceway
使用 traceway version 验证安装。
3. 身份验证
登录时会以交互方式提示输入密码,因此请让用户自行运行该命令(在 Claude Code 中,建议输入 ! traceway login --url https://<instance>,以便将输出显示在会话中):
traceway login --url https://<traceway-instance>
当密码存储在机密存储中时,可使用非交互式替代方法(切勿将密码回显到命令行或 Shell 历史记录中):
printf '%s' "$TRACEWAY_PASSWORD" | traceway login --url https://<instance> --username [email protected] --password-stdin
多个实例或账号可通过配置文件共存:traceway login --url ... --profile work,然后使用 traceway profiles list / traceway profiles use work。
4. 选择项目并进行冒烟检查
traceway projects list
traceway projects use <project-id>
traceway exceptions list --since 24h
后续所有命令都会隐式使用所选项目。
流程:调试
/traceway debug issue X 或 /traceway debug <free-form bug description>。
1. 解析问题引用
X 可能有多种形式;请将其解析为异常哈希(16 个十六进制字符):
| 引用形式 | 解析方法 |
|---|---|
| Dashboard URL | 请参阅上文的“解析 Dashboard URL”;对于 /issues/... URL,路径中紧跟在 /issues/ 后面的部分就是哈希,?preset/?from/?to 提供时间范围。当 URL 指向某个问题时,请修复该问题最近的一次(LAST)出现记录——见步骤 2。 |
| 独立的 16 位十六进制字符串 | 已经是哈希 |
| 其他任何内容(标题、错误消息、类型、文件名) | 搜索:traceway exceptions list --since 7d --search "<text>";如果没有结果,将范围扩大到 --since 30d(并添加 --include-archived) |
| 没有问题引用,只有 Bug 描述 | 跳到下面的分类处理 |
如果搜索返回多个分组,请列出简要选项(哈希、数量、lastSeen、首条堆栈行),并在深入调查前询问用户要选哪一个。
traceway exceptions list --since 7d --search "checkout" --output json \
| jq '.data[]? | {hash: .exceptionHash, count, lastSeen, top: (.stackTrace | split("\n")[0])}'
2. 深入调查问题
traceway exceptions show <hash> --page-size 5
这是最有价值的调用:它会返回完整堆栈跟踪、出现记录列表(包含 recordedAt、attributes(用户 ID、应用版本、请求上下文)),以及每条记录可选的 traceId / spanId / sessionId。出现记录按时间从新到旧排列,每条记录都带有自己的完整堆栈跟踪,因此默认页面包含 50 条记录,输出会远超 100k 字符,并被任何工具输出限制截断;使用 --page-size 5 可保留分组标题和最新的五条出现记录,这正是首次查看所需的内容。只有在通过 jq 精简 JSON 时,才保留默认页面,示例如下。traceId 是 OpenTelemetry 跟踪 ID(32 个十六进制字符),也是该请求的日志和跨度所带的 ID。响应还包含 relatedEntity:最新一次出现记录所属的端点、任务或 AI 跟踪,以及 endpoints show / tasks show / ai-traces show 所需的 id 和 recordedAt。firstSeen 可用于关联部署:某个分组如果在发布后不久首次出现,通常指向该次发布的差异。无效哈希会以退出码 5 返回 not_found;此时请改用搜索。
当用户提供了问题 URL(或哈希)时,请修复最近一次(LAST)出现记录,而不是“整个分组”。 一个哈希可能包含多个不同的错误:哈希基于去除了消息的规范化堆栈跟踪计算,因此两个无关的故障只要共享顶部的堆栈帧(例如都捕获在同一个中间件/恢复帧),就会合并到同一个分组中。分组中的代表性堆栈跟踪和 firstSeen 可能属于另一个如今已不再出现的错误,而非用户正在查看的错误。请以最新的一次出现记录为准,并修复该特定故障路径:
# The occurrence the user actually wants: the latest one. Pin its exact message + attributes + trace.
traceway exceptions show <hash> --output json \
| jq '.occurrences | sort_by(.recordedAt) | last
| {recordedAt, message: (.stackTrace | split("\n")[0]), attributes, traceId, spanId}'
# Then confirm whether the group is homogeneous or mixed — distinct first lines = distinct bugs:
traceway exceptions show <hash> --output json \
| jq -r '[.occurrences[].stackTrace | split("\n")[0]] | group_by(.)
| map("\(length)x \(.[0])") | .[]'
如果分组中包含多种错误,请仅针对最近一次出现记录的错误进行修复;在报告中提及其他错误簇,但除非用户提出要求,否则不要修复。最近一次出现记录的消息和 attributes(而不是分组的代表性堆栈)决定了需要复现并修复的故障;其 recordedAt 则是下面按 ID 查询 traces show / sessions show 时要传入的时间提示。
3. 分类并关联(也是自由形式错误描述的入口)
从描述中提取症状、受影响的端点/功能和时间范围,然后在形成假设前读取多个信号:
traceway exceptions list --since 24h --order-by lastSeen # what is erroring (firstSeen for regressions, count for volume)
traceway logs query --since 24h --min-severity 17 # errors and worse
traceway logs query --since 24h --search "payment declined" # search log bodies
traceway logs query --since 24h --service checkout-api --min-severity 13
traceway endpoints list --since 24h --search "checkout" # latency p50/p95/p99, count and impact, --order-by impact|count|p95|lastSeen
严重性是 OTel 数值,而非名称:1 TRACE、5 DEBUG、9 INFO、13 WARN、17 ERROR、21 FATAL。标志是 --min-severity 17,绝不能用 --severity error。
按 trace 关联:当某条事件或日志行带有 trace ID 时,获取完整的请求时间线;这通常是找到根因最快的途径:
traceway exceptions show $HASH --output json | jq -r '.occurrences[0].traceId' \
| xargs -I{} traceway logs query --trace-id {} --output json
获取完整的跨服务 trace 和用户会话,并复用该事件的 recordedAt 作为(必需的)时间提示,确保两次查询都限定在分区范围内:
OCC=$(traceway exceptions show $HASH --output json | jq -c '.occurrences[0]')
TS=$(jq -r '.recordedAt' <<<"$OCC")
DT=$(jq -r '.traceId // empty' <<<"$OCC")
SID=$(jq -r '.sessionId // empty' <<<"$OCC")
[ -n "$DT" ] && traceway traces show "$DT" --recorded-at "$TS" # available endpoint/task/ai-trace/exception nodes across services
[ -n "$SID" ] && traceway sessions show "$SID" --started-at "$TS" # the session + the exceptions that fired in it
traces show 会连接跨服务的可用节点。检查每个节点的 spanGraphStatus(表格输出中的 GRAPH 列):时间窗口、保留策略和读取限制可能导致 span 及其相关异常缺失。
检查指标以寻找系统性原因(与 firstSeen 同步出现的峰值表明可能是饱和,而非代码错误):
traceway metrics query --name system.cpu.utilization --tag state=idle --aggregation min --since 24h # busy = 1 - idle
traceway metrics query --name <name> --aggregation avg|sum|count|min|max [--tag key=value] [--group-by <tag>]
CLI 也接受 p50|p95|p99,但服务端没有针对指标点的分位数聚合,会静默地为这些指标计算 avg——绝不能将其作为百分位数呈现。延迟百分位数来自 traceway endpoints list,由原始请求时长计算得出。没有 metrics list;无效名称会正常返回空的 series: {},因此可以安全地探测名称。来自 Traceway OTel Agent 的主机指标使用 system.* 名称,OTLP 直方图指标则存储为两个序列:<name>.avg 和 <name>.count。
4. 与代码关联
- 打开堆栈跟踪中提到的文件和行,并阅读失败路径。
- 如果问题在某个已知时间开始,检查当时发布了什么:
git log --since "<firstSeen>" --until "<firstSeen + 1h>"或部署历史。 - 提出一个假设,能够解释目标事件的全部观测信息(消息、受影响的端点、时间和数量),而不只是第一条堆栈帧。当 URL/哈希将你定位到最近一次事件时(步骤 2),解释该错误;不要勉强用一个假设涵盖仅仅共享该哈希的相邻集群。
- 根据用户的指示提出或实施修复,并将范围限定在目标事件的失败路径内。
5. 证据不足时,添加检测,而不是猜测
编写修复前,先诚实地回答一个问题:遥测数据是否真的解释了这次故障? 当你能指出出错的代码行、到达该行的输入,以及该输入为何有误时,证据才算充分。仅有堆栈跟踪通常不够。数据既无法证实也无法反驳的合理猜测同样不够。
如果无法解释,就不要发布推测性的修复。会改变行为的猜测会掩盖症状、毁掉下一次复现的机会,还会让问题多经历一轮处理。相反,应添加能回答未决问题的检测,让下一次故障自行揭示原因。
选择能弥补具体证据缺口的信号:
| 无法确定的内容 | 要添加的内容 |
|---|---|
| 执行了哪个分支,或输入是什么 | 在决策点记录日志,并将用于决策的值作为属性。失败路径使用 ERROR 严重级别,这样 --min-severity 17 就能找到它 |
| 时间花在哪里,或哪一步失败 | 在每个可疑步骤周围添加子 span,并在请求的活动上下文中开启 |
| 影响了谁或什么(用户、租户、发布版本、负载形态) | 在请求 span 上添加属性,或将属性传给 recordException |
| 发生频率如何,或在什么条件下发生 | 添加计数器或直方图指标,并使用你想按其细分的低基数维度作为标签 |
| 服务边界处的哪个位置发生故障 | 在调用中传播 Trace 上下文,并在边界两侧各添加一个 span 或日志 |
| 代码路径是否实际运行 | 在入口处添加日志或计数器,让数据缺失也能成为证据 |
添加内容时遵循以下规则:
- 在请求或任务的活动 span 内发出信号。这样日志才会带上 Trace ID,并显示在 Trace 中。
- 将标识符放入属性,绝不要写进消息文本。分组前会剥离消息,而属性可用于筛选。
- 控制基数。用户 ID 和请求 ID 应放在 span 属性中,绝不能放在指标标签或 span 名称中。
- 绝不要记录机密、令牌或个人数据。
- 将其作为永久检测发布,而不是临时调试输出。明天就会删除的内容毫无帮助。
- 如果该区域完全没有检测,先使用
traceway-setupskill 进行设置,而不是只补上一行日志。
然后向用户说明后续安排。说明你无法确定什么、添加了什么,以及再次触发时要运行的确切命令:
traceway logs query --trace-id <id> --output json
traceway exceptions show <hash> --output json | jq '.occurrences | last | .attributes'
添加检测是调试会话的合理成果,并不代表修复失败。应将其作为交付内容进行汇报。
6. 汇报并清理
总结症状、证据(异常哈希、日志摘录、指标异常)、根因和修复。附上 traceway exceptions show <hash> 参考命令,方便用户核验。修复部署并验证后,仅在用户提出要求时归档:
traceway exceptions archive <hash> --yes
流程:性能
/traceway perf <endpoint or symptom>,或任何关于缓慢、高延迟、p95/p99 或“为什么 X 很慢”的请求。以资深性能工程师的方式处理:先量化,将成本定位到某个 span,根据检查清单确认原因,区分代码问题与资源饱和,然后确定根因。只读;绝不归档或修改数据。
完整方法以及瓶颈检查清单(Select N+1、缺少索引、过于频繁的 IPC、连接池耗尽、GC 暂停等 20 多项,每项都关联了可确认问题的 Traceway 信号),请阅读此 skill 目录中的 performance.md(通过 MCP 访问:traceway://knowledge/performance 资源)。这是权威参考资料。
使用此 skill 中记录的读取命令,按以下流程处理:
- 量化并定位。 运行
traceway endpoints list --since 24h --order-by p95(或impact)。先查看延迟分布:p50 已经很高,说明每个请求都会受到影响(系统性问题:查询、索引、算法);p99 远高于 p50,说明存在长尾(争用、连接池耗尽、GC、重试、依赖不稳定)。请注意,对于标记为慢的端点,impact/impactReason已按偏移量调整,而原始 p50/p95/p99 未作调整。 - 检查已接受的基线。 在判定端点较慢之前,运行
traceway endpoints slow "<endpoint>"。非零offsetMs表示运维人员接受了相应的延迟(并提供了reason),因此只有超出该偏移量的延迟才是真正的回归;offsetMs 0表示采用默认阈值。只有在明确属于多个端点的系统性变慢时,才跳过此步骤。 - 确定开始时间:缩短时间窗口。 不要直接盲查默认时间窗口;逐步缩小范围,直到窗口涵盖问题开始的时间。
traceway endpoints chart --metric-type p95 --interval-minutes <n>会返回排名靠前端点随时间变化的延迟({timestamp, endpoint, value},单位为 ms):沿着某个端点的时间桶逐个查看,找出 p95 首次跃升的时间桶。时间戳表示时间桶的起始时间,因此问题是在该时间桶内开始的,而不是更早:使用--from/--to仅重查该时间桶,并将间隔设为不超过 15 分钟,然后再报告时间。使用traceway metrics query --name <metric> --interval-minutes <n>(基础设施/运行时曲线)确认原因。对于不在前 5 名中的特定路由,可通过相邻时间窗口,对traceway endpoints list --search <name> --from <a> --to <b>进行二分查找。参见performance.md中的“确定变慢开始的时间”。 - 获取有代表性的慢请求跟踪。 运行
traceway endpoints show <endpointId> --recorded-at <t>查看单个请求的跨度瀑布图,或运行traceway traces show <traceId> --recorded-at <t>(traceId由endpoints show输出)查看跨服务时间线。选择刚刚找到的慢请求时间窗口内的跟踪;找出耗时最长的环节。 - 根据清单分析耗时最长的环节。 占主导地位的跨度是数据库调用、外部调用、进程内计算,还是工作开始前的间隔(排队 / 锁等待 / 连接池耗尽)?在
performance.md中查找对应项。 - 区分代码问题与资源饱和。 拉取同一时间窗口内的基础设施/运行时指标:
traceway metrics query --name system.cpu.utilization --tag state=idle --aggregation min(繁忙程度等于 1 减去空闲程度;该指标按state拆分,因此切勿在未筛选的情况下读取),然后查询system.memory.utilization的state=used,以及运行时的堆和 GC 指标(jvm.*、go.*、v8js.*)。如果指标峰值与延迟开始时间吻合,说明是资源饱和,而不是代码缺陷。 - 与代码和部署记录关联。 根据第 3 步得出的开始时间,检查当时发布的内容:运行
git log --since '<onset - 30m>' --until '<onset + 30m>',或查看部署历史。延迟在发布时跃升,说明存在回归;延迟逐渐上升且没有部署,则可能是数据增长(N+1、缺少索引、没有分页)。 - 报告。 说明瓶颈、证据(端点百分位数、开始时间、占主导地位的跨度、任何相关的指标异常)、对应清单项的根因,以及具体的修复方案;同时提供
endpoints show/traces show的引用,方便用户核实。如果端点已标记为慢,请说明延迟是否超过已接受的偏移量。
如果瀑布图无法定位耗时来源,请先暂停,不要提出修复方案。无法解释的间隔、覆盖整个处理程序的单个超大跨度,或无法复现的长尾,都意味着同一件事:跟踪过于粗略,无法据此采取行动。在该处理程序中,为可疑步骤添加子跨度,然后等待下一个慢请求指出真正的问题所在。参见“调试流程”中的“证据不足时”。
Flow:查询
对于自由形式的请求(“生产环境哪里出问题了?”、“/api/checkout 是否变慢了?”、“显示服务 X 的错误”),直接使用读取命令。若请求明确涉及延迟或变慢,则转到上文的 Performance 流程。
命令参考
| 命令 | 用途 |
|---|---|
traceway projects {list,use} | 列出或选择当前项目 |
traceway exceptions list | 按组列出异常;--search、--search-type text|regex、--order-by lastSeen|firstSeen|count、--include-archived |
traceway exceptions show <hash> | 单个异常组:完整堆栈跟踪 + 发生记录 |
traceway exceptions occurrence <id> --recorded-at <t> | 按 ID 查询单次异常(快速):完整详情 + sessionId + 录制记录 |
traceway logs query | 日志;--search(--search-type body|attribute)、--service、--min-severity <n>、--trace-id |
traceway endpoints list | 各端点的 p50/p95/p99 和计数;--search、--order-by impact|count|p95|lastSeen |
traceway endpoints chart | 热门端点随时间变化的延迟;--metric-type total_time|p50|p95|p99、--interval-minutes。用于查找延迟发生变化的时间 |
traceway endpoints slow <endpoint> | 运维人员是否将此端点标记为慢:{offsetMs, reason}。offsetMs 0 = 未标记。该偏移量是已接受延迟的基线 |
traceway endpoints show <id> --recorded-at <t> | 按 ID 查询单个请求:跨度瀑布图 + 关联错误 |
traceway tasks show <id> --recorded-at <t> | 按 ID 查询单次后台任务运行 |
traceway ai-traces show <id> --recorded-at <t> | 按 ID 查询单条 AI 跟踪记录 + 其对话 |
traceway sessions show <id> --started-at <t> | 按 ID 查询单个会话 + 会话中触发的异常 |
traceway traces show <id> --recorded-at <t> | 分布式跟踪:所有共享该 ID 的服务节点 |
traceway metrics query --name <metric> | 时间序列;--aggregation、--tag、--group-by、--interval-minutes |
traceway pages list / pages show <id> | 值班页面;--status active|open|acknowledged|resolved |
traceway alerts list | 告警规则:类型、是否启用、暂停至何时 |
traceway monitors list / monitors show <id> | 正常运行时间监控、其状态和事件 |
traceway post-mortems list / post-mortems show <id> | 事后分析文档;--search、--tag |
traceway profiles {list,use}、login、logout、version | 配置文件和会话管理 |
按 ID 查询的 show/occurrence 命令需要提供从仪表板 URL、通知或 exceptions show 的异常记录中获取的 ID,并且必须提供记录的时间戳(--recorded-at / --started-at);请参阅上文的“按 ID 快速查询”。
尚未实现(不要编造标志;请引导用户使用 Web UI):tasks / sessions / ai-traces / traces 的 list 动词(这些对象目前仅支持按 ID 使用 show),以及 metrics list/discover。
示例
# What's broken right now
traceway exceptions list --since 1h --order-by lastSeen --page-size 10 --output json \
| jq '.data[]? | {hash: .exceptionHash, count, lastSeen}'
# Did anything NEW break since a deploy at 13:00 UTC
traceway exceptions list --from 2026-06-11T13:00:00Z --to "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--order-by firstSeen --output json \
| jq '.data[]? | select(.firstSeen >= "2026-06-11T13:00:00Z") | {hash: .exceptionHash, firstSeen, count}'
# Worst endpoint by latency
traceway endpoints list --since 1h --order-by p95 --page-size 1 --output json | jq '.data[0]'
# Errors for one service (exceptions --search is free text, not a service filter; use logs)
traceway logs query --service checkout-api --min-severity 17 --since 1h --output json \
| jq '.data[]? | {timestamp, body, traceId}'
空结果(data: null 或 data: [])不代表错误:扩大时间范围,重新检查当前项目(traceway projects list);如果应用从未连接到 Traceway,请先完成设置(traceway-setup 技能)。