#!/usr/bin/env python # -*- coding: utf-8 -*- """ 数据库监控 API 监控维度与「数据库连接管理」一致:每个启用连接(code)为一个监控目标, 凭证通过 ConnectionResolver 解析,支持 PostgreSQL / MySQL / SQL Server / Oracle。 """ import logging from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from core.database_monitor.config_resolver import ( create_monitor_collector, list_monitor_configs, resolve_monitor_target, ) from core.database_monitor.schema import ( DatabaseConfigSchema, DatabaseConnectionTestSchema, DatabaseOverviewSchema, DatabaseRealtimeStatsSchema, ) logger = logging.getLogger(__name__) router = APIRouter(prefix="/database_monitor", tags=["数据库监控"]) async def get_database_configs(db: AsyncSession) -> List[dict]: """获取全部可监控连接配置(供 WebSocket 等模块复用)。""" return await list_monitor_configs(db) @router.get("/configs", response_model=List[DatabaseConfigSchema], summary="获取数据库监控目标列表") async def get_database_monitor_configs(db: AsyncSession = Depends(get_db)): """获取已注册的数据库连接列表,作为监控目标。""" configs = await list_monitor_configs(db) return [ DatabaseConfigSchema( name=config["name"], db_name=config["db_name"], db_type=config["db_type"], host=config["host"], port=config["port"], database=config["database"], user=config["user"], has_password=config["has_password"], is_system=config.get("is_system", False), ) for config in configs ] @router.get("/{connection_code}/overview", response_model=DatabaseOverviewSchema, summary="获取数据库概览信息") async def get_database_overview( connection_code: str, database: Optional[str] = Query(None, description="覆盖连接默认库/服务名"), db: AsyncSession = Depends(get_db), ): """获取指定连接的监控概览。""" try: target = await resolve_monitor_target(db, connection_code, database) except ValueError as exc: raise HTTPException(status_code=404, detail=str(exc)) from exc collector = create_monitor_collector(target) data = await collector.get_all_info(connection_code, target["name"]) return DatabaseOverviewSchema(**data) @router.get("/{connection_code}/realtime", response_model=DatabaseRealtimeStatsSchema, summary="获取数据库实时统计") async def get_database_realtime_stats( connection_code: str, database: Optional[str] = Query(None, description="覆盖连接默认库/服务名"), db: AsyncSession = Depends(get_db), ): """获取指定连接的实时统计。""" try: target = await resolve_monitor_target(db, connection_code, database) except ValueError as exc: raise HTTPException(status_code=404, detail=str(exc)) from exc collector = create_monitor_collector(target) data = await collector.get_realtime_stats(connection_code) return DatabaseRealtimeStatsSchema(**data) @router.post("/{connection_code}/test", response_model=DatabaseConnectionTestSchema, summary="测试数据库连接") async def test_database_connection( connection_code: str, database: Optional[str] = Query(None, description="覆盖连接默认库/服务名"), db: AsyncSession = Depends(get_db), ): """测试指定连接是否可用。""" try: target = await resolve_monitor_target(db, connection_code, database) except ValueError as exc: raise HTTPException(status_code=404, detail=str(exc)) from exc collector = create_monitor_collector(target) result = await collector.test_connection() return DatabaseConnectionTestSchema(**result)