Files
Mutual_Fund/nl2sql/audit.py
T

67 lines
1.9 KiB
Python

"""NL2SQL 审计日志适配器,复用现有 audit_log 表。"""
from __future__ import annotations
import json
from sqlalchemy import text
_SENSITIVE_KEYS = {"password", "token", "secret", "api_key", "connection", "credential"}
def _sanitize(value):
"""递归移除连接凭据等不应进入审计详情的字段。"""
if isinstance(value, dict):
return {
key: "[REDACTED]" if str(key).lower() in _SENSITIVE_KEYS else _sanitize(item)
for key, item in value.items()
}
if isinstance(value, (list, tuple)):
return [_sanitize(item) for item in value]
return value
async def write_nl2sql_audit(
db,
*,
user_id: int | None,
username: str | None,
action: str,
target: str | None,
trace_id: str | None,
detail: dict | None = None,
status: str = "成功",
) -> None:
"""写入 NL2SQL 审计事件,调用方负责在失败时降级。"""
statement = text(
"""
INSERT INTO audit_log
(user_id, username, module, action, target, detail, trace_id, status)
VALUES
(:user_id, :username, :module, :action, :target, :detail, :trace_id, :status)
"""
)
await db.execute(
statement,
{
"user_id": user_id,
"username": username,
"module": "nl2sql",
"action": action,
"target": target,
"detail": json.dumps(_sanitize(detail or {}), ensure_ascii=False),
"trace_id": trace_id,
"status": status,
},
)
await db.commit()
async def write_nl2sql_audit_safely(db, **kwargs) -> bool:
"""审计写入失败时记录 False,不阻断查询主流程。"""
try:
await write_nl2sql_audit(db, **kwargs)
except Exception: # noqa: BLE001 审计故障不能影响查询能力
return False
return True