From 21057ea11015b00667bbd30a38a0ecdb568d306b Mon Sep 17 00:00:00 2001 From: yeuimu <2197651308@qq.com> Date: Thu, 27 Aug 2026 09:45:28 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20alert=20=E8=A1=A5=E5=85=A8=20flow=20?= =?UTF-8?q?=E5=90=8D;AGENTS.md=20=E8=A1=A5=E5=85=85=20monitor=20=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 9 +++++++++ flows/monitor/alert_failure.py | 15 ++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 934cbcd..7495b5f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -79,6 +79,15 @@ uv run prefect # 运行 prefect CLI > 注:`serve_all.py` 为旧进程式部署,已被 work pool 模型取代,保留仅作参考。 +## 企微机器人告警/上报(monitor) + +- 发送层 `flows/shared/wecom.py`:`send_markdown/send_text`,wecom-aibot-sdk 按需连接(连接→认证→发送→断开),全容错。 + 凭据在 `Secret` Block `wecom-aibot-credentials`(JSON:`bot_id/secret/chat_id`);chat_id 用 `scripts/wecom_capture_chatid.py` 捕获。 +- `flows/monitor/alert_failure.py`(wecom-alert):prefect.yaml 里声明的事件触发器,任意 flow run `Failed/Crashed` 自动运行并发群报警,零代码侵入,新 flow 自动覆盖。 +- `flows/monitor/daily_report.py`(daily-report,18:30):近 7 天 RIIN/SDS 核验(subflow 复用 verify)+商品完整性(`db.get_goods_integrity`)+OCR+失败回顾。 +- `flows/monitor/device_check.py`(device-check,09:00):内存/swap/宿主机磁盘(`/` 挂载在容器 `/host`)/GPU(nvidia-smi)阈值 80% 报警 + Docker 容器异常(docker.sock)+Prefect 失败+OCR/PG 探活。 +- worker 容器已挂载 `/:/host:ro`、`/var/run/docker.sock`、GPU(见 docker-compose.yml),勿移除,否则对应检查降级。 + ## 参考文档 - Prefect 入门:https://docs.prefect.org.cn/v3/get-started diff --git a/flows/monitor/alert_failure.py b/flows/monitor/alert_failure.py index da84ded..86d22ba 100644 --- a/flows/monitor/alert_failure.py +++ b/flows/monitor/alert_failure.py @@ -53,12 +53,21 @@ def _flow_run_id(event: dict) -> str | None: def _fetch_run_detail(run_id: str) -> dict: - """查 Prefect API 补全 flow run 权威信息,失败返回空 dict。""" + """查 Prefect API 补全 flow run 权威信息(含 flow 名),失败返回空 dict。""" api_url = os.environ.get("PREFECT_API_URL", "http://localhost:4200/api") try: resp = httpx.get(f"{api_url}/flow_runs/{run_id}", timeout=10) resp.raise_for_status() - return resp.json() + detail = resp.json() + flow_id = detail.get("flow_id") + if flow_id: + try: + fresp = httpx.get(f"{api_url}/flows/{flow_id}", timeout=10) + fresp.raise_for_status() + detail["_flowName"] = fresp.json().get("name", "") + except Exception: # noqa: BLE001 + detail["_flowName"] = "" + return detail except Exception as err: # noqa: BLE001 print(f"[wecom-alert] 查询 flow run {run_id} 失败: {err}") return {} @@ -86,7 +95,7 @@ def wecom_alert_failure(event: dict | str | None = None) -> dict: flow_name, run_name, state_msg, occurred = "", resource_name, "", ev.get("occurred", "") if run_id: detail = _fetch_run_detail(run_id) - flow_name = detail.get("name", "") or resource_name + flow_name = detail.get("_flowName") or resource_name run_name = detail.get("name", "") state = detail.get("state") or {} state_msg = (state.get("message") or "").strip()