"""NL2SQL 管理员诊断数据构造。""" from __future__ import annotations from collections import deque from threading import Lock def build_diagnostic_snapshot( *, query_id: str, status: str, access_tables: set[str] | list[str], security_rule: str | None = None, model_elapsed_ms: float | None = None, sql: str | None = None, ) -> dict: """构造不含原始 SQL 和敏感结果的诊断快照。""" return { "query_id": query_id, "status": status, "access_tables": sorted(set(access_tables)), "security_rule": security_rule, "model_elapsed_ms": model_elapsed_ms, "has_sql": bool(sql), } class DiagnosticRegistry: """保存最近的脱敏诊断摘要,进程重启后自动清空。""" def __init__(self, *, max_items: int = 100): self._items = deque(maxlen=max_items) self._lock = Lock() def record(self, **kwargs) -> None: """记录诊断摘要并丢弃未定义的敏感字段。""" allowed = { "query_id", "status", "access_tables", "security_rule", "model_elapsed_ms", "sql", } snapshot = build_diagnostic_snapshot(**{key: value for key, value in kwargs.items() if key in allowed}) with self._lock: self._items.appendleft(snapshot) def list_recent(self) -> list[dict]: """返回最近诊断摘要的副本。""" with self._lock: return [dict(item) for item in self._items] diagnostic_registry = DiagnosticRegistry()