import os import time import asyncio import logging from fastapi import FastAPI, Request from app.api import health, recommend, chat, analyze, tongue, adapter from app import monitoring from src.app import router as questionnaire_router logger = logging.getLogger(__name__) app = FastAPI(title="cfc-langgraph", version="0.3.0") app.include_router(health.router) app.include_router(recommend.router) app.include_router(chat.router) app.include_router(analyze.router) app.include_router(tongue.router) app.include_router(adapter.router) app.include_router(monitoring.router) app.include_router(questionnaire_router) @app.middleware("http") async def timing_middleware(request: Request, call_next): start = time.perf_counter() response = await call_next(request) elapsed = time.perf_counter() - start if elapsed > 5: logger.warning("SLOW_REQUEST: %s %s took %.2fs", request.method, request.url.path, elapsed) else: logger.debug("REQUEST: %s %s took %.2fs", request.method, request.url.path, elapsed) response.headers["X-Response-Time"] = f"{elapsed:.3f}s" return response @app.on_event("startup") async def startup(): from app.config import settings from app.log_config import setup_logging json_logs = os.getenv("JSON_LOGS", "false").lower() == "true" setup_logging(level=settings.log_level, json_format=json_logs) if os.getenv("LANGCHAIN_TRACING_V2", "").lower() == "true": logger.info( "LangSmith 已启用: project=%s, api_key=%s...", settings.langchain_project, settings.langchain_api_key[:8] if settings.langchain_api_key else "none", ) from app.rag.retriever import RagRetriever retriever = RagRetriever() await retriever.initialize() async def schedule_kb_sync(): while True: try: from app.tasks.knowledge_sync import sync_knowledge_base await sync_knowledge_base() except Exception as e: logger.warning("知识库同步失败: %s", e) await asyncio.sleep(3600) asyncio.create_task(schedule_kb_sync()) logger.info("知识库定时同步已启动 (间隔: 3600s)") @app.on_event("shutdown") async def shutdown(): from app.tools.java_client import JavaClient client = JavaClient() await client.close()