diff --git a/docs/guides/observability_ui_governance.md b/docs/guides/observability_ui_governance.md index c38c559..b9d116d 100644 --- a/docs/guides/observability_ui_governance.md +++ b/docs/guides/observability_ui_governance.md @@ -60,6 +60,14 @@ Guard 會檢查: ### 2. Production 10 頁 HTTP 巡檢 +建議使用 repo 內建腳本: + +```bash +python3 scripts/check_observability_pages.py +``` + +或透過 quick review 選單執行第 7 項。 + ```bash python3 - <<'PY' import urllib.request diff --git a/scripts/check_observability_pages.py b/scripts/check_observability_pages.py new file mode 100644 index 0000000..ff8803a --- /dev/null +++ b/scripts/check_observability_pages.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +"""Production smoke check for AI observability pages. + +The goal is to catch broken observability pages quickly after UI, route, +schema, or deployment changes. It verifies the ten war-room pages return HTTP +200 and do not expose raw framework/database errors to the user. +""" + +from __future__ import annotations + +import argparse +import sys +import urllib.error +import urllib.request + + +PAGES = [ + ("/observability/overview", "總覽"), + ("/observability/agent_orchestration", "Agent"), + ("/observability/business_intel", "商業"), + ("/observability/host_health", "主機"), + ("/observability/ai_calls", "AI 呼叫"), + ("/observability/budget", "預算"), + ("/observability/promotion_review", "晉升"), + ("/observability/rag_queries", "RAG"), + ("/observability/quality_trend", "品質"), + ("/observability/ppt_audit_history", "PPT"), +] + +ERROR_NEEDLES = [ + "Traceback", + "UndefinedError", + "ProgrammingError", + "Internal Server Error", + 'relation "', + "relation "", + "查詢失敗:", +] + + +def fetch_page(base_url: str, path: str, timeout: int) -> tuple[int, str]: + request = urllib.request.Request( + base_url.rstrip("/") + path, + headers={"User-Agent": "momo-observability-smoke/1.0"}, + ) + with urllib.request.urlopen(request, timeout=timeout) as response: + html = response.read().decode("utf-8", "ignore") + return response.status, html + + +def main() -> int: + parser = argparse.ArgumentParser(description="Smoke check AI observability pages") + parser.add_argument("--base-url", default="https://mo.wooo.work") + parser.add_argument("--timeout", type=int, default=12) + args = parser.parse_args() + + failed = False + print(f"Observability page smoke: {args.base_url.rstrip('/')}") + + for path, label in PAGES: + try: + status, html = fetch_page(args.base_url, path, args.timeout) + except urllib.error.HTTPError as exc: + print(f"- {label}: HTTP {exc.code}, FAIL") + failed = True + continue + except Exception as exc: + print(f"- {label}: {type(exc).__name__}: {exc}, FAIL") + failed = True + continue + + found = [needle for needle in ERROR_NEEDLES if needle in html] + if status != 200 or found: + print(f"- {label}: HTTP {status}, issues={found or 'bad_status'}, FAIL") + failed = True + else: + print(f"- {label}: HTTP {status}, issues=none") + + if failed: + print("Observability page smoke: FAIL") + return 1 + + print("Observability page smoke: PASS") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/quick_review.sh b/scripts/quick_review.sh index 26c74e8..cd92244 100755 --- a/scripts/quick_review.sh +++ b/scripts/quick_review.sh @@ -16,6 +16,7 @@ NC='\033[0m' # No Color PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" CODE_REVIEW_SCRIPT="$PROJECT_ROOT/scripts/code_review.py" OBSERVABILITY_UI_GUARD="$PROJECT_ROOT/scripts/check_observability_ui.py" +OBSERVABILITY_PAGE_SMOKE="$PROJECT_ROOT/scripts/check_observability_pages.py" # 顯示標題 echo -e "${BLUE}========================================${NC}" @@ -53,6 +54,16 @@ run_observability_ui_guard() { python3 "$OBSERVABILITY_UI_GUARD" } +run_observability_page_smoke() { + if [ ! -f "$OBSERVABILITY_PAGE_SMOKE" ]; then + echo -e "${RED}❌ AI觀測台頁面巡檢不存在: $OBSERVABILITY_PAGE_SMOKE${NC}" + exit 1 + fi + + echo -e "${GREEN}🌐 開始 AI觀測台 10頁線上巡檢...${NC}" + python3 "$OBSERVABILITY_PAGE_SMOKE" +} + # 顯示選單 if [ $# -eq 0 ]; then echo -e "${YELLOW}請選擇操作:${NC}" @@ -62,8 +73,9 @@ if [ $# -eq 0 ]; then echo "4) 安全檢查 (Security Review)" echo "5) 效能檢查 (Performance Review)" echo "6) AI觀測台 UI/UX 防回歸檢查" + echo "7) AI觀測台 10頁線上巡檢" echo "" - read -p "請輸入選項 (1-6): " choice + read -p "請輸入選項 (1-7): " choice case $choice in 1) @@ -96,6 +108,9 @@ if [ $# -eq 0 ]; then 6) run_observability_ui_guard ;; + 7) + run_observability_page_smoke + ;; *) echo -e "${RED}❌ 無效選項${NC}" exit 1