144 lines
5.1 KiB
Python

"""
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)}