feat(api): Phase 21.2 K3s Status Telegram Report (ADR-041)
All checks were successful
E2E Health Check / e2e-health (push) Successful in 19s
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:
@@ -25,6 +25,7 @@ from fastapi import APIRouter, Depends, Query
|
|||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from src.services.stats_service import StatsService, get_stats_service
|
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"])
|
router = APIRouter(prefix="/stats", tags=["Statistics"])
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ router = APIRouter(prefix="/stats", tags=["Statistics"])
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
StatsServiceDep = Annotated[StatsService, Depends(get_stats_service)]
|
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)
|
result = await service.get_feedback_summary(days)
|
||||||
return FeedbackSummary(**result)
|
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 "報告發送失敗",
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📍 當前狀態 (2026-03-31 02:15 台北)
|
## 📍 當前狀態 (2026-03-31 02:30 台北)
|
||||||
|
|
||||||
| 項目 | 狀態 |
|
| 項目 | 狀態 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| **Phase 21.1 Daily E2E** | ✅ **已完成** (每日 00:00 台北自動執行) |
|
| **Phase 21.1 Daily E2E** | ✅ **已完成** (每日 00:00 台北) |
|
||||||
| **Phase 21.2 K3s Report** | 📋 **待實施** (2h) |
|
| **Phase 21.2 K3s Report** | ✅ **已完成** (每日 09:00 台北) |
|
||||||
| **Phase 21.3 Weekly Report** | 📋 **待實施** (2h) |
|
| **Phase 21.3 Weekly Report** | 📋 **待實施** (2h) |
|
||||||
| **#15 SSE + 樂觀更新** | ✅ **完成** (`8c8664c`) |
|
| **#15 SSE + 樂觀更新** | ✅ **完成** (`8c8664c`) |
|
||||||
| **#16 DOM Bypass** | ✅ **完成** (`0b87018`) |
|
| **#16 DOM Bypass** | ✅ **完成** (`0b87018`) |
|
||||||
|
|||||||
Reference in New Issue
Block a user