feat(audit): per-request loguru audit middleware with daily rotation
按需为每个 HTTP 接口写一条合规记录到 data/logs/audit/audit-YYYY-MM-DD.log,字段:时间 / 用户 / METHOD path / 状态码。 设计: * 复用全局 loguru logger,文件 sink 由 audit._DailyFileSink 自管:缓存当天文件句柄、跨日重建。不走 loguru 的 rotation=00:00(产物是 audit.log.YYYY-MM-DD_HH-MM-SS, 不符合按天单文件的命名要求)。 * AuditMiddleware 只做 CPU 验签拿 user_id:cookie access_token 优先,Authorization Bearer 兜底,无/坏 JWT 一律记 '-'。 绝不查 DB(RequestContext 在路由解析后才注入)。 * 审计失败不拖死请求:所有异常捕获。 * 与 main.py 现有 access_log 严格分离:access_log 走 stderr 诊断(method/path/status/耗时),audit 走独立文件合规 (时间/用户/接口),并存。 * 启动时按 settings.audit_log_retention_days 清理过期文件 (设 0 关闭)。 * 新增 settings.audit_log_dir(默认 data/logs/audit,相对 cwd) 与 settings.audit_log_retention_days(默认 30)两个配置项; .env.example 同步。 新增 9 个 case:文件创建、行字段、未登录 '-'、坏 JWT、ULID path、retention 清理/关闭、Bearer 头、幂等。
This commit is contained in:
@@ -68,6 +68,17 @@ class Settings(BaseSettings):
|
||||
"anything else falls back to INFO inside configure_logging()."
|
||||
),
|
||||
)
|
||||
audit_log_dir: str = Field(
|
||||
default="data/logs/audit",
|
||||
description=(
|
||||
"审计日志目录。每天一个文件 audit-YYYY-MM-DD.log。"
|
||||
"路径相对于 backend 进程 cwd(容器内通常为 /app)。"
|
||||
),
|
||||
)
|
||||
audit_log_retention_days: int = Field(
|
||||
default=30,
|
||||
description="审计日志保留天数;过期文件启动时清理。设 0 关闭清理。",
|
||||
)
|
||||
|
||||
# ── runtime container endpoint ───────────────────────────────
|
||||
runtime_api_url: str = Field(
|
||||
|
||||
Reference in New Issue
Block a user