""" Routes API pour les métriques système et des hôtes. """ from typing import Optional from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from app.core.dependencies import get_db, verify_api_key from app.crud.host_metrics import HostMetricsRepository from app.crud.app_setting import AppSettingRepository from app.services import db class CollectionScheduleRequest(BaseModel): interval: str = "off" router = APIRouter() @router.get("") async def get_metrics(api_key_valid: bool = Depends(verify_api_key)): """Récupère les métriques système globales.""" return db.metrics @router.get("/all-hosts") async def get_all_hosts_metrics( api_key_valid: bool = Depends(verify_api_key), db_session: AsyncSession = Depends(get_db) ): """Récupère les métriques de tous les hôtes.""" try: repo = HostMetricsRepository(db_session) metrics_dict = await repo.get_all_latest() # Convertir en dict host_id -> metrics result = {} for host_id, m in metrics_dict.items(): result[m.host_id] = { "host_id": m.host_id, "metric_type": m.metric_type, "cpu_usage_percent": m.cpu_usage_percent, "cpu_load_1m": m.cpu_load_1m, "cpu_model": m.cpu_model, "cpu_count": m.cpu_count, "memory_usage_percent": m.memory_usage_percent, "memory_total_mb": m.memory_total_mb, "memory_used_mb": m.memory_used_mb, "disk_root_usage_percent": m.disk_root_usage_percent, "disk_root_total_gb": m.disk_root_total_gb, "disk_root_used_gb": m.disk_root_used_gb, "os_name": m.os_name, "uptime_human": m.uptime_human, "collected_at": m.collected_at, "collection_status": "success" if not m.error_message else "failed", "error_message": m.error_message, } return result except Exception as e: # Si la table n'existe pas encore ou autre erreur return {} @router.get("/collection-schedule") async def get_collection_schedule( api_key_valid: bool = Depends(verify_api_key), db_session: AsyncSession = Depends(get_db) ): """Récupère l'intervalle de collecte des métriques.""" try: repo = AppSettingRepository(db_session) setting = await repo.get("metrics_collection_interval") interval = setting.value if setting else "off" return {"interval": interval} except Exception: return {"interval": "off"} @router.post("/collection-schedule") async def set_collection_schedule( request: CollectionScheduleRequest, api_key_valid: bool = Depends(verify_api_key), db_session: AsyncSession = Depends(get_db) ): """Définit l'intervalle de collecte des métriques.""" interval = request.interval valid_intervals = ["off", "5min", "15min", "30min", "1h", "6h", "12h", "24h"] if interval not in valid_intervals: raise HTTPException( status_code=400, detail=f"Intervalle invalide. Valeurs acceptées: {valid_intervals}" ) try: repo = AppSettingRepository(db_session) await repo.set("metrics_collection_interval", interval) await db_session.commit() return {"interval": interval, "message": f"Intervalle de collecte défini à {interval}"} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{host_id}") async def get_host_metrics( host_id: str, api_key_valid: bool = Depends(verify_api_key), db_session: AsyncSession = Depends(get_db) ): """Récupère les métriques d'un hôte spécifique.""" try: repo = HostMetricsRepository(db_session) metrics = await repo.get_latest_for_host(host_id) if not metrics: return {"host_id": host_id, "collection_status": "no_data"} return { "host_id": metrics.host_id, "metric_type": metrics.metric_type, "cpu_usage_percent": metrics.cpu_usage_percent, "cpu_load_1m": metrics.cpu_load_1m, "cpu_model": metrics.cpu_model, "cpu_count": metrics.cpu_count, "memory_usage_percent": metrics.memory_usage_percent, "memory_total_mb": metrics.memory_total_mb, "memory_used_mb": metrics.memory_used_mb, "disk_root_usage_percent": metrics.disk_root_usage_percent, "disk_root_total_gb": metrics.disk_root_total_gb, "disk_root_used_gb": metrics.disk_root_used_gb, "disk_info": metrics.disk_info, "os_name": metrics.os_name, "uptime_human": metrics.uptime_human, "collected_at": metrics.collected_at, "collection_status": "success" if not metrics.error_message else "failed", "error_message": metrics.error_message, } except Exception as e: return {"host_id": host_id, "collection_status": "error", "error_message": str(e)}