审计日志
审计日志用于回答“谁在什么时间做了什么操作”“哪些接口耗时异常”“哪些接口失败并产生了异常信息”。它将操作审计、性能日志和异常日志串在同一个 TraceId 下,方便从页面快速定位到具体请求和业务上下文。
为了不增加用户的接入负担,审计能力在设计时复用了项目中已有的 Swagger/OpenAPI 注解。大多数业务接口只要正常维护
@Tag和@Operation,审计就可以自动填充模块名称、操作名称、请求方法、操作人、接口路径、耗时和执行结果;重点场景或默认推断不满足时,再通过@OperationAudit、@OperationAuditIgnore补充业务 ID、修正操作类型或排除无需留痕的接口。审计模块是可选模块。默认后台已经启用,如果项目不需要审计,或担心审计写入带来额外开销,可以通过
audit-log.yml关闭,也可以在派生项目中移除sz-module-audit和前端菜单入口。
低负担接入
自动填充审计信息
审计默认关注 Controller 中的业务操作。普通新增、修改、删除接口不需要额外写审计代码,只要接口本身已经有 @Tag 和 @Operation:
@Tag(name = "字典来源")
@RestController
@RequestMapping("/sys-dict-source")
public class SysDictSourceController {
@Operation(summary = "新增字典来源")
@PostMapping
public ApiResult<Void> create(@RequestBody SysDictSourceCreateDTO dto) {
// 业务逻辑
}
}这条请求进入审计后,会自动得到“字典来源 / 新增字典来源”这样的可读描述。@Tag(name) 会作为模块名称,@Operation(summary) 会作为操作名称,POST 会被推断为新增操作。
默认自动采集哪些请求,由 audit-log.yml 的 methods 决定。生产环境一般只采集写操作,例如 POST、PUT、DELETE。如果方法或类上有 @SaIgnore,说明它通常是公开接口,默认不会自动进入审计;确实需要记录时,可以显式加 @OperationAudit。
重点场景补充 @OperationAudit
@OperationAudit 用于补足自动推断表达不了的信息,常见有三类:记录业务 ID、修正操作类型、控制参数或响应体记录。
角色授权接口虽然是 PUT,但排查时更希望按角色 ID 追踪:
@Operation(summary = "角色菜单配置")
@OperationAudit(operationType = OperationType.UPDATE, bizId = "#dto.roleId")
@PutMapping("/menu")
public ApiResult<Void> updateRoleMenu(@RequestBody RoleMenuUpdateDTO dto) {
// 业务逻辑
}脚本导出接口通常是 POST,如果不说明会被推断成新增。这里显式标记为导出,并记录导出的菜单 ID:
@Operation(summary = "导出菜单 SQL脚本")
@OperationAudit(operationType = OperationType.EXPORT, bizId = "#dto.ids")
@PostMapping("/script/sql/export")
public ApiResult<ScriptExportVO> exportSql(@RequestBody ScriptExportDTO dto) {
// 业务逻辑
}文件上传、Excel 导入这类接口可以标记为导入:
@Operation(summary = "上传资源文件")
@OperationAudit(operationType = OperationType.IMPORT)
@PostMapping("/upload")
public ApiResult<ResourceRef> upload(@RequestPart MultipartFile file) {
// 业务逻辑
}@OperationAudit 的常用参数不多:
| 参数 | 什么时候用 | 效果 |
|---|---|---|
operationType | HTTP 方法不能表达业务含义时 | 将操作标记为 IMPORT、EXPORT、UPDATE 等类型 |
bizId | 需要按业务主键定位时 | 在审计记录中保存业务 ID,支持 #id、#dto.id、#dto.ids、#p0.id |
name / module | Swagger 文案不适合审计展示时 | 覆盖 @Operation(summary) 或 @Tag(name) |
recordParams | 全局不记录参数,但个别接口要留痕时 | 当前接口强制记录脱敏、截断后的参数 |
responseBody | 全局记录响应体,但某个接口不能记录时 | 使用 BodyRecordMode.NEVER 禁止当前接口记录响应体 |
操作类型支持 AUTO、CREATE、UPDATE、DELETE、QUERY、IMPORT、EXPORT、LOGIN、LOGOUT、OTHER。默认 AUTO 会按请求方法推断:POST 为新增,PUT/PATCH 为修改,DELETE 为删除,GET 为查询。
不想生成审计日志
如果某个业务接口不希望生成审计日志,可以在方法或类上加 @OperationAuditIgnore:
@OperationAuditIgnore
@GetMapping("/internal/status")
public ApiResult<StatusVO> status() {
// 高频轮询、内部状态接口等
}这类场景通常包括高频轮询、健康检查、内部探活、无需留痕的公开接口。除此之外,@SaIgnore 标记的接口默认也不会被自动审计;methods 不包含的 HTTP 方法也不会自动审计。显式添加 @OperationAudit 时,可以把这些特殊场景重新纳入审计。
audit-log.yml 配置
审计配置位于:
config/{profile}/audit-log.yml修改后需要重启服务生效。它不依赖 sys_config,这样审计能力不会被数据库、缓存等运行时配置反向影响。
推荐写法
先从这份配置理解即可。多数项目只需要关注这些核心项:
sz:
audit:
# 总开关。false 时不写操作审计,适合不需要审计或临时关闭。
enabled: true
# 审计模式:
# standard:生产常规模式,只记录必要审计信息。
# debug:本地/测试排障模式,会额外输出访问摘要和慢响应日志。
# off:关闭审计;traceId 仍可保留用于普通日志定位。
mode: standard
# 写入模式。
# sync:同步尽力写入,保存失败不阻断业务。
# async:异步写入,适合高吞吐场景评估使用。
write-mode: sync
# 自动采集的 HTTP 方法。
# 生产建议只放写操作;不要轻易加入高频 GET。
methods: [POST, PUT, DELETE]
# 慢操作阈值,单位毫秒。
# 超过后会进入“性能日志”视图。
slow-threshold-ms: 2000
# 是否记录请求参数。
# 参数会脱敏和截断;敏感系统可设为 false,再用 @OperationAudit(recordParams = true) 精准开启。
record-params: true
# 是否记录响应体。
# 默认关闭,避免敏感数据和大响应入库;排障时再临时开启。
record-response-body: false
# SQL 审计:
# off:关闭 SQL 审计,推荐生产默认。
# slow:只记录慢 SQL,适合线上临时排查。
# all:记录全部 SQL,适合本地/测试环境。
sql-mode: off
# 是否启用 traceId,用于串联接口日志、SQL 日志和审计记录。
trace-enabled: true
# traceId 请求/响应头名称。
trace-header-name: X-Trace-Id生产环境建议保持 mode=standard、sql-mode=off、record-response-body=false。如果线上正在排查接口慢,可以临时把 sql-mode 调整为 slow,并适当降低 slow-threshold-ms;问题确认后再恢复,避免日志量过大。
本地或测试环境需要看完整 SQL 时,可以使用 mode=debug 和 sql-mode=all。这会更方便排查数据权限、字典加载、代码生成器、多表写入等问题,但不建议长期放在生产。
如果你感觉审计对性能有影响,可以先做三件事:关闭响应体记录,关闭 SQL 审计,减少自动采集方法。仍然有压力时,再将 enabled=false 或 mode=off 关闭操作审计入库。
进阶扩展位置
普通项目只需要修改 config/{profile}/audit-log.yml 中已经展示的核心项。下面这些不是当前模板里建议用户直接维护的常规 yml 参数,而是后端审计配置模型中的能力分组,主要给二开或框架扩展时定位代码用:
| 分组 | 代码位置 | 用途 |
|---|---|---|
operation | sz-common/sz-common-log/src/main/java/com/sz/logger/AuditProperties.java | 操作审计主记录模型,例如参数最大长度、响应体最大长度、字段截断长度 |
diagnostic | AuditProperties.Diagnostic、sz-module-audit 中的诊断写入逻辑 | 性能日志、异常日志等诊断明细 |
sql | AuditProperties.Sql、sz-common-db-core 的 SQL 输出配置 | SQL 输出模式、慢 SQL 阈值、完整 SQL 输出 |
access | AuditProperties.Access、sz-common-log 的访问日志切面 | HTTP 访问日志输出,不等同于操作审计入库 |
trace | AuditProperties.Trace、TraceIdFilter | traceId 请求头、响应头和 W3C traceparent 兼容 |
event | AuditProperties.Event、AuditEventDispatcher | 外部审计事件发布,方便后续扩展 Webhook、MQ、告警通知 |
如果只是调整运行策略,优先使用上面的 enabled、mode、methods、slow-threshold-ms、record-params、record-response-body、sql-mode 等核心配置。只有需要修改默认截断长度、诊断明细保存方式、TraceId 兼容策略或事件发布机制时,再进入这些代码位置二开。
页面怎么看
审计页面位于“系统管理 / 操作审计”,页面提供三个页签:审计日志、性能日志、异常日志。排查时先按问题类型选页签,再用顶部概览、快捷筛选和详情抽屉逐层缩小范围。
- 想知道谁做了什么,进入
审计日志。 - 想定位哪个接口慢,进入
性能日志。 - 想排查哪个接口失败,进入
异常日志。
顶部概览会随页签切换统计口径,例如总操作数、成功率、失败数、慢操作数或异常记录数。快捷筛选适合日常排查:全部 默认查看最近 30 天,仅失败、慢操作、今天、近7天 可以快速缩小范围。需要精确定位时,切到 自定义,再按模块、操作类型、操作人、结果、请求方法、接口路由、业务 ID、TraceId、最小耗时和操作时间组合查询。

