統帥要求: 1. 所有 6 個觀測頁的功能和數據都要完整寫入資料庫儲存 2. Ollama 切 GCP 順序 GCP-A → GCP-B → 111 盤點結果: - 4/6 頁面已有 DB 表(ai_calls / learning_episodes / rag_query_log / ai_call_budgets) - 2/6 頁面是即時查詢無歷史:host_health(HTTP probe)、ppt_audit(os.listdir) - Ollama 99% 已合規,僅 1 處過時註解 修補(B-1): - services/code_review_pipeline_service.py:207 註解更新 「直呼內網 Ollama (192.168.0.188)」→ 「走 resolve_ollama_host 三主機級聯 ADR-027」 新增(B-2): - migrations/029_create_host_health_probes.sql - 三主機健康歷史表(label/url/healthy/response_ms/error_msg) - 索引:probed_at / (host_label, probed_at) - 30 天保留(cron 清理) - migrations/030_create_ppt_audit_results.sql - PPT 視覺審核結果表(status/issues_count/issues_found JSONB/confidence) - 索引:audited_at / pptx_filename / failed-only partial - routes/admin_observability_routes.py:host_health_dashboard - 每次 probe 寫入 host_health_probes(失敗安全) - 新增 24h 健康趨勢卡片(uptime % / 平均 ms) - routes/admin_observability_routes.py:ppt_audit_history - 從 ppt_audit_results 讀過去 7 日 audit 紀錄 - 顯示審核時間/檔名/結果/問題數/信心度/耗時 - services/ppt_vision_service.py:check_ppt_file - 新增 _persist_audit_result() 跑完寫入 DB(status/issues/confidence/duration) - 失敗安全:DB 寫入失敗只 log warning,不擋主流程 - templates/admin/host_health.html + ppt_audit_history.html - 新增「24h 健康趨勢」card(host_health) - 新增「視覺審核歷史紀錄」card(ppt_audit) DoD: - 程式碼語法 ✓ - Jinja 平衡 ✓ - 失敗安全(DB 寫入或讀取失敗都不擋頁面渲染)✓ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
49 lines
2.4 KiB
SQL
49 lines
2.4 KiB
SQL
-- =============================================================================
|
||
-- Migration 029: host_health_probes — 三主機健康歷史
|
||
-- Operation Ollama-First v5.0 — Phase 38
|
||
-- 日期: 2026-05-04 台北
|
||
-- 對應頁面: /observability/host_health
|
||
-- =============================================================================
|
||
-- 說明:
|
||
-- 原本 host_health 頁面每次刷新都即時 HTTP probe 三主機 /api/tags,
|
||
-- 無歷史 → 無法看趨勢、無法回查「昨天 GCP 是不是有掛過」。
|
||
-- 本 migration 加表,每次 probe 寫一筆,留 30 天歷史(cron 清理)。
|
||
--
|
||
-- 寫入點:
|
||
-- 1. routes/admin_observability_routes.py::host_health_dashboard 每次 render 寫
|
||
-- 2. scheduler.py 加每 5 分鐘 background probe(即使無人開頁也記錄)
|
||
--
|
||
-- 索引設計:
|
||
-- - (probed_at DESC) 給最新 N 筆查詢
|
||
-- - (host_label, probed_at DESC) 給「某台主機過去 24h 趨勢」
|
||
-- =============================================================================
|
||
|
||
CREATE TABLE IF NOT EXISTS host_health_probes (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
probed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
host_label VARCHAR(64) NOT NULL, -- 'Primary (GCP)' / 'Secondary (GCP)' / 'Fallback (111)'
|
||
host_url VARCHAR(256) NOT NULL, -- http://34.143.170.20:11434 等
|
||
healthy BOOLEAN NOT NULL,
|
||
unhealthy_mark BOOLEAN NOT NULL DEFAULT FALSE, -- 對應 _is_unhealthy(host)
|
||
models_count INTEGER DEFAULT 0, -- 載入模型數
|
||
response_ms INTEGER, -- HTTP probe 耗時(ms)
|
||
error_msg TEXT, -- 失敗時的 exception 文字(截 500 字)
|
||
|
||
CONSTRAINT chk_host_label_029
|
||
CHECK (host_label IN ('Primary (GCP)', 'Secondary (GCP)', 'Fallback (111)'))
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_host_health_probes_at
|
||
ON host_health_probes (probed_at DESC);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_host_health_probes_label_at
|
||
ON host_health_probes (host_label, probed_at DESC);
|
||
|
||
-- 清理舊資料(保留 30 天)— 由 scheduler 每日 03:00 跑:
|
||
-- DELETE FROM host_health_probes WHERE probed_at < NOW() - INTERVAL '30 days';
|
||
|
||
COMMENT ON TABLE host_health_probes IS
|
||
'三主機 Ollama 健康歷史;每次 host_health 頁面 render 或 scheduler 5min cron 寫入';
|
||
COMMENT ON COLUMN host_health_probes.host_label IS
|
||
'services/ollama_service.py::get_host_label() 對應標籤';
|