fix(api): 將主機資源告警收斂成脫敏事件卡
Some checks failed
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / tests (push) Successful in 1m48s
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
Your Name
2026-06-18 15:22:11 +08:00
parent dafe534259
commit 5d76ac1145
5 changed files with 216 additions and 29 deletions

View File

@@ -69,11 +69,12 @@ root 364 181 0.7 3491396 494608 ? Rl 05:56 0:18 /opt/hostedto
result = format_host_resource_alert_card(raw_alert)
assert "主機資源告警h110-gitea" in result
assert "P1 主機資源壓力h110-gitea" in result
assert "ai_automation_alert_card_v1" in result
assert "影響判讀" in result
assert "一眼摘要" in result
assert "CPU 使用率" in result
assert "Load" in result
assert "容器 root 進程" in result
assert "AI 自動化判讀" in result
assert "runner_build_resource_pressure" in result
assert "candidate_only" in result
@@ -101,7 +102,7 @@ def test_orphan_browser_alert_becomes_runaway_process_event_packet() -> None:
result = format_host_resource_alert_card(raw_alert)
assert "主機資源告警110" in result
assert "P3 主機資源壓力110" in result
assert "ai_automation_alert_card_v1" in result
assert "orphan_browser_smoke_runaway_process" in result
assert "HostOrphanBrowserSmokeHighCpu" in result
@@ -124,7 +125,7 @@ def test_ci_runner_load_alert_becomes_capacity_event_packet() -> None:
result = format_host_resource_alert_card(raw_alert)
assert "主機資源告警110" in result
assert "P3 主機資源壓力110" in result
assert "ci_runner_load_saturation" in result
assert "CI load evidence packet" in result
assert "Gitea Actions run" in result
@@ -166,6 +167,89 @@ async def test_send_alert_notification_normalizes_host_resource_raw_dump(monkeyp
assert "/workspace/wooo/" not in payload["text"]
def test_prisma_generate_alert_redacts_raw_process_json_and_urls() -> None:
"""Prisma generate 類 root Node.js 告警不得把路徑、URL 或 JSON 直接送出。"""
raw_alert = """WARN h110-gitea 🔴 CPU 警告: used=29.8% load=8.62
WARN h110-gitea ⚠️ 容器內 root Node.js 進程:
root 365 27.5 0.1 1283324 108564 ? Sl 06:27 0:00 node /opt/hostedtoolcache/node/20.20.2/x64/bin/pnpm prisma generate
root 376 15.5 0.3 11756860 217220 ? Rl 06:27 0:03 node ./node_modules/.bin/../prisma/build/index.js generate
root 392 0.0 0.0 1096836 53400 ? Ssl 06:27 0:00 /opt/hostedtoolcache/node/20.20.2/x64/bin/node /workspace/wooo/vibework/node_modules/.pnpm/prisma@7.8.0_types+react@18.3.30_react@18.3.30/node_modules/prisma/build/index.js {"product":"prisma","version":"7.8.0","endpoint":"https://checkpoint.prisma.io","command":"generate"}
"""
result = format_host_resource_alert_card(raw_alert)
assert "P1 主機資源壓力h110-gitea" in result
assert "runner_prisma_generate_resource_pressure" in result
assert "Prisma generate" in result
assert "容器 root 進程:<code>3</code>" in result
assert "套件來源" in result
assert "runtime_write_gate=0" in result
assert "root 365" not in result
assert "checkpoint.prisma.io" not in result
assert "node_modules" not in result
assert "/opt/hostedtoolcache" not in result
assert "/workspace/wooo" not in result
assert '"product":"prisma"' not in result
@pytest.mark.asyncio
async def test_send_alert_notification_forces_html_card_for_markdown_host_alert(monkeypatch) -> None:
"""即使呼叫端用 Markdownhost raw dump 仍必須被最後出口改成 HTML 卡。"""
sent_requests = []
gateway = TelegramGateway()
async def fake_send_request(method, payload):
sent_requests.append((method, payload))
return {"ok": True}
monkeypatch.setattr(TelegramGateway, "alert_chat_id", property(lambda _self: "chat"))
monkeypatch.setattr(gateway, "_send_request", fake_send_request)
await gateway.send_alert_notification(
text=(
"WARN h110-gitea 🔴 CPU 警告: used=29.8% load=8.62\n"
"root 365 27.5 0.1 1283324 108564 ? Sl 06:27 0:00 "
"node /opt/hostedtoolcache/node/20.20.2/x64/bin/pnpm prisma generate"
),
parse_mode="MarkdownV2",
)
payload = sent_requests[0][1]
assert payload["parse_mode"] == "HTML"
assert "ai_automation_alert_card_v1" in payload["text"]
assert "runner_prisma_generate_resource_pressure" in payload["text"]
assert "/opt/hostedtoolcache" not in payload["text"]
@pytest.mark.asyncio
async def test_send_text_normalizes_host_resource_alert(monkeypatch) -> None:
"""send_text 旁路也不能把 host resource raw dump 直接送出。"""
sent_requests = []
gateway = TelegramGateway()
async def fake_send_request(method, payload):
sent_requests.append((method, payload))
return {"ok": True}
monkeypatch.setattr(TelegramGateway, "alert_chat_id", property(lambda _self: "chat"))
monkeypatch.setattr(gateway, "_send_request", fake_send_request)
await gateway.send_text(
text=(
"WARN h110-gitea 🔴 CPU 警告: used=29.8% load=8.62\n"
"root 365 27.5 0.1 1283324 108564 ? Sl 06:27 0:00 "
"node /workspace/wooo/vibework/node_modules/.bin/prisma generate"
),
)
payload = sent_requests[0][1]
assert payload["parse_mode"] == "HTML"
assert "P1 主機資源壓力" in payload["text"]
assert "node_modules" not in payload["text"]
assert "/workspace/wooo" not in payload["text"]
def test_weekly_report_marks_all_zero_as_low_trust_anomaly() -> None:
report = WeeklyReportMessage(
week_range="2026-W24",