背景:
鉴于日常开发过程中,很多排查问题的情况下,需要二次操作业务流程进行入参的获取,实际操作起来增加排查问题的处理时间,为了提高效率,可以通过Aop实现接口入参以及返回的日志打印,方便快速解决问题。
上代码:
@Aspect
@Component
@Slf4j
public class LogAspect {
//用来记录请求进入的时间,防止多线程时出错,这里用了ThreadLocal
ThreadLocal<Long> startTime = new ThreadLocal<>();
/**
* 定义切入点
*/
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework" +
".web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping) ")
public void requestLog() {
}
/**
* 方法之前执行,日志打印请求信息
*
* @param joinPoint joinPoint
*/
@Before("requestLog()")
public void doBefore(JoinPoint joinPoint) {
startTime.set(System.currentTimeMillis());
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
Object[] args = joinPoint.getArgs();
Object[] params = new Object[args.length];
for (int i = 0; i< args.length;i++) {
if (!(args[i] instanceof HttpServletRequest) && !(args[i] instanceof HttpServletResponse) && !(args[i] instanceof MultipartFile)) {
params[i]=args[i];
}
}
//打印当前的请求路径,请求参数,如果需要打印其他的信息可以到request中去拿
log.info("【请求参数】:{} ,RequestParam:{}", request.getRequestURI(), JSON.toJSON(params));
}
/**
* 方法返回之前执行,打印才返回值以及方法消耗时间
*
* @param response 返回值
*/
@AfterReturning(returning = "response", pointcut = "requestLog()")
public void doAfterRunning(Object response) {
//打印返回值信息
log.info("【响应返回】:{} ", JSON.toJSON(response));
//打印请求耗时
log.info("【本次请求响应时间】: [{}ms]", System.currentTimeMillis() - startTime.get());
}
}