"""监控与日志模型(存储于 metrics.db) - MetricPoint: 资源监控时序数据(Agent 上报) - ServerInfo: 服务器基础信息快照(Agent 上报) - SecurityCheck: 安全检查项结果 - EventLog: 系统事件日志 """ from datetime import datetime from typing import Optional from sqlalchemy import Index from sqlmodel import Field, SQLModel from app.core.timeutils import utcnow class MetricPoint(SQLModel, table=True): """资源监控时序数据""" __tablename__ = "metric_points" __table_args__ = (Index("ix_metric_points_asset_ts", "asset_id", "ts"),) id: Optional[int] = Field(default=None, primary_key=True) asset_id: int = Field(index=True, description="关联资产 ID") ts: datetime = Field(default_factory=utcnow, index=True, description="采集时间") cpu_pct: Optional[float] = Field(default=None, description="CPU 使用率 %") mem_pct: Optional[float] = Field(default=None, description="内存使用率 %") disk_pct: Optional[float] = Field(default=None, description="磁盘使用率 %") net_in_mb: Optional[float] = Field(default=None, description="网络入流量 MB(采样间隔)") net_out_mb: Optional[float] = Field(default=None, description="网络出流量 MB(采样间隔)") load_1m: Optional[float] = Field(default=None, description="1 分钟负载") uptime_sec: Optional[int] = Field(default=None, description="运行时长(秒)") class ServerInfo(SQLModel, table=True): """服务器基础信息快照(每个资产一条,覆盖更新)""" __tablename__ = "server_info" id: Optional[int] = Field(default=None, primary_key=True) # 逻辑关联 assets.id(跨库不设物理外键) asset_id: int = Field(unique=True, index=True) hostname: Optional[str] = Field(default=None) os: Optional[str] = Field(default=None, description="操作系统发行版") kernel: Optional[str] = Field(default=None, description="内核版本") cpu_cores: Optional[int] = Field(default=None) mem_total_gb: Optional[float] = Field(default=None) disk_total_gb: Optional[float] = Field(default=None) public_ip: Optional[str] = Field(default=None) tailscale_ip: Optional[str] = Field(default=None) status: Optional[str] = Field(default="online", description="online/offline") last_seen: datetime = Field(default_factory=utcnow, description="最近上报时间") class SecurityCheck(SQLModel, table=True): """安全检查项结果""" __tablename__ = "security_checks" __table_args__ = (Index("ix_security_checks_asset_ts", "asset_id", "ts"),) id: Optional[int] = Field(default=None, primary_key=True) asset_id: int = Field(index=True) ts: datetime = Field(default_factory=utcnow, index=True) check_item: str = Field(description="检查项,如 ssh_config/firewall/updates") status: str = Field(default="unknown", description="pass/warn/fail/unknown") detail: Optional[str] = Field(default=None, description="检查详情") suggestion: Optional[str] = Field(default=None, description="加固建议") class EventLog(SQLModel, table=True): """系统事件日志""" __tablename__ = "event_logs" id: Optional[int] = Field(default=None, primary_key=True) ts: datetime = Field(default_factory=utcnow, index=True) level: str = Field(default="info", index=True, description="info/warning/error") source: str = Field(default="system", description="来源,如 agent/api/backup") asset_id: Optional[int] = Field(default=None, index=True) message: str = Field(description="事件内容")