docs: record hwlab opencode otel triage
This commit is contained in:
@@ -84,6 +84,38 @@ OTel trace 内常见业务关联属性:
|
||||
- `sessionId` / `turnId` / `threadId`: HWLAB/AgentRun 会话与 turn 关联
|
||||
- `failureKind` / `willRetry` / `terminalStatus`: 错误与终态判断
|
||||
|
||||
## HWLAB OpenCode /global/event 排障
|
||||
|
||||
OpenCode 对话长时间显示 `Thinking`、用户发消息后无 assistant 文本、或怀疑 iframe/live state 没吃到事件时,先分别证明 provider、Cloud Web 代理和浏览器事件流三层状态。provider span 可能已经 200,但 UI 仍可能因 `/global/event` 目录、ticket 或 live state 不一致而不收敛。
|
||||
|
||||
优先用明确 service 的 TraceQL 查询 provider,避免普通 grep 漏掉新 span 名或属性:
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts platform-infra observability search \
|
||||
--target <node> \
|
||||
--query '{ resource.service.name = "opencode-provider-proxy" }' \
|
||||
--lookback-minutes 30 \
|
||||
--candidate-limit 100 \
|
||||
--limit 20
|
||||
```
|
||||
|
||||
provider 侧至少看 `/v1/chat/completions` 的 HTTP status、duration、`opencode.provider.sse.content_chunks`、`opencode.provider.sse.content_chars`、`opencode.provider.sse.reasoning_only_choices_dropped`、output data lines、done lines 和 JSON error 数。只有这些正常,才能把焦点转到 Cloud Web 代理或 UI。
|
||||
|
||||
Cloud Web 侧查 `/global/event` 长连接的 start span;长连接可能在调查窗口内不关闭,所以必须依赖 stream start 可见性,而不是只等 completion span:
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts platform-infra observability search \
|
||||
--target <node> \
|
||||
--query '{ resource.service.name = "hwlab-cloud-web" && span.http.route = "/global/event" }' \
|
||||
--lookback-minutes 30 \
|
||||
--candidate-limit 300 \
|
||||
--limit 20
|
||||
```
|
||||
|
||||
期望看到 `opencode.proxy.stream.start`,并检查 `opencode.proxy.sse.directory_rewrite_enabled`、`opencode.proxy.sse.directory_rewrite_from`、`opencode.proxy.sse.directory_rewrite_to`、`opencode.proxy.ticket_accepted`、`span.http.route=/global/event` 和 streaming 标记。`from=/workspace`、`to=/` 代表 HWLAB iframe/public route 与 OpenCode server workspace route 已对齐;如果该 rewrite 不存在或 ticket 未接受,provider 正常也不能说明 UI 正常。
|
||||
|
||||
关闭 OpenCode UI 卡住类 issue 时,OTel 只能证明链路状态;最终还要用 web-probe DOM/事件证据确认浏览器看到 assistant 文本、没有残留 `Thinking`,并且 EventSource 收到 `message.part.updated`、`step-finish`、`session.idle` 等事件。若 `--grep` 没搜到新属性或 span 名,改用上述 TraceQL query,再只对小范围 trace 使用 `trace --raw` 做 bounded attr drill-down。
|
||||
|
||||
## Code Agent / AgentRun 排障
|
||||
|
||||
追 `Code Agent 代理暂时无法连接上游`、`provider-stream-disconnected`、Workbench 加载/转圈、turn idle 报错、AgentRun command terminal 状态时:
|
||||
|
||||
@@ -170,6 +170,7 @@ MDTODO 或 Project Management 的 Web 重写/布局 closeout 不能只引用组
|
||||
- issue closeout 优先引用 `web-probe script` 输出的顶层 `issueEvidence` 或 `summary.issueEvidence`;只有需要展开调查时才粘贴 `probe.script.result`、`probe.steps` 或完整 `reportPath`,避免 stdout、summary 和 report 多层重复同一证据。
|
||||
- stdin heredoc 与 `--script-file` 都按 ES module 加载,脚本必须导出 `export default async ({ page, gotoStable, recordStep, ... }) => { ... }`;不要在模块顶层直接写 `return`。失败为 `Illegal return statement`、`does not provide an export named default` 或 finalUrl 仍是 `about:blank` 且 stepCount=0 时,先按 probe 脚本入口误用处理,不要归因成 Cloud Web 行为失败。
|
||||
- 自定义脚本需要主动失败时,优先返回 `{ ok: false, failedCondition: "..." }` 或抛出错误;兼容返回 `{ pass: false }`、`{ success: false }`,且 `{ ok: true, pass: false }` 仍按失败处理。`failedCondition`、`errorMessage`、`message`、`error`、`reason` 或 `summary` 会进入失败摘要;不要只把失败埋在普通业务字段里。
|
||||
- OpenCode iframe 或 direct-host smoke 必须等到 OpenCode frame/direct origin 可用后再操作 composer;填入 prompt 后优先点击可见的 `[data-action='prompt-submit']`,不要把 Enter-only 当成稳定提交路径。关闭 OpenCode 对话类 issue 时,`web-probe script` 顶层 `ok` 不能只是“脚本没抛错”;必须断言 DOM body 出现最终 assistant 文本、没有残留 `Thinking`,并记录 EventSource 或等价事件探针看到 `message.part.updated`、`step-finish`、`session.idle`。手工 EventSource 探针可以证明 `/global/event` 消息到达,但不能替代 UI DOM 终态证据。
|
||||
- web-probe 由 UniDesk CLI 从 YAML 声明的 bootstrap admin sourceRef 读取凭据并建立同源 `hwlab_session`;脚本不得自行读取、打印或复制 Web 登录凭据、cookie、token 或完整 API key。
|
||||
- 需要禁用 `EventSource`、mock `Date`/clock、注入 preload hook 或修改浏览器启动前全局对象时,`page.addInitScript()` 必须在目标页面整页加载前注册,并用 `page.goto(new URL(path, origin).toString(), { waitUntil: "domcontentloaded" })` 进入目标 deep link;不要依赖 `gotoStable()` 复用当前 SPA 页面后再期待 init script 生效。若只在已加载页面上 route/block 请求,既有 SSE 或 store 状态可能继续更新,不能作为“无后端刷新依赖”的验收。
|
||||
- 脚本构造 URL 时使用 `new URL(path, baseUrl).toString()`;不要拼出 `//v1/...`。
|
||||
|
||||
@@ -119,6 +119,8 @@ HWLAB 接入 OpenCode 时,默认采用独立 `opencode-server` Pod 和独立 p
|
||||
|
||||
OpenCode provider/model、public hostname、SecretRef 和 extra FRP proxy 都必须从 issue/CLI 选中的 node/lane YAML 与目标 HWLAB repo render 读取;长期参考不硬编码当前模型或端口。关闭 OpenCode 集成、provider profile 或微前端入口类 issue 时,最小证据应来自选中 node/lane 的 `web-probe script`:登录 HWLAB public origin,打开 `/opencode`,确认 iframe origin、OpenCode `/global/health`、`/config` 中的 provider/model、`/session` 创建,以及 `/session/:id/message` 返回的 providerID、modelID、terminal finish 和最终 assistant text。只看到 `opencode-server` Pod ready、Caddy hostname 200 或 Secret 存在,不能替代这个浏览器入口 smoke。
|
||||
|
||||
排查 OpenCode 对话长时间停在 `Thinking` 或无 assistant 文本时,先拆分 provider 完成、Cloud Web 代理长连接和 UI live state 三层事实。provider 侧必须按 `opencode-provider-proxy` service 明确查 OTel,确认 `/v1/chat/completions` 状态、耗时、content chunk、reasoning-only drop 和 done line;Cloud Web 侧必须能看到 `/global/event` 的 `opencode.proxy.stream.start` span,以及 `opencode.proxy.sse.directory_rewrite_enabled`、`from=/workspace`、`to=/`、`ticket_accepted=true` 等属性。关闭证据必须包含浏览器 DOM 最终 assistant 文本、没有残留 `Thinking`,以及 EventSource 收到 `message.part.updated`、`step-finish`、`session.idle` 等事件;provider 200 或 `/session/:id/message` 返回 terminal 不能单独证明 UI 已收敛。OpenCode composer smoke 应优先点击可见的 `[data-action='prompt-submit']` 提交按钮;只依赖 Enter 在 contenteditable 状态下不稳定。
|
||||
|
||||
## HWLAB FRP 维护
|
||||
|
||||
HWLAB 公网 FRP server 由 master server 上的 `hwlab-frps-dev` 容器承担,容器使用 host network,并把 `/opt/hwlab-frp/frps.dev.toml` 只读挂载到 `/etc/frp/frps.toml`。这个 server 侧 allowlist 是 UniDesk 指挥侧维护对象,不属于 G14 k3s GitOps desired state;G14 侧 `frpc` ConfigMap/Deployment 只负责各 runtime namespace 的客户端 tunnel。
|
||||
|
||||
Reference in New Issue
Block a user