06 - 真排障手册
直接 Ctrl+F 搜你看到的真字面 (error code / log 关键词). 5 类紧急情况 + 全 degraded_reason 真表 + 真后端 trace 看法.
紧急程度 4 档
| 档 | 真症状 | 响应时间 | 升级 |
|---|---|---|---|
| 🚨 P0 紧急 | 系统完全死 / 真泄漏发现 / 真安全事件 | < 5 min | 立即 SSH 上去, 见下 §5 类紧急 |
| ⚠ P1 重要 | AI 报告字面错 / 关键 endpoint degraded | < 30 min | 看 backend log + grep degraded_reason |
| 📝 P2 一般 | 某场景偶发 false_positive / UI 体验差 | < 1 day | 收集反馈, 起 phase |
| 💡 P3 改进 | 运维建议加新功能 | 试用结束汇总 | 起 preliminary doc |
5 类紧急情况 (P0)
紧急 1: backend 完全不响应
真症状:
- 浏览器 frontend 转圈不出报告
curl http://127.0.0.1:5000/api/v1/healthz真返000(拒接) 或 hang
30 秒排查:
# 1. 看进程
pgrep -af "backend/app.py" | grep -v "bash -c"
# 0 真返 → backend 死了, 跳到"重启" 段
# 1+ 真返 → backend 在跑但 hang, 看 log
tail -50 workspace/system_monitor/logs/backend-verify.log | grep -E "Traceback|ERROR|Killed|OOM"
重启:
cd /home/kk/code/project/cs-26spring-final-project/workspace/system_monitor
OLD_PID=$(pgrep -f "backend/app.py" | grep -v "bash -c" | head -1)
[ -n "$OLD_PID" ] && kill -9 "$OLD_PID"
sleep 3
# 清 .pyc 缓存 (Phase 69.A 教训 lesson 11)
find backend/ -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null
# 重启
set -a; source .env.local; set +a
nohup ./backend/.venv/bin/python backend/app.py > logs/backend-verify.log 2>&1 &
NEW_PID=$!
sleep 6
# 验
curl -s -o /dev/null -w "HTTP %{http_code}\n" --max-time 5 http://127.0.0.1:5000/api/v1/healthz
# 期望 200 / 401 / 404
真挂仍不起:
| 真因 | 真测 | 修法 |
|---|---|---|
.env.local 缺 MONITOR_AUTH_PASSWORD 或 MONITOR_AUTH_TOKEN_SECRET |
tail logs/backend-verify.log 看 sys.exit(1) 真返 |
补缺的 env, 重启 |
| port 5000 被占 | lsof -i:5000 看哪个 pid 占 |
kill <pid> 或换 port |
| 文件权限错 | ls -la backend/app.py 看 owner / +x |
chown / chmod +x |
| venv 损坏 | backend/.venv/bin/python --version 真返 ImportError |
重建 venv (见 04-deployment.md §步骤 1) |
| Python 真 exception (代码 bug) | tail -100 logs/backend-verify.log | grep -A 20 "Traceback" |
真 bug 不在 SOP 范围, 起 hotfix phase |
紧急 2: ES 连不上 (degraded 大面积)
真症状:
- 所有 endpoint 真返
degraded_reason="es_query_failed"或"data_source_unavailable" - 报告里全是 fallback 数据
30 秒排查:
# 1. ES 真活吗?
curl -s --max-time 5 http://10.10.1.147:9200/_cluster/health
# 期望: {"status":"green"} 或 yellow
# 2. VPN 真通吗? (跨网段时)
ping -c 3 10.10.1.147
# 0 包 = 网络断
真因 + 修法:
| 真因 | 修法 |
|---|---|
| VPN 真断 | 重连 vpn.gbu.edu.cn SSL VPN |
| ES 真挂 | 不在你管, 找 ES 管理员; 等 ES 恢复, backend 自动恢复 (无需重启) |
| ES timeout (24h 大聚合 > 60s) | 改 .env.local OPENCLAW_ES_TIMEOUT_SECONDS=120 重启 backend |
ES index 真删 (dns-dnstap-*) |
找 ES 管理员恢复; backend fallback 到 open_dataset 2012 样本继续给报告但显红色 banner |
紧急 3: LLM 全挂 (本地 + DeepSeek 都不可达)
真症状:
- 所有 endpoint 真返
ai_reasoning.available=false,fallback_reason="model_unavailable" - 仍出报告但全是 deterministic 文字 (没有 LLM 自然语言解释)
30 秒排查:
# 1. 本地 LLM 真活吗?
curl -s --max-time 5 "$OPENCLAW_LOCAL_URL" -X POST \
-H "Content-Type: application/json" \
-d '{"model":"...","messages":[{"role":"user","content":"hi"}]}'
# 2. DeepSeek 真活吗?
curl -s --max-time 10 https://api.deepseek.com/chat/completions \
-H "Authorization: Bearer $OPENCLAW_DEEPSEEK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"hi"}]}'
真因 + 修法:
| 真因 | 修法 |
|---|---|
| 本地 LLM 真挂 (机器 down / process 死) | 找本地 LLM 部署管理员; backend 会自动 fallback 到 DeepSeek (无需手动) |
| DeepSeek API key 真失效 / 过期 | 改 .env.local OPENCLAW_DEEPSEEK_API_KEY=<新 key> 重启 backend |
| DeepSeek 真欠费 (HTTP 402) | 充值 |
DeepSeek model 名错 (用了 deepseek-chat) |
改 OPENCLAW_DEEPSEEK_MODEL=deepseek-v4-flash 重启 |
| 出公网真断 (校园网防火墙 block 443) | 找网络管理员开 api.deepseek.com:443 ACL |
| 全断 (本地 + 云端都死) | 本系统 degrade 到只出 deterministic 文字, 仍可用. 告诉运维"AI 段降级, 数据仍可信". 不阻塞 |
紧急 4: 真生产数据真泄漏 (P0 安全)
真症状:
- 任何 frontend / fixture / git history 出现真域名 (e.g.
deepinstinctweb) - 真 MAC (不是
02:00:00:*占位) - 真 API key
真立即响应 (30 分钟内):
# 1. 截图 / 保留证据
# 2. 立即不再 push / commit
# 3. 看真泄漏范围
grep -rE "deepinstinctweb|sk-[a-zA-Z0-9]{20,}" \
workspace/system_monitor/test_backup/ \
docs/agent-handoff/ \
workspace/system_monitor/logs/
# 4. 看 git history
git log --all -p 2>&1 | grep -c "<真泄漏字面>"
# 5. 若 > 0, filter-repo 洗 (Phase 68.E + R31 同款 SOP):
cat > /tmp/replacements.txt <<'EOF'
<真泄漏字面>==>anon-redacted-XXX.example.invalid
EOF
git filter-repo --replace-text /tmp/replacements.txt --force
# 6. 验
git log --all -p 2>&1 | grep -c "<真泄漏字面>"
# 期望: 0
# 7. force push 覆盖远程
git push --force-with-lease origin <branch>
# 8. 起 phase 修脱敏源头 (类比 Phase 68.E sanitize_fixture.py _HOSTNAME_RE)
详见 feedback_bitter_lessons_r10_r37.md lesson 10.
紧急 5: 真发现 AI 给的建议含"执行性动作" (违 preview_only)
真症状:
- 运维截图发现 AI 建议里写"删除 X 配置" / “重启 nginx” / “drop ACL rule”
- 这违反
preview_only=true设计契约
真立即响应:
# 1. 截图保留
# 2. 看哪个 endpoint 真返的
grep -rE "rm -rf|systemctl restart|drop|delete from" workspace/system_monitor/backend/assistant/ | head -10
# 3. 找到真生成这文本的位置
# 通常是 recommended_actions builder 或 LLM prompt 模板
# Phase 64.F 起严守"建议动作必须可执行但不真执行"
# 4. 立即 patch (改 LLM prompt 或 invariant 拦字面)
# 这是 P0 必修, 不可留账
# 起 phase70.X coding agent prompt (类比 Phase 68.E)
degraded_reason 全表 (运维高频遇到)
degraded_reason 真字面 |
含义 | 真在哪触发 | 怎么排 |
|---|---|---|---|
es_query_failed |
ES query timeout / 5xx / 连不上 | 任何 endpoint 跑 ES tool 失败 | 见紧急 2 |
deterministic_seed_rejected |
tool_plan_validator 真拒 round 1 plan | multiround agent round 1 出口 | 看 rejected_tools[*].reason. Phase 68.C 已修主真因 (_context_window 不识别 incident_window). 复发可能是新字段约定 |
tool_validator_rejected |
同上但 round 2+ LLM 给的 plan 真拒 | multiround agent round 2+ | LLM 真给了非白名单工具, 看 rejected_tools |
no_root_cause_ranked |
hypothesis builder 真返空 hypotheses | report_status_invariants 出口 | 数据不足, 不是 bug. 看 findings 真值是否合理 |
tool_budget_exhausted |
跑了 max_tools (默认 8) 没结论 | multiround agent | 真复杂 case, 加 max_tools=12 真请求或起 phase 改默认 |
data_source_unavailable |
ES 连 health check 都失败 | live_query_guard 早返 | ES 真挂 / VPN 断 |
model_unavailable |
LLM 主+fallback 都挂 | llm_client.call_reasoning_model_with_fallback | 见紧急 3 |
no_hypotheses_to_validate |
(✅ 合法) hypothesis builder 真返空 (数据正常) | A endpoint 默认行为 | 不是 error |
disabled_by_config |
reasoner 被 env 禁 | reasoner 装载点 | 看 OPENCLAW_REASONING_PRIMARY 是否真设 |
deterministic_meta_reasoning_only |
(✅ 合法) A endpoint 设计不调 LLM | A endpoint 默认 | 不是 error |
needs_user_clarification |
clue 路径 LLM 抽不到时间窗或真凶域名 | clue_parser_v2 | 让运维补线索, 不是 bug. 反复触发说明关键词集需扩 (Phase 69.A 教训) |
time_window_too_large |
clue 窗口超 LIVE_MAX_WINDOW | live_query_guard | Phase 69.C 升 24h, Phase 69.D 升 168h hard cap. 仍超 = 真问 > 7 天大窗口需 phase70.X 优化 |
Backend log 真常见关键词
tail -f workspace/system_monitor/logs/backend-verify.log 看:
| 真字面 | 真含义 | 严重度 |
|---|---|---|
[p68a] reasoner.input ... 字段缺失 |
Phase 68.A 真凶可见 (装配链断 None 字段, 没被 silent 0 吞) | 📝 P2 留观察 |
[p67a3] asset_lookup_fallback_exhausted |
resolver_ip 在 asset_registry 3 tier fallback 全 miss | 📝 P2 (业务影响段可能空) |
[p67a4] round_n_plan_validator_rescue |
LLM plan 真被拒, deterministic rescue 救活 | 📝 P2 (说明 LLM 输出真不稳, 但被救) |
[p64c] mutex_violation: status=degraded but recommended_actions_status=actionable |
invariant 真守, 降级 actionable → awaiting_evidence | 📝 P2 不算 error |
[p66d] headline_overclaim_when_cannot_rank |
invariant 真守, headline 真降级 | 📝 P2 不算 error |
[p66d3] headline_rewrite_after_final_rank |
final rank 后真覆写 headline | 📝 P2 不算 error |
[p66d2] args_domain_phantom_propagated |
LLM 真凭空写了 phantom domain (Phase 66.D2 真守) | ⚠ P1 (LLM 真出错但被拦) |
Traceback (most recent call last) |
Python 真 exception | 🚨 P0 必看 |
reasoning model fallback: ... trying deepseek-cloud |
本地 LLM 真挂 fallback 真触发 | 📝 P2 (双源工作正常) |
OPENCLAW_DEEPSEEK_URL ... 401 Unauthorized |
DeepSeek key 真失效 | ⚠ P1 (双源 fallback 死了) |
ERROR: Connection refused: 10.10.1.147:9200 |
ES 真挂 / 网络断 | 🚨 P0 见紧急 2 |
sys.exit(1) |
backend 启动时 env 真缺 | 🚨 P0 见紧急 1 |
真后端 tool_trace 看法
任何 endpoint 真返 JSON 内含 tool_trace[]. 真值字段:
{
"tool": "query_dns_failure_summary",
"args": {"start": "...", "end": "...", "resolver_ip": "..."},
"args_summary": {...}, // sanitize 后的 args (脱敏)
"status": "ok|failed|skipped",
"failure_reason": "", // failed 时真因
"result_summary": {...}, // tool 真返
"execution_enabled": false, // 安全旗
"preview_only": true,
"raw_log_scan": false
}
排障时看:
| 看 | 找啥 |
|---|---|
status="failed" 真因 |
failure_reason 字面 (es_query_timeout / validator_rejected: missing X / 等) |
status="skipped" 真因 |
details.reason 字面 (Phase 64.F 真新增 enum) |
args vs args_summary 差异 |
看是否 silent fallback 字段为空 |
result_summary 真值 |
看跟 LLM 自然语言矛盾不矛盾 |
frontend 排障 (vite HMR 真不工作时)
# 1. 看 frontend dev server 在不在跑
pgrep -af "vite" | grep -v "bash -c"
# 2. 浏览器侧 F12 → Network tab → 看是否 fetch 到 :5000 真返
# 看 axios 真请求 url + response status / body
# 3. 浏览器侧 Ctrl+Shift+R 强刷 (清 vite HMR 缓存)
# 4. frontend dev 真挂重起
cd workspace/system_monitor/frontend
pkill -f "vite"
sleep 2
nohup npm run dev > ../logs/frontend-dev.log 2>&1 &
sleep 5
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:3002
真复现某个 bug 的 SOP
# 1. 收集真复现条件
# - 真用户操作 (哪个 endpoint, 什么 payload)
# - 真返 JSON (frontend network tab 拷)
# - 真 backend log tail 200 行
# 2. 真复现真 capture
cd workspace/system_monitor
./scripts/run_round_evaluation.sh r-debug-<descriptor>
# 6 步 pipeline 真跑, fixture 入 staging
# 3. 真后端 fixture 真 grep 找真凶字面
grep -rnE "<真凶关键字>" test_backup/fixtures_real_backend/r-debug-<X>_*.json | head
# 4. 真在源码定位
grep -rnE "<同款关键字>" backend/assistant/ | head
# 看哪个 .py 真生成这个字面
# 5. 起 source-fix phase prompt (类比 Phase 68.A-F)
# 走 plugin v0.1.2 phase-prompt-guard 5 检查
真返时间真异常 (慢)
| 真症状 | 真因 | 真修 |
|---|---|---|
| Endpoint A > 30s (期望 3-5s) | LLM reasoner 真慢 (云端) | 改 OPENCLAW_REASONER_TIMEOUT_SECONDS=30 |
| Endpoint B > 180s | 多 round LLM × 多 ES, 真累积慢 | 看 tool_trace 哪段最慢; 真复杂 case 自然慢 |
| Endpoint C > 60s | DHCP 5 工具其中 1-2 真 ES timeout | 看 tool_trace status=failed; 增 ES timeout |
| Clue 路径 > 180s | 24h 大窗口聚合慢 | 真问 > 7 天 = 已知 168h hard cap 性能未真验, 起 phase70.X 优化 |
| 任何 endpoint > 300s | 真有 hang (LLM 不返 / ES 不返) | 重启 backend 排 hang |
升级到下一阶段时 (生产部署)
涉及 systemd / nginx / gunicorn / PostgreSQL 等. 详见 04-deployment.md §生产部署.
排障时找 systemd / nginx / PostgreSQL 各自 SRE 文档, 本 doc 不展开.
下一步: 07-extension-guide.md (加新功能怎么做)