Files
ewoooc/scripts/check_observability_pages.py
OoO b963dcf209
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
test(observability): add production page smoke check
2026-05-05 15:35:47 +08:00

89 lines
2.6 KiB
Python

#!/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())