SpringBoot3+Vue3 接口访问日志实战:@ApiAccessLog 慢接口、参数脱敏与 OperateLog 如何分工
一句话:操作日志回答「业务上改了什么」;访问日志回答「这次 HTTP 调了谁、花了多久、带了啥参数」------两者都要,且密码绝不能进库。

开源仓库:GitCode · RuoyiOffice|AtomGit · RuoyiOffice
为什么光有「操作日志」不够?
| 问题 | 只靠 OperateLog | 加上 ApiAccessLog |
|---|---|---|
| 接口突然变慢 | 往往无耗时字段 | duration 毫秒可排序 |
| GET 查询谁刷了敏感列表 | 常不记 | 记 URL + 用户 + IP |
| 前端报 500 对不上人 | 缺请求上下文 | trace-id + 请求参数快照 |
| 登录接口参数 | 容易把密码打进日志 | sanitizeKeys 默认抹掉 password/token |
运营后台里,访问日志列表长这样:

操作日志则更偏「业务动作」:

三类日志怎么分工?
text
一次 HTTP
├─ TraceFilter → 响应头 trace-id(串联前后)
├─ ApiAccessLogFilter → 访问日志(耗时/URL/参数/结果码)
├─ @OperateLog / 业务注解 → 操作日志(模块/动作/业务语义)
└─ GlobalExceptionHandler → 错误日志(堆栈 + 同一 traceId)
| 类型 | 粒度 | 典型字段 | 默认记不记 Body |
|---|---|---|---|
| 访问日志 | 每次 API | URL、Method、duration、resultCode、IP、UA | 请求默认记,响应默认不记 |
| 操作日志 | 业务动作 | 操作模块、操作名、业务 id | 按注解配置 |
| 错误/异常日志 | 失败路径 | 堆栈、错误码 | 按级别 |
面试口径:访问日志偏可观测与审计检索;操作日志偏合规「谁改了业务数据」。
@ApiAccessLog:注解能控什么?
java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiAccessLog {
boolean enable() default true; // 总开关
boolean requestEnable() default true; // 是否记请求参数
boolean responseEnable() default false; // 是否记响应(默认关,防爆炸)
String[] sanitizeKeys() default {}; // 额外脱敏字段
String operateModule() default ""; // 空则回退 Swagger @Tag
String operateName() default ""; // 空则回退 @Operation.summary
OperateTypeEnum[] operateType() default {};
}
用法示例:
java
@PostMapping("/update-password")
@ApiAccessLog(
operateModule = "用户中心",
operateName = "修改密码",
requestEnable = true,
sanitizeKeys = {"password", "newPassword", "oldPassword"}
)
public CommonResult<Boolean> updatePassword(@RequestBody PwdReq req) { ... }
@GetMapping("/export")
@ApiAccessLog(enable = false) // 大导出别记 Body,避免日志库被打满
public void export(...) { ... }
模块名、操作名优先注解;未填时自动吃 SpringDoc 的 @Tag / @Operation,减少重复劳动。
Filter 链路:计时 → 脱敏 → 异步落库
核心节奏(概念对齐实现):
text
beginTime = now
提前取出 query + body(避免后续 XSS Filter 改写后丢真值)
│
▼
filterChain.doFilter(...)
│
├─ 成功 → createApiAccessLog(ex=null)
└─ 异常 → createApiAccessLog(ex) 再抛出
│
▼
build:userId、resultCode、traceId、URL、duration、sanitize 后的 params
│
▼
apiAccessLogApi.createApiAccessLogAsync(...) // 异步,不拖慢主请求
默认脱敏键
全局默认抹掉:password、token、accessToken、refreshToken。
注解里的 sanitizeKeys 是追加 ,不是替换------改密接口务必把 newPassword 也写上。
请求 vs 响应
| 项 | 默认 | 原因 |
|---|---|---|
| 请求参数 | 开 | 排查「传错参」刚需,体量通常可控 |
| 响应 Body | 关 | 列表页可能上 MB,日志库先炸 |
| 需要开响应时 | responseEnable=true |
仅限小 VO 的关键写接口 |
操作类型推断
无显式 operateType 时,按 HTTP Method 映射:GET→查询、POST→创建、PUT→更新、DELETE→删除。粗分够用;精细业务仍建议注解写死。
存储字段清单(便于建表/排障)
| 字段 | 用途 |
|---|---|
| userId / userType | 谁调的 |
| requestUrl / requestMethod | 调了哪个接口 |
| requestParams | 脱敏后的 query+body |
| responseBody | 可选;默认空 |
| resultCode / resultMsg | 业务成功或失败码 |
| duration | 慢接口排序核心 |
| traceId | 与错误日志、前端 Network 对齐 |
| userIp / userAgent | 安全与终端分析 |
| beginTime / endTime | 时间窗检索 |
| operateModule / operateName | 列表可读的业务语义 |
索引建议:(begin_time)、(duration)、(user_id, begin_time)、(trace_id);按月分区防表膨胀。
TraceId:访问日志与排障的胶水
TraceFilter 把当前 traceId 写入响应头(如 trace-id)。访问日志写入同一字段后:
- 用户反馈「点保存失败」→ 从前端 Network 抄
trace-id - 访问日志按 traceId 定位 URL、耗时、结果码
- 错误日志/APM 用同一 id 拉堆栈
没有 TraceId,三张表只能靠「大概时间 + 用户 id」糊对,效率差一个数量级。
慢接口治理怎么用这张表?
| 步骤 | 做法 |
|---|---|
| 1 | 按 duration 降序,盯 Top N |
| 2 | 同 URL 聚合 P95(可离线 SQL / BI) |
| 3 | 区分「偶发慢」与「全天慢」 |
| 4 | 对照是否缺索引、N+1、同步调外部 HTTP |
| 5 | 对导出/报表接口:关访问 Body 或采样,避免日志比业务还重 |
经验阈值(可调):管理端 API > 1s 告警,> 3s 必须建优化单。
和 Vue3 前端的配合
- 统一请求封装遇到业务错误时,把响应头
trace-id打进错误提示或「复制诊断信息」。 - 勿在前端 console 打印带密码的整包 config。
- 大文件下载走 Blob 时,访问日志仍记 URL;不要对二进制开
responseEnable。
落地清单
- 生产打开访问日志异步写入
- 登录/改密/支付相关接口补全
sanitizeKeys - 大导出、文件流接口
enable=false或关 Body - 响应头透出
trace-id,网关勿剥掉 - 日志表按月分区/归档,建
(duration)、(user_id, begin_time)索引 - 与操作日志权限分开:运维看访问,业务审计看操作
FAQ
Q1:是否每个接口都要写 @ApiAccessLog?
A:可以全局 Filter 默认记录;注解用于关闭 或微调脱敏/响应。没有注解不等于不记。
Q2:异步落库失败怎么办?
A:Filter 内 catch 打 error,不影响主业务;需监控「访问日志写入失败」次数。
Q3:和网关访问日志重复?
A:网关偏流量与路由;应用内访问日志带登录用户、业务结果码、脱敏后业务参数。可并存,字段别完全重复堆两份 Body。
Q4:多租户怎么隔离?
A:落库带租户字段(或行级租户插件);查询端按租户过滤,禁止跨租户捞全站访问明细。
Q5:响应默认不记,出事怎么复盘?
A:靠结果码 + 请求参数 + 错误日志堆栈;必要时对单个接口临时打开 responseEnable 或开 Debug 采样。
和 RuoyiOffice 的对应关系
| 能力 | 位置(概念) |
|---|---|
@ApiAccessLog + Filter |
Web Starter · apilog |
| 异步写入 API | Infra 访问日志服务 |
| Trace 响应头 | Monitor · TraceFilter |
| 前端列表 | 基础设施 · API 访问日志 |
| 对照:操作日志 | Security · OperateLog |
总结
- 访问日志 管 HTTP 可观测;操作日志管业务审计------不要互相替代。
@ApiAccessLog控制开关、Body、脱敏;默认抹 password/token。- 异步落库 + duration + traceId 是慢接口与客服排障的三件套。
- 大响应、大导出要主动降噪,否则日志系统先于业务垮掉。
下一篇换业务进阶:会议室在冲突检测之后,如何用统一消息中心做会前提醒,并在改期时 cancelByBiz。
⭐ GitCode · AtomGit 点星,夏日活动攒积分。
在线体验:RuoyiOffice
商业版源码授权:联系页 · 企业微信
RuoyiOffice
关键词:SpringBoot3、ApiAccessLog、访问日志、参数脱敏、慢接口、TraceId、OperateLog、Vue3