需求
把接口的入参出参打印出来
代码
因为只是需要接口的入参出参,所以我们拦截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的过程,从同事身上学到了很多有用的知识和技巧,也接触了很多好玩的东西,对于一些项目启动初期的支持性建设,比如异常管理和拦截,接口访问控制,日志等都有了一些新的理解,还是挺有收获的。