import logging import time import structlog from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from prometheus_fastapi_instrumentator import Instrumentator from .api import kb, compliance, regulation from .core.config import settings # 结构化日志配置 structlog.configure( wrapper_class=structlog.make_filtering_bound_logger( getattr(logging, settings.log_level.upper(), logging.INFO) ) ) logger = structlog.get_logger() app = FastAPI( title="AI合规智能中枢 API", description="面向车企与工厂的全链路合规智能平台", version="0.1.0", docs_url="/docs", redoc_url="/redoc", ) # CORS(开发环境) app.add_middleware( CORSMiddleware, allow_origins=["*"] if settings.app_env == "development" else [], allow_methods=["*"], allow_headers=["*"], ) # Prometheus 指标 Instrumentator().instrument(app).expose(app) # 注册路由 app.include_router(kb.router) app.include_router(compliance.router) app.include_router(regulation.router) @app.middleware("http") async def log_requests(request: Request, call_next): start = time.time() response = await call_next(request) duration_ms = int((time.time() - start) * 1000) logger.info( "request", method=request.method, path=request.url.path, status=response.status_code, duration_ms=duration_ms, ) return response @app.get("/health") async def health(): """健康检查(含依赖服务检测)""" import httpx from .core.config import settings checks = {"status": "ok", "services": {}} # 检查嵌入服务 try: async with httpx.AsyncClient(timeout=5) as client: r = await client.get(f"{settings.embedding_service_url}/health") checks["services"]["embedding"] = "ok" if r.status_code == 200 else "degraded" except Exception: checks["services"]["embedding"] = "unavailable" # 检查 MCP Server try: async with httpx.AsyncClient(timeout=5) as client: r = await client.get(f"{settings.mcp_server_url}/health") checks["services"]["mcp"] = "ok" if r.status_code == 200 else "degraded" except Exception: checks["services"]["mcp"] = "unavailable" return checks