排查接口问题时,最有价值的三条信息通常是:请求带来了什么、返回了什么、耗时多久。项目把这些信息统一放在 WebLogAspect,所有
@RestController 自动被拦截,业务代码不用手写日志。
一、切点只看 RestController
@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
public void controllerPointcut() {
}
这个范围足够克制:只记录 HTTP 入口,不拦截 Service、Mapper 等内部调用,避免一次请求产生成倍的重复日志。
二、环绕通知统一记录开始和结束
方法执行前输出 HTTP 方法、URI、目标方法、参数;执行后输出耗时和结果;异常分支输出异常消息后继续抛出,交给
GlobalExceptionHandler 处理。
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
log.info("<== cost={}ms", System.currentTimeMillis() - startTime);
return result;
计时必须包住 proceed(),如果用普通前置和后置通知,异常路径很容易漏掉失败耗时。
三、不要把请求对象序列化进日志
HttpServletRequest、HttpServletResponse、MultipartFile 被排除,只记录类型名。它们要么不适合 JSON 序列化,要么可能携带大文件和流对象。
返回值超过 2000 字符会截断,避免一个大列表把日志系统打出超高成本。
四、日志内容要有取舍
入参和出参日志在开发、测试环境很好用,生产环境要特别注意:
- 密码、token、邮箱、身份证号等字段需要脱敏。
- 大响应只保留长度或摘要即可。
- 高并发接口可以采样,而不是每条全量输出。
五、经验总结
AOP 解决的是“通用观测能力”,不是业务日志。关键业务动作仍应在 Service 层记录,例如订单创建成功、邮件发送失败原因。