AutoRpa/rpa_oms/app/inbound/audit.py

74 lines
1.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 入站审计:一行请求一条,写失败只记日志,不把业务请求打成 500。
from __future__ import annotations
import json
import logging
from typing import Any
logger = logging.getLogger("rpa_oms.inbound.audit")
_INSERT_SQL = """
INSERT INTO rpa_oms_inbound_audit (
api_no, http_code, request_json, response_json, error_text, token_masked
) VALUES (
:api_no, :http_code, :request_json, :response_json, :error_text, :token_masked
)
"""
_ERROR_MAX = 4000
# 有 token 就打成 ***,没有则空。不把明文写进审计。
def mask_token(token: str | None) -> str | None:
if not token:
return None
return "***"
# 把入参或出参收成 JSON 字符串,datetime / Decimal 用 str。
def dumps(payload: Any) -> str:
return json.dumps(payload, ensure_ascii=False, default=str)
# 内部错误原文截到 VARCHAR2(4000)。空串当没有。
def clip_error(text: str | None) -> str | None:
if not text:
return None
if len(text) > _ERROR_MAX:
return text[:_ERROR_MAX]
return text
# 往审计表插一行。任何异常都吞掉并记日志。
def write_audit(
conn,
*,
api_no: int,
http_code: int,
payload: Any,
response: Any,
error_text: str | None,
token: str | None,
) -> None:
binds = {
"api_no": api_no,
"http_code": http_code,
"request_json": dumps(payload if payload is not None else {}),
"response_json": dumps(response if response is not None else {}),
"error_text": clip_error(error_text),
"token_masked": mask_token(token),
}
try:
with conn.cursor() as cur:
cur.execute(_INSERT_SQL, binds)
conn.commit()
except Exception:
logger.exception("inbound audit write failed")
# 取出内部错误原文:优先 __cause__,供审计表用,不给出站。
def cause_text(exc: BaseException) -> str:
cause = exc.__cause__ or exc
return str(cause)