""" 简化版 FastAPI 应用主入口 用于快速启动和测试 """ from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse import structlog from datetime import datetime from app.config import get_settings from app.handlers.webhook import router as webhook_router from app.handlers.health import router as health_router from app.handlers.logs import router as logs_router from app.handlers.admin import router as admin_router # 配置日志 structlog.configure( processors=[ structlog.stdlib.filter_by_level, structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), structlog.processors.TimeStamper(fmt="iso"), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.UnicodeDecoder(), structlog.processors.JSONRenderer() ], context_class=dict, logger_factory=structlog.stdlib.LoggerFactory(), wrapper_class=structlog.stdlib.BoundLogger, cache_logger_on_first_use=True, ) logger = structlog.get_logger() # 创建 FastAPI 应用 app = FastAPI( title="Gitea Webhook Ambassador", description="高性能的 Gitea 到 Jenkins 的 Webhook 服务", version="1.0.0" ) # 添加 CORS 中间件 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 包含路由 app.include_router(webhook_router) app.include_router(health_router) app.include_router(logs_router) app.include_router(admin_router) @app.get("/") async def root(): """根路径""" return { "name": "Gitea Webhook Ambassador", "version": "1.0.0", "description": "高性能的 Gitea 到 Jenkins 的 Webhook 服务", "endpoints": { "webhook": "/webhook/gitea", "health": "/health", "metrics": "/metrics", "logs": "/api/logs", "admin": "/api/admin" } } @app.middleware("http") async def log_requests(request: Request, call_next): """请求日志中间件""" start_time = datetime.utcnow() # 记录请求 logger.info( "Request started", method=request.method, url=str(request.url), client_ip=request.client.host if request.client else None ) # 处理请求 response = await call_next(request) # 计算处理时间 process_time = (datetime.utcnow() - start_time).total_seconds() # 记录响应 logger.info( "Request completed", method=request.method, url=str(request.url), status_code=response.status_code, process_time=process_time ) # 添加处理时间到响应头 response.headers["X-Process-Time"] = str(process_time) return response @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): """全局异常处理器""" logger.error( "Unhandled exception", method=request.method, url=str(request.url), error=str(exc), exc_info=True ) return JSONResponse( status_code=500, content={ "error": "Internal server error", "message": "An unexpected error occurred" } ) if __name__ == "__main__": import uvicorn settings = get_settings() logger.info( "Starting Gitea Webhook Ambassador", host=settings.server.host, port=settings.server.port, version=settings.version ) uvicorn.run( "app.main_simple:app", host=settings.server.host, port=settings.server.port, reload=settings.server.reload )