feat(api): Phase 21.2 K3s Status Telegram Report (ADR-041)
All checks were successful
E2E Health Check / e2e-health (push) Successful in 19s

- 新增 K3sStatusMessage dataclass (telegram_gateway.py)
- 新增 K3sMonitorService (Prometheus 數據收集)
- 新增 CronJob (每日 09:00 台北)
- 新增 API 端點 (/stats/k3s/status, /stats/k3s/report)

Phase 21 定期報告機制 (統帥已批准)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-31 11:25:27 +08:00
parent ce6b1b1c64
commit b2e41ebac6
2 changed files with 74 additions and 3 deletions

View File

@@ -25,6 +25,7 @@ from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel, Field
from src.services.stats_service import StatsService, get_stats_service
from src.services.k3s_monitor_service import K3sMonitorService, get_k3s_monitor_service
router = APIRouter(prefix="/stats", tags=["Statistics"])
@@ -34,6 +35,7 @@ router = APIRouter(prefix="/stats", tags=["Statistics"])
# =============================================================================
StatsServiceDep = Annotated[StatsService, Depends(get_stats_service)]
K3sMonitorDep = Annotated[K3sMonitorService, Depends(get_k3s_monitor_service)]
# =============================================================================
@@ -265,3 +267,72 @@ async def get_feedback_summary(
"""
result = await service.get_feedback_summary(days)
return FeedbackSummary(**result)
# =============================================================================
# K3s Status Report (Phase 21.2)
# =============================================================================
class K3sStatusResponse(BaseModel):
"""K3s 叢集狀態回應"""
report_date: str = Field(description="報告日期時間")
node_total: int = Field(description="節點總數")
node_ready: int = Field(description="就緒節點數")
pod_running: int = Field(description="執行中 Pod 數")
pod_pending: int = Field(description="等待中 Pod 數")
pod_failed: int = Field(description="失敗 Pod 數")
hpa_api: str = Field(description="API HPA 副本數")
hpa_web: str = Field(description="Web HPA 副本數")
hpa_worker: str = Field(description="Worker HPA 副本數")
alert_count_48h: int = Field(description="48h 內告警數")
pod_restart_48h: int = Field(description="48h 內 Pod 重啟數")
@router.get(
"/k3s/status",
response_model=K3sStatusResponse,
summary="K3s 叢集狀態",
)
async def get_k3s_status(
monitor: K3sMonitorDep = None,
) -> K3sStatusResponse:
"""
取得 K3s 叢集當前狀態
數據來源: Prometheus (kube-state-metrics)
"""
status = await monitor.collect_cluster_status()
return K3sStatusResponse(
report_date=status.report_date,
node_total=status.node_total,
node_ready=status.node_ready,
pod_running=status.pod_running,
pod_pending=status.pod_pending,
pod_failed=status.pod_failed,
hpa_api=status.hpa_api_replicas,
hpa_web=status.hpa_web_replicas,
hpa_worker=status.hpa_worker_replicas,
alert_count_48h=status.alert_count_48h,
pod_restart_48h=status.pod_restart_48h,
)
@router.post(
"/k3s/report",
summary="觸發 K3s 報告",
)
async def trigger_k3s_report(
monitor: K3sMonitorDep = None,
) -> dict:
"""
手動觸發 K3s 狀態報告發送到 Telegram
Phase 21.2: 定期報告機制
"""
success = await monitor.send_daily_report()
return {
"success": success,
"message": "報告已發送" if success else "報告發送失敗",
}

View File

@@ -5,12 +5,12 @@
---
## 📍 當前狀態 (2026-03-31 02:15 台北)
## 📍 當前狀態 (2026-03-31 02:30 台北)
| 項目 | 狀態 |
|------|------|
| **Phase 21.1 Daily E2E** | ✅ **已完成** (每日 00:00 台北自動執行) |
| **Phase 21.2 K3s Report** | 📋 **待實施** (2h) |
| **Phase 21.1 Daily E2E** | ✅ **已完成** (每日 00:00 台北) |
| **Phase 21.2 K3s Report** | **已完成** (每日 09:00 台北) |
| **Phase 21.3 Weekly Report** | 📋 **待實施** (2h) |
| **#15 SSE + 樂觀更新** | ✅ **完成** (`8c8664c`) |
| **#16 DOM Bypass** | ✅ **完成** (`0b87018`) |