#!/usr/bin/env python3 # -*- coding: utf-8 -*- """作业 8 · 步骤 4:验收 Prometheus 抓取 + Grafana 大盘。""" from __future__ import annotations import json import os import sys import time import urllib.parse import urllib.request from pathlib import Path import _bootstrap # noqa: F401 import _config as C def _on_207() -> bool: return Path("/opt/workbuddy").is_dir() or os.environ.get("DIFY_API_LOCAL") == "1" def get(url: str) -> str: with urllib.request.urlopen(url, timeout=20) as resp: return resp.read().decode("utf-8", "replace") def prom_query(expr: str) -> float | None: url = "%s/api/v1/query?query=%s" % ( C.HOMEWORK8_PROMETHEUS_URL.rstrip("/"), urllib.parse.quote(expr), ) raw = json.loads(get(url)) res = raw.get("data", {}).get("result", []) if not res: return None return float(res[0]["value"][1]) def accept_local() -> int: time.sleep(18) # 等 Prometheus 至少刮取一轮新 exporter ok_scrape = False for _ in range(18): try: targets = json.loads(get("%s/api/v1/targets" % C.HOMEWORK8_PROMETHEUS_URL)) for t in targets.get("data", {}).get("activeTargets", []): if t.get("labels", {}).get("job") == "ai-platform-sla-exporter": if t.get("health") == "up": ok_scrape = True break except Exception: pass if ok_scrape: break time.sleep(5) if not ok_scrape: print("[WARN] Prometheus 尚未抓到 exporter,继续查 instant query") metrics = { "availability_pct": prom_query("ai_platform_availability_ratio * 100"), "ttft_p99": prom_query("ai_sla_first_token_latency_p99_seconds"), "full_p99": prom_query("ai_sla_full_response_latency_p99_seconds"), "kb_accuracy_pct": prom_query("ai_sla_kb_accuracy_ratio * 100"), "mttr_min": prom_query("ai_sla_mttr_minutes"), } print(json.dumps(metrics, ensure_ascii=False, indent=2)) missing = [k for k, v in metrics.items() if v is None] if missing: print("[FAIL] Prometheus 缺少指标: %s" % ", ".join(missing)) return 1 dash_url = "%s/d/%s" % (C.HOMEWORK8_GRAFANA_URL.rstrip("/"), C.HOMEWORK8_DASHBOARD_UID) try: health = get("%s/api/health" % C.HOMEWORK8_GRAFANA_URL) if "ok" not in health.lower(): print("[FAIL] Grafana health 异常") return 1 except Exception as exc: print("[FAIL] Grafana 不可达: %s" % exc) return 1 print("[PASS] 作业8 SLA 大盘验收") print(" Grafana: %s (admin / %s)" % (dash_url, C.HOMEWORK8_GRAFANA_PASS)) print(" Prometheus: %s" % C.HOMEWORK8_PROMETHEUS_URL) print(" Exporter: %s/metrics" % C.SLA_EXPORTER_BASE) return 0 def main() -> int: if _on_207(): return accept_local() from dify_api import Dify d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD) try: d.login() out, err = d.sh( "/usr/bin/python3 /opt/workbuddy/scripts_cursor/作业8_SLA监控大盘/作业8_04_验收大盘.py" ) print(out or err) return 0 if "[PASS] 作业8 SLA 大盘验收" in (out or "") else 1 finally: d.close() if __name__ == "__main__": sys.exit(main())