项目中对请求接口打印日志踩坑
数据准备
定义一个AOP拦截器来打印日志,在接口执行完和执行抛异常时都会打印
@Slf4j
@Aspect
@Component
public class ApiLogAspect {
@Around("@annotation(com.imooc.ApiLog)")
public Object doAround(ProceedingJoinPoint joinPoint) {
long startTime = System.currentTimeMillis();
Object[] httpReqParams = joinPoint.getArgs();
Object httpResp = null;
HttpServletRequest request = null;
try {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
request = attributes.getRequest();
httpResp = joinPoint.proceed(joinPoint.getArgs());
return httpResp;
} catch (Throwable e) {
Object httpReq = httpReqParams[0];
if (!(httpReq instanceof String)) {
httpReq = JSON.toJSONString(httpReq);
}
httpResp = new BaseResponse(Version.VERSION_1, ApiStatusCode.STATUS_CODE_500);
log.error("fullUrl:{} url:{} request:{} ",
RequestUtils.getUrl(request), request.getRequestURI(), httpReq, e);
return httpResp;
} finally {
if (!(httpResp instanceof String)) {
httpResp = JSON.toJSONString(httpResp);
}
Object httpReq = httpReqParams[0];
if (!(httpReq instanceof String)) {
httpReq = JSON.toJSONString(httpReq);
}
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
log.info("startTime:{} endTime:{} duration:{} fullUrl:{} url:{} userAgent:{} " +
"requestIp:{} realIp:{} request:{} response:{}",
startTime,
endTime,
duration,
RequestUtils.getUrl(request),
request.getRequestURI(),
RequestUtils.getUserAgent(request),
RequestUtils.getRequestIp(request),
RequestUtils.getRemoteAddr(request),
httpReq,
httpResp);
}
}
}
定义一个接口
@RestController
@RequestMapping("/api")
@Slf4j
public class HealthController {
@GetMapping("/health")
public String health(@RequestBody TestVO testVO) {
testVO.setAddress("测试地址");
return "success";
}
@Data
public static class TestVO {
private String ip;
private String address;
}
}
问题描述
以上述代码为例,在接口执行完打印日志,但是接口执行过程中修改了请求参数,导致实际打印的日志已经不是原始的请求报文了,影响后续排查问题。
解决方法
拆分为两个日志,接口执行前和接口执行后都打印日志,通过 trackingNo 串起来。

浙公网安备 33010602011771号