审计日志
审计日志关注完整操作记录,适合回答“谁做了什么”。列表会把操作类型、模块、操作名称、TraceId、结果、操作人、时间、请求方法和耗时放在同一行,便于从业务动作直接定位到一次请求。
如果关键接口配置了 bizId,就可以按业务主键追踪一次授权、导出、批量删除或配置变更。接口上如果有 @SaCheckPermission,权限码也会进入审计记录,方便回看当时执行的是哪类权限动作。

点击 详情 后,先看顶部的操作类型、操作名称、结果、操作人、时间、耗时和 IP;再看基础信息里的模块、权限码、业务 ID、请求路径、TraceId、EventId、响应码和响应消息。底部的 请求参数、响应内容 支持复制,适合把一次操作的上下文带到后端日志或接口调试里继续排查。

性能日志
性能日志关注慢操作。接口耗时超过 slow-threshold-ms 后,会被标记为慢操作,进入性能日志视图。
列表优先展示耗时、接口路径、操作内容、TraceId、结果、操作人和时间,耗时列会突出慢请求。它适合排查列表查询慢、导入导出慢、数据权限 SQL 变慢、字典加载慢等问题。配合 traceId,可以继续去应用日志或 SQL 日志中找到同一次请求的细节。

性能详情会明确标记 慢操作=是,同时保留请求路径、权限码、TraceId、耗时、请求参数和响应内容。生产排障时,通常先在性能日志里确认慢接口,再用 TraceId 对照应用日志或慢 SQL 日志判断瓶颈是在业务逻辑、数据权限、字典加载还是数据库查询。

异常日志
异常日志关注失败操作。Controller 抛出异常,或 ApiResult.code 不是成功码 0000 时,会进入异常视图。
列表会展示异常摘要、接口路径、操作内容、操作人、时间和耗时。先看异常摘要可以快速区分是代码异常、业务响应失败,还是下游依赖导致的失败;再通过接口路径和操作内容判断影响的是哪个业务入口。

详情里重点看错误类型、错误消息、响应码、请求参数、异常堆栈和 TraceId。生产环境排查时,可以先在异常日志里确定失败接口,再回到业务日志中用 TraceId 串联上下文;如果同一个 TraceId 同时出现在审计日志或性能日志里,也可以把操作人、权限码、请求参数和耗时信息一起带入分析。

可选模块与关闭方式
审计模块是可选模块。不同需求可以选择不同关闭方式。
只是不想写审计数据,保留页面和依赖:
sz:
audit:
enabled: false或者:
sz:
audit:
mode: off如果只是担心性能,可以先保留操作审计主记录,降低诊断和日志成本:
sz:
audit:
mode: standard
record-params: false
record-response-body: false
sql-mode: off如果派生项目完全不需要审计,可以移除 sz-service-admin 对 sz-module-audit 的依赖,不再导入 audit-log.yml,前端 edition 不注册 auditModule,并移除审计菜单或不分配审计菜单权限。
数据存储
审计模块新增两张表:
| 表 | 说明 |
|---|---|
sys_operation_log | 操作审计主记录 |
sys_operation_log_detail | 请求参数、响应体、异常堆栈等诊断明细 |
生产环境需要结合合规要求规划保留周期。审计表增长较快时,可以按操作时间归档或清理历史数据;清理前应先备份,并保留公司要求的审计周期内数据。
注意事项
- 请求参数、响应体和异常堆栈已有脱敏与截断处理,但仍不建议记录密码、密钥、令牌、身份证等敏感字段。
record-response-body默认关闭;只有排障确实需要时再临时开启。sql-mode=all适合本地开发和测试,不适合长期用于生产。- 修改
VITE_AUDIT_API_BASE、sz.api-prefix.modules.audit.prefix或 Nginx location 时必须保持一致,否则前端审计页面会出现 404。
