项目中对请求接口打印日志踩坑

数据准备

定义一个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 串起来。

posted @ 2025-07-04 20:13  strongmore  阅读(13)  评论(0)    收藏  举报