"""慢日志 API。""" from typing import Optional from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.security import get_current_user, require_role from app.core.crypto import decrypt_password from app.models.user import User from app.models.instance import Instance from app.services.slow_log_collector import SlowLogCollector router = APIRouter(prefix="/slow-logs", tags=["慢日志分析"]) @router.get("/instances/{instance_id}") async def list_slow_logs( instance_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(require_role("admin", "dba")), ): """获取指定实例的慢日志。""" result = await db.execute(select(Instance).where(Instance.id == instance_id)) instance = result.scalar_one_or_none() if not instance: raise HTTPException(status_code=404, detail="数据源不存在") collector = SlowLogCollector() logs = collector.get_slow_logs(instance_id) return { "instance_id": instance_id, "total": len(logs), "logs": [log.to_dict() for log in logs], } @router.post("/instances/{instance_id}/collect") async def collect_slow_logs( instance_id: int, database: str = "", limit: int = 50, db: AsyncSession = Depends(get_db), current_user: User = Depends(require_role("admin", "dba")), ): """手动收集慢日志。""" result = await db.execute(select(Instance).where(Instance.id == instance_id)) instance = result.scalar_one_or_none() if not instance: raise HTTPException(status_code=404, detail="数据源不存在") if not database: database = instance.database or "" collector = SlowLogCollector() instance.password = decrypt_password(instance.password) try: if instance.db_type == "mysql": logs = await collector.collect_mysql_slow_logs(instance, database, limit) elif instance.db_type in ("postgres", "postgresql"): logs = await collector.collect_postgres_slow_logs(instance, database, limit) else: raise HTTPException(status_code=400, detail=f"不支持的类型: {instance.db_type}") except Exception as e: raise HTTPException(status_code=500, detail=f"收集失败: {str(e)}") await collector.save_slow_logs(instance_id, logs) report = collector.get_report(instance_id) return report.to_dict() @router.get("/instances/{instance_id}/report") async def slow_log_report( instance_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(require_role("admin", "dba")), ): """获取慢日志分析报告。""" collector = SlowLogCollector() report = collector.get_report(instance_id) return report.to_dict() @router.get("/dashboard/top") async def dashboard_top_queries( db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """仪表盘慢查询 TOP 10。""" collector = SlowLogCollector() all_logs = [] for instance_id, logs in collector._logs.items(): all_logs.extend(logs) # 全局 TOP 10 top = sorted(all_logs, key=lambda x: x.avg_time_ms, reverse=True)[:10] return { "total_instances": len(collector._logs), "top_queries": [q.to_dict() for q in top], }