加入日志管理
This commit is contained in:
+63
-9
@@ -28,6 +28,10 @@ _BACKEND_DIR = _REPO_DIR / "backend"
|
||||
if str(_BACKEND_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(_BACKEND_DIR))
|
||||
|
||||
from utils.repo_logging import configure_text2sql_api_logging
|
||||
|
||||
configure_text2sql_api_logging(_REPO_DIR)
|
||||
|
||||
from main import setup_environment, load_schema, create_orchestrator, resolve_sql_dialect
|
||||
from agents.orchestrator import GenerationResult
|
||||
from nl_lite_store import lite_nl_store
|
||||
@@ -38,11 +42,6 @@ from utils.dialog_context import (
|
||||
is_likely_follow_up,
|
||||
)
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# per-request 覆盖 LLM client 时,使用锁避免并发串改 orchestrator.deepseek
|
||||
@@ -617,6 +616,15 @@ async def _run_generate(
|
||||
orch = get_orchestrator()
|
||||
dialect = resolve_sql_dialect(os.getenv("TEXT2SQL_DIALECT", "sqlserver"))
|
||||
dc = (dialog_context or "").strip() or None
|
||||
q = question.strip()
|
||||
logger.info(
|
||||
"[GEN/API] dialect=%s top_k=%s dialog_context_chars=%s question_len=%s preview=%r",
|
||||
dialect,
|
||||
top_k,
|
||||
len(dc) if dc else 0,
|
||||
len(q),
|
||||
q[:300] + ("…" if len(q) > 300 else ""),
|
||||
)
|
||||
|
||||
async def _call_with_orch(o) -> GenerationResult:
|
||||
def _call() -> GenerationResult:
|
||||
@@ -643,6 +651,20 @@ async def _chat_stream_events(request: NLChatRequest) -> AsyncIterator[bytes]:
|
||||
text = request.message.strip()
|
||||
orch = get_orchestrator()
|
||||
dialog_block, last_data = await _load_session_text2sql_context(request, text)
|
||||
logger.info(
|
||||
"[API/stream] 开始: user_id=%r visitor_biz_id=%r session_id=%r service_code=%r model=%r "
|
||||
"lang_code=%r msg_chars=%s preview=%r dialog_context_chars=%s last_turn_was_data_query=%s",
|
||||
request.user_id,
|
||||
request.visitor_biz_id,
|
||||
request.session_id,
|
||||
request.service_code,
|
||||
request.model,
|
||||
request.lang_code,
|
||||
len(text),
|
||||
text[:400] + ("…" if len(text) > 400 else ""),
|
||||
len(dialog_block) if dialog_block else 0,
|
||||
last_data,
|
||||
)
|
||||
lang = _normalize_lang_code(request.lang_code)
|
||||
async with _maybe_override_orch_llm(orch, request) as o:
|
||||
classified = await asyncio.to_thread(
|
||||
@@ -656,7 +678,11 @@ async def _chat_stream_events(request: NLChatRequest) -> AsyncIterator[bytes]:
|
||||
reply = (classified.reply_suggestion or "").strip()
|
||||
if not reply:
|
||||
reply = _localized_conversation_reply(lang)
|
||||
logger.info("[API/stream] 对话意图: conversation(跳过 Text2SQL,与 CLI single_query 一致)")
|
||||
logger.info(
|
||||
"[API/stream] 对话意图 conversation(跳过 Text2SQL): reply_chars=%s reply_preview=%r",
|
||||
len(reply),
|
||||
reply[:500] + ("…" if len(reply) > 500 else ""),
|
||||
)
|
||||
yield _sse_data({"stage": "orchestrator", "stream_kind": "content", "content": "CHAT"})
|
||||
async for pkt in _sse_stream_text_chunks("chat", reply):
|
||||
yield pkt
|
||||
@@ -669,10 +695,24 @@ async def _chat_stream_events(request: NLChatRequest) -> AsyncIterator[bytes]:
|
||||
try:
|
||||
result = await _run_generate(text, dialog_context=dialog_block or None, request=request)
|
||||
except Exception as e:
|
||||
logger.error(f"[API/stream] 生成异常: {e}")
|
||||
logger.error(f"[API/stream] 生成异常: {e}", exc_info=True)
|
||||
yield _sse_data({"code": 500, "msg": str(e), "data": None})
|
||||
return
|
||||
|
||||
sql_out = (result.sql or "").strip()
|
||||
logger.info(
|
||||
"[API/stream] Text2SQL 完成: valid=%s attempts=%s tables_used=%s sql_chars=%s sql_head=%r",
|
||||
result.valid,
|
||||
result.attempts,
|
||||
result.tables_used,
|
||||
len(sql_out),
|
||||
sql_out[:500] + ("…" if len(sql_out) > 500 else ""),
|
||||
)
|
||||
if result.errors:
|
||||
logger.warning("[API/stream] 错误列表: %s", result.errors)
|
||||
if result.warnings:
|
||||
logger.info("[API/stream] 警告列表: %s", result.warnings)
|
||||
|
||||
# What this SQL does / SQL 说明:按 lang_code 本地化
|
||||
try:
|
||||
if isinstance(result.metadata, dict):
|
||||
@@ -747,9 +787,21 @@ async def nl_chat(request: NLChatRequest):
|
||||
lang = _normalize_lang_code(request.lang_code)
|
||||
raise HTTPException(status_code=400, detail=_localized_empty_input_reply(lang))
|
||||
text = request.message.strip()
|
||||
logger.info(f"[API] 问题: {text[:100]}...")
|
||||
orch = get_orchestrator()
|
||||
dialog_block, last_data = await _load_session_text2sql_context(request, text)
|
||||
logger.info(
|
||||
"[API/chat] 请求: user_id=%r session_id=%r service_code=%r model=%r lang=%r "
|
||||
"msg_chars=%s preview=%r dialog_context_chars=%s last_turn_was_data_query=%s",
|
||||
request.user_id,
|
||||
request.session_id,
|
||||
request.service_code,
|
||||
request.model,
|
||||
request.lang_code,
|
||||
len(text),
|
||||
text[:400] + ("…" if len(text) > 400 else ""),
|
||||
len(dialog_block) if dialog_block else 0,
|
||||
last_data,
|
||||
)
|
||||
lang = _normalize_lang_code(request.lang_code)
|
||||
async with _maybe_override_orch_llm(orch, request) as o:
|
||||
classified = await asyncio.to_thread(
|
||||
@@ -1004,5 +1056,7 @@ if __name__ == "__main__":
|
||||
host=host,
|
||||
port=port,
|
||||
reload=False,
|
||||
log_level="info"
|
||||
log_level="info",
|
||||
# 必须为 None:False 仍会进入 uvicorn 的 fileConfig 分支并崩溃;None 才跳过覆盖 root 日志
|
||||
log_config=None,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user