需求
把接口的入参出参打印出来
代码
因为只是需要接口的入参出参,所以我们拦截controller文件夹就可以。
@Component @Aspect @Slf4j public class MethodLogAspect { @Around("execution(public * com.test.log.controller..*.*(..))") public Object doAuthMethodInterrupt(ProceedingJoinPoint point) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String methodName = point.getSignature().getName(); String userId = request.getHeader(HeaderParamKeyEunm.USER_ID.getValue()); // 入参 Object[] paramArr = point.getArgs(); //序列化时过滤掉request和response List<Object> logArgs = streamOf(paramArr) .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse ))) .collect(Collectors.toList()); // 入参打印 String reqId = System.currentTimeMillis() + "-" + DingCallbackCrypto.Utils.getRandomStr(6); ThreadContext.setReqId(reqId); log.info(">>>>>>>>>>>> ReqId:{} ***** Method:{} ***** UserId:{} ***** Param:{}" , reqId, methodName, userId, JSONObject.toJSONString(logArgs)); try { long currentTimeStampBegin = System.currentTimeMillis(); Object obj = point.proceed(); long diff = System.currentTimeMillis() - currentTimeStampBegin; // 出参打印 log.info("<<<<<<<<<<<< ReqId:{} ***** Response:{} ***** Diff:{}ms", reqId, JSONObject.toJSONString(obj), diff); return obj; } catch (Throwable e) { log.error("<<<<<<<<<<<< ReqId:{},REQUEST_ERROR_MSG:{}", reqId, e.getMessage()); // throw new RuntimeException(e); e.printStackTrace(); return Result.SYSTEM_ERROR(); } } public static <T> Stream<T> streamOf(T[] array) { return ArrayUtils.isEmpty(array) ? Stream.empty() : Arrays.stream(array); }
总结
这种打日志的方式是去年新学的,面试的时候经常会被问到IOC,AOP,但是自己实际上没有真的去用过,或者说用了也感觉不是非常的有感触,去年的时候可能是因为频繁的启动新项目,所有有了很多从0到1的过程,从同事身上学到了很多有用的知识和技巧,也接触了很多好玩的东西,对于一些项目启动初期的支持性建设,比如异常管理和拦截,接口访问控制,日志等都有了一些新的理解,还是挺有收获的。