from __future__ import annotations from datetime import datetime from typing import Optional from sqlalchemy import DateTime, Float, ForeignKey, Integer, JSON, String, Text, Index from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.sql import func from .database import Base class HostMetrics(Base): """Stocke les métriques collectées par les builtin playbooks pour chaque hôte.""" __tablename__ = "host_metrics" __table_args__ = ( Index("idx_host_metrics_host_id", "host_id"), Index("idx_host_metrics_collected_at", "collected_at"), Index("idx_host_metrics_metric_type", "metric_type"), ) id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) host_id: Mapped[str] = mapped_column(String, ForeignKey("hosts.id", ondelete="CASCADE"), nullable=False) metric_type: Mapped[str] = mapped_column(String(50), nullable=False) # 'system_info', 'disk_usage', 'memory', etc. # Métriques CPU cpu_count: Mapped[Optional[int]] = mapped_column(Integer) cpu_model: Mapped[Optional[str]] = mapped_column(String(200)) cpu_cores: Mapped[Optional[int]] = mapped_column(Integer) cpu_threads: Mapped[Optional[int]] = mapped_column(Integer) cpu_threads_per_core: Mapped[Optional[int]] = mapped_column(Integer) cpu_sockets: Mapped[Optional[int]] = mapped_column(Integer) cpu_mhz: Mapped[Optional[float]] = mapped_column(Float) cpu_max_mhz: Mapped[Optional[float]] = mapped_column(Float) cpu_min_mhz: Mapped[Optional[float]] = mapped_column(Float) cpu_load_1m: Mapped[Optional[float]] = mapped_column(Float) cpu_load_5m: Mapped[Optional[float]] = mapped_column(Float) cpu_load_15m: Mapped[Optional[float]] = mapped_column(Float) cpu_usage_percent: Mapped[Optional[float]] = mapped_column(Float) cpu_temperature: Mapped[Optional[float]] = mapped_column(Float) # Métriques mémoire memory_total_mb: Mapped[Optional[int]] = mapped_column(Integer) memory_used_mb: Mapped[Optional[int]] = mapped_column(Integer) memory_free_mb: Mapped[Optional[int]] = mapped_column(Integer) memory_usage_percent: Mapped[Optional[float]] = mapped_column(Float) swap_total_mb: Mapped[Optional[int]] = mapped_column(Integer) swap_used_mb: Mapped[Optional[int]] = mapped_column(Integer) swap_usage_percent: Mapped[Optional[float]] = mapped_column(Float) # Métriques disque (stockées en JSON pour flexibilité - plusieurs disques) disk_info: Mapped[Optional[object]] = mapped_column(JSON) # Liste des points de montage avec usage disk_devices: Mapped[Optional[object]] = mapped_column(JSON) # Liste des disques + partitions (layout) disk_root_total_gb: Mapped[Optional[float]] = mapped_column(Float) disk_root_used_gb: Mapped[Optional[float]] = mapped_column(Float) disk_root_usage_percent: Mapped[Optional[float]] = mapped_column(Float) # Storage stacks (JSON) lvm_info: Mapped[Optional[object]] = mapped_column(JSON) zfs_info: Mapped[Optional[object]] = mapped_column(JSON) # Informations système os_name: Mapped[Optional[str]] = mapped_column(String(100)) os_version: Mapped[Optional[str]] = mapped_column(String(100)) kernel_version: Mapped[Optional[str]] = mapped_column(String(100)) hostname: Mapped[Optional[str]] = mapped_column(String(200)) uptime_seconds: Mapped[Optional[int]] = mapped_column(Integer) uptime_human: Mapped[Optional[str]] = mapped_column(String(100)) # Réseau (stocké en JSON pour flexibilité) network_info: Mapped[Optional[dict]] = mapped_column(JSON) # Données brutes et métadonnées raw_data: Mapped[Optional[dict]] = mapped_column(JSON) # Données brutes du playbook collection_source: Mapped[Optional[str]] = mapped_column(String(100)) # Nom du builtin playbook collection_duration_ms: Mapped[Optional[int]] = mapped_column(Integer) error_message: Mapped[Optional[str]] = mapped_column(Text) collected_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) host: Mapped["Host"] = relationship("Host", back_populates="metrics") def __repr__(self) -> str: return f""