Skip to content

审计日志

审计日志用于回答“谁在什么时间做了什么操作”“哪些接口耗时异常”“哪些接口失败并产生了异常信息”。它将操作审计、性能日志和异常日志串在同一个 TraceId 下,方便从页面快速定位到具体请求和业务上下文。

为了不增加用户的接入负担,审计能力在设计时复用了项目中已有的 Swagger/OpenAPI 注解。大多数业务接口只要正常维护 @Tag@Operation,审计就可以自动填充模块名称、操作名称、请求方法、操作人、接口路径、耗时和执行结果;重点场景或默认推断不满足时,再通过 @OperationAudit@OperationAuditIgnore 补充业务 ID、修正操作类型或排除无需留痕的接口。

审计模块是可选模块。默认后台已经启用,如果项目不需要审计,或担心审计写入带来额外开销,可以通过 audit-log.yml 关闭,也可以在派生项目中移除 sz-module-audit 和前端菜单入口。

低负担接入

自动填充审计信息

审计默认关注 Controller 中的业务操作。普通新增、修改、删除接口不需要额外写审计代码,只要接口本身已经有 @Tag@Operation

java
@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.ymlmethods 决定。生产环境一般只采集写操作,例如 POSTPUTDELETE。如果方法或类上有 @SaIgnore,说明它通常是公开接口,默认不会自动进入审计;确实需要记录时,可以显式加 @OperationAudit

重点场景补充 @OperationAudit

@OperationAudit 用于补足自动推断表达不了的信息,常见有三类:记录业务 ID、修正操作类型、控制参数或响应体记录。

角色授权接口虽然是 PUT,但排查时更希望按角色 ID 追踪:

java
@Operation(summary = "角色菜单配置")
@OperationAudit(operationType = OperationType.UPDATE, bizId = "#dto.roleId")
@PutMapping("/menu")
public ApiResult<Void> updateRoleMenu(@RequestBody RoleMenuUpdateDTO dto) {
    // 业务逻辑
}

脚本导出接口通常是 POST,如果不说明会被推断成新增。这里显式标记为导出,并记录导出的菜单 ID:

java
@Operation(summary = "导出菜单 SQL脚本")
@OperationAudit(operationType = OperationType.EXPORT, bizId = "#dto.ids")
@PostMapping("/script/sql/export")
public ApiResult<ScriptExportVO> exportSql(@RequestBody ScriptExportDTO dto) {
    // 业务逻辑
}

文件上传、Excel 导入这类接口可以标记为导入:

java
@Operation(summary = "上传资源文件")
@OperationAudit(operationType = OperationType.IMPORT)
@PostMapping("/upload")
public ApiResult<ResourceRef> upload(@RequestPart MultipartFile file) {
    // 业务逻辑
}

@OperationAudit 的常用参数不多:

参数什么时候用效果
operationTypeHTTP 方法不能表达业务含义时将操作标记为 IMPORTEXPORTUPDATE 等类型
bizId需要按业务主键定位时在审计记录中保存业务 ID,支持 #id#dto.id#dto.ids#p0.id
name / moduleSwagger 文案不适合审计展示时覆盖 @Operation(summary)@Tag(name)
recordParams全局不记录参数,但个别接口要留痕时当前接口强制记录脱敏、截断后的参数
responseBody全局记录响应体,但某个接口不能记录时使用 BodyRecordMode.NEVER 禁止当前接口记录响应体

操作类型支持 AUTOCREATEUPDATEDELETEQUERYIMPORTEXPORTLOGINLOGOUTOTHER。默认 AUTO 会按请求方法推断:POST 为新增,PUT/PATCH 为修改,DELETE 为删除,GET 为查询。

不想生成审计日志

如果某个业务接口不希望生成审计日志,可以在方法或类上加 @OperationAuditIgnore

java
@OperationAuditIgnore
@GetMapping("/internal/status")
public ApiResult<StatusVO> status() {
    // 高频轮询、内部状态接口等
}

这类场景通常包括高频轮询、健康检查、内部探活、无需留痕的公开接口。除此之外,@SaIgnore 标记的接口默认也不会被自动审计;methods 不包含的 HTTP 方法也不会自动审计。显式添加 @OperationAudit 时,可以把这些特殊场景重新纳入审计。

audit-log.yml 配置

审计配置位于:

text
config/{profile}/audit-log.yml

修改后需要重启服务生效。它不依赖 sys_config,这样审计能力不会被数据库、缓存等运行时配置反向影响。

推荐写法

先从这份配置理解即可。多数项目只需要关注这些核心项:

yaml
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=standardsql-mode=offrecord-response-body=false。如果线上正在排查接口慢,可以临时把 sql-mode 调整为 slow,并适当降低 slow-threshold-ms;问题确认后再恢复,避免日志量过大。

本地或测试环境需要看完整 SQL 时,可以使用 mode=debugsql-mode=all。这会更方便排查数据权限、字典加载、代码生成器、多表写入等问题,但不建议长期放在生产。

如果你感觉审计对性能有影响,可以先做三件事:关闭响应体记录,关闭 SQL 审计,减少自动采集方法。仍然有压力时,再将 enabled=falsemode=off 关闭操作审计入库。

进阶扩展位置

普通项目只需要修改 config/{profile}/audit-log.yml 中已经展示的核心项。下面这些不是当前模板里建议用户直接维护的常规 yml 参数,而是后端审计配置模型中的能力分组,主要给二开或框架扩展时定位代码用:

分组代码位置用途
operationsz-common/sz-common-log/src/main/java/com/sz/logger/AuditProperties.java操作审计主记录模型,例如参数最大长度、响应体最大长度、字段截断长度
diagnosticAuditProperties.Diagnosticsz-module-audit 中的诊断写入逻辑性能日志、异常日志等诊断明细
sqlAuditProperties.Sqlsz-common-db-core 的 SQL 输出配置SQL 输出模式、慢 SQL 阈值、完整 SQL 输出
accessAuditProperties.Accesssz-common-log 的访问日志切面HTTP 访问日志输出,不等同于操作审计入库
traceAuditProperties.TraceTraceIdFiltertraceId 请求头、响应头和 W3C traceparent 兼容
eventAuditProperties.EventAuditEventDispatcher外部审计事件发布,方便后续扩展 Webhook、MQ、告警通知

如果只是调整运行策略,优先使用上面的 enabledmodemethodsslow-threshold-msrecord-paramsrecord-response-bodysql-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 同时出现在审计日志或性能日志里,也可以把操作人、权限码、请求参数和耗时信息一起带入分析。

异常日志详情

可选模块与关闭方式

审计模块是可选模块。不同需求可以选择不同关闭方式。

只是不想写审计数据,保留页面和依赖:

yaml
sz:
  audit:
    enabled: false

或者:

yaml
sz:
  audit:
    mode: off

如果只是担心性能,可以先保留操作审计主记录,降低诊断和日志成本:

yaml
sz:
  audit:
    mode: standard
    record-params: false
    record-response-body: false
    sql-mode: off

如果派生项目完全不需要审计,可以移除 sz-service-adminsz-module-audit 的依赖,不再导入 audit-log.yml,前端 edition 不注册 auditModule,并移除审计菜单或不分配审计菜单权限。

数据存储

审计模块新增两张表:

说明
sys_operation_log操作审计主记录
sys_operation_log_detail请求参数、响应体、异常堆栈等诊断明细

生产环境需要结合合规要求规划保留周期。审计表增长较快时,可以按操作时间归档或清理历史数据;清理前应先备份,并保留公司要求的审计周期内数据。

注意事项

  1. 请求参数、响应体和异常堆栈已有脱敏与截断处理,但仍不建议记录密码、密钥、令牌、身份证等敏感字段。
  2. record-response-body 默认关闭;只有排障确实需要时再临时开启。
  3. sql-mode=all 适合本地开发和测试,不适合长期用于生产。
  4. 修改 VITE_AUDIT_API_BASEsz.api-prefix.modules.audit.prefix 或 Nginx location 时必须保持一致,否则前端审计页面会出现 404。