from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager import logging from .core.config import settings from .core.logging_config import setup_logging, get_logger from .core.database import init_db from .core.db_monitor import start_monitoring, log_pool_status, get_pool_status from .api.account import router as account_router from .api.database import router as database_router from .api.task import router as task_router from .api.comprehensive_data import router as comprehensive_data_router from .api.export_excel import router as export_excel_router from .api.daily import router as daily_router from .api.section_data import router as section_data_router from .api.level_data import router as level_data_router from .api.checkpoint import router as checkpoint_router from .api.function_list import router as function_list_router from .utils.scheduler import task_scheduler # 初始化日志系统 setup_logging() logger = get_logger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """应用生命周期管理""" # 启动时执行 logger.info("应用启动中...") # 初始化数据库 try: init_db() logger.info("数据库初始化完成") except Exception as e: logger.error(f"数据库初始化失败: {e}") # 启动数据库监控 try: start_monitoring() logger.info("数据库连接池监控已启动") # 记录初始连接池状态 pool_stats = get_pool_status() logger.info(f"初始连接池状态: {pool_stats}") except Exception as e: logger.error(f"数据库监控启动失败: {e}") # 启动定时任务调度器 try: task_scheduler.start() logger.info("定时任务调度器启动完成") except Exception as e: logger.error(f"定时任务调度器启动失败: {e}") yield # 关闭时执行 logger.info("应用关闭中...") # 记录最终连接池状态 try: pool_stats = get_pool_status() logger.info(f"最终连接池状态: {pool_stats}") except Exception as e: logger.error(f"获取最终连接池状态失败: {e}") try: task_scheduler.shutdown() logger.info("定时任务调度器已关闭") except Exception as e: logger.error(f"定时任务调度器关闭失败: {e}") # 创建FastAPI应用 app = FastAPI( title="铁路项目管理系统", description="基于FastAPI、MySQL、SQLAlchemy的铁路项目管理系统", version="1.0.0", lifespan=lifespan ) # 配置CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], # 生产环境建议配置具体域名 allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 注册路由 app.include_router(account_router, prefix="/api") app.include_router(database_router, prefix="/api") app.include_router(task_router, prefix="/api") app.include_router(comprehensive_data_router, prefix="/api") app.include_router(export_excel_router, prefix="/api") app.include_router(daily_router, prefix="/api") app.include_router(section_data_router, prefix="/api") app.include_router(level_data_router, prefix="/api") app.include_router(checkpoint_router, prefix="/api") app.include_router(function_list_router, prefix="/api") # app.include_router(test_router, prefix="/api") # 根路径 @app.get("/") async def root(): """根路径""" return { "message": "铁路项目管理系统 API", "version": "1.0.0", "docs": "/docs", "redoc": "/redoc" } # 健康检查 @app.get("/health") async def health_check(): """健康检查""" return { "status": "healthy", "database": "connected", "scheduler": "running" if task_scheduler.scheduler.running else "stopped" } # 数据库监控端点 @app.get("/api/monitor/database") async def get_database_monitor(): """获取数据库连接池监控信息""" from .core.db_monitor import get_monitoring_report return get_monitoring_report() # 连接池状态端点 @app.get("/api/monitor/pool") async def get_pool_status(): """获取连接池状态""" from .core.db_monitor import get_pool_status return get_pool_status() # 全局异常处理 @app.exception_handler(Exception) async def global_exception_handler(request, exc): """全局异常处理""" import traceback from .core.db_monitor import get_pool_status # 获取异常详情 error_msg = str(exc) error_type = type(exc).__name__ stack_trace = traceback.format_exc() # 获取当前连接池状态 try: pool_stats = get_pool_status() pool_info = f", 连接池使用率: {pool_stats.get('usage_percent', 'N/A')}%" except: pool_info = "" # 记录详细错误日志 logger.error( f"🚨 全局异常: {error_type}: {error_msg} " f"请求路径: {request.url.path}, 方法: {request.method}{pool_info}\n" f"堆栈跟踪:\n{stack_trace}" ) return HTTPException( status_code=500, detail=f"服务器内部错误: {error_type}" )