在 Day 26 完成 Prometheus 指標採集與 Grafana 視覺化監控儀表板 後,PrescriptionVLM 系統已具備健康數據可視化能力。
然而,運營團隊無法 24 小時盯著 Grafana 儀表板。當系統突發 5xx 伺服器內部錯誤、Gemini VLM API 延遲過高,或是 CPU/記憶體使用率異常時,系統必須主動推播 即時告警訊息 至開發團隊的 LINE 頻道,以便在長輩發現服務異常前進行處理。
今天我們將為 PrescriptionVLM 系統建立 Grafana Alerting 系統異常告警與 LINE 即時通知機制。完成項目包含:
在生產環境的可觀測性中,告警機制是確保服務品質的重要部分:
app.py)由於 Grafana Alerting 的預設 Webhook payload 格式較複雜,我們在 app.py 中新增一個專用的告警接收端點 /api/alerts/line,自動解析 Grafana 告警 JSON 並呼叫 LINE Push API:
@app.route("/api/alerts/line", methods=["POST"])
def handle_grafana_alert():
"""接收 Grafana Webhook 告警並轉發至 LINE"""
alert_data = request.get_json()
if not alert_data:
return jsonify({"status": "invalid payload"}), 400
status = alert_data.get("status", "unknown") # firing 或 resolved
alerts = alert_data.get("alerts", [])
for alert in alerts:
labels = alert.get("labels", {})
annotations = alert.get("annotations", {})
alert_name = labels.get("alertname", "系統異常告警")
severity = labels.get("severity", "warning")
summary = annotations.get("summary", "檢測到系統數據異常")
description = annotations.get("description", "無詳細說明")
# 根據告警狀態選擇圖示與顏色提示
status_icon = "🚨 [FIRING]" if status == "firing" else "✅ [RESOLVED]"
message_text = (
f"{status_icon} PrescriptionVLM 系統告警\n"
f"━━━━━━━━━━━━━━━\n"
f"📌 告警名稱: {alert_name}\n"
f"⚠️ 嚴重程度: {severity.upper()}\n"
f"📝 概要說明: {summary}\n"
f"🔍 詳細資訊: {description}\n"
f"⏰ 觸發時間: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
)
# 呼叫現有 LINE 推播機制
if line_bot_api and line_user_id:
try:
line_bot_api.push_message(
PushMessageRequest(
to=line_user_id,
messages=[TextMessage(text=message_text)]
)
)
logger.info(f"告警訊息已成功轉發至 LINE: {alert_name}")
except Exception as e:
logger.error(f"轉發告警至 LINE 失敗: {str(e)}")
return jsonify({"status": "success"}), 200
在 Grafana 管理介面中完成告警規則設定:
1. 設定 Contact Point (告警聯絡點)
登入 Grafana (http://localhost:3000) ➔ 進入 Alerting ➔ Contact points。
點擊 Add contact point:
LINE-Webhook-Alert
Webhook
http://web:5000/api/alerts/line
點擊 Test 測試連線,並點擊 Save contact point。
2. 設定 Notification Policy (通知策略)
LINE-Webhook-Alert。3. 建立 Alert Rule (告警規則範例)
進入 Alert rules ➔ New alert rule,建立兩組核心防禦規則:
規則 A:HTTP 5xx 伺服器錯誤過高
sum(rate(flask_http_request_total{status=~"5.."}[2m])) > 0
severity = critical
PrescriptionVLM 發生 5xx 內部伺服器錯誤
規則 B:Gemini VLM API 延遲過高
histogram_quantile(0.95, sum(rate(flask_http_request_duration_seconds_bucket[5m])) by (le)) > 5
severity = warning
API 95% 回應時間超過 5 秒
1. 模擬系統異常觸發告警
發送故意引發錯誤的測試請求:
# 手動向 API 發送無效請求以產生異常
curl -X POST http://127.0.0.1:5000/analyze-prescription -F "invalid_field=1"
2. 觀察 Grafana 與 LINE 推播
Normal 轉為 Pending,持續 1 分鐘後進入 Firing 狀態。🚨 [FIRING] PrescriptionVLM 系統告警 的結構化通知訊息。✅ [RESOLVED] 復原通知。測試通過後,將 Day 27 的修改提交至 GitHub:
git add app.py
git commit -m "保留雙引號 改填寫自己要記錄的標記 ex.鐵人賽第二十七天"
git push
今天我們完成了 PrescriptionVLM 的主動告警機制,透過 Grafana Alerting 與 LINE Webhook 的整合,實現了系統異常檢測與即時推播通知的能力。
明天(Day 28),我們將進入專案的終極整合與架構優化,實作 多模態 VLM 提示詞工程終極調優與邊緣異常防衛,進一步提升藥袋識別的精準度與抗干擾能力!