效果

SpringBOot-AOP抽取全局日志输入--获取入参的key和value,出参,异常 - 图1

测试的方法

SpringBOot-AOP抽取全局日志输入--获取入参的key和value,出参,异常 - 图2

入参有各种类型的

自定义类注解

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. /**
  6. * @类说明: feign调用日志AOP处理
  7. * @Author: 张俊杰 2020年09月05日 14:06
  8. */
  9. @Target(ElementType.TYPE)
  10. @Retention(RetentionPolicy.RUNTIME)
  11. public @interface FeignLogOutput {
  12. public String value() default "";
  13. }

切面类

  1. /**
  2. * @类说明: 用于拦截feign请求的日志切面类.
  3. * @Author: 张俊杰 2020年09月05日 14:11
  4. */
  5. @Aspect
  6. @Configuration
  7. public class FeignlLogAspect {
  8. private static final Logger logger = LoggerFactory.getLogger(FeignLogOutput.class);
  9. //切点
  10. @Pointcut("@within(com.datangwealth.um.common.aop.annotation.FeignLogOutput)")
  11. public void pointCut() {
  12. }
  13. @Around("pointCut()")
  14. public Object interceptMethodAround(ProceedingJoinPoint pjd) {
  15. Object result = null;
  16. Signature signature = pjd.getSignature();
  17. String methodName = signature.getName();
  18. String className = signature.getDeclaringTypeName();
  19. String methodNameAndClassName = className + "#" + methodName;
  20. Object[] args = pjd.getArgs(); //获取参数值数组
  21. // 获取参数名字数组
  22. String[] paramNames = ((CodeSignature) pjd.getSignature()).getParameterNames();
  23. //进行循环拼接
  24. StringJoiner stringJoiner = new StringJoiner(" ");
  25. for (int i = 0; i < paramNames.length; i++) {
  26. int count = i + 1;
  27. stringJoiner.add("\r\n参数" + count + ": " + paramNames[i] + "--->" + args[i]);
  28. }
  29. try {
  30. //开始入参写入......
  31. logger.info(" {}方法远程调用入参{}", methodNameAndClassName, stringJoiner.toString());
  32. result = pjd.proceed();
  33. // 正常情况下方法出参在下面代码里面写...
  34. this.resultTypeTransition(result, methodNameAndClassName);
  35. } catch (Throwable e) {
  36. // 方法异常走这里
  37. logger.error("{}方法远程调用异常 ", methodNameAndClassName);
  38. e.printStackTrace();
  39. }
  40. return result;
  41. }
  42. /**
  43. * @功能描述: 结果参数类型转换
  44. * @Author: 张俊杰 2020年09月05日 18:04
  45. */
  46. private void resultTypeTransition(Object result, String methodNameAndClassName) {
  47. if (result instanceof List) {
  48. List<Object> objects = (List) result;
  49. logger.info("{}方法远程调用出参,返回列表长度为:{} ", methodNameAndClassName, objects.size());
  50. } else if (result instanceof String) {
  51. String objects = (String) result;
  52. logger.info("{}方法远程调用出参,返回参数为:{} ", methodNameAndClassName, objects);
  53. } else if (result instanceof Result) {
  54. Result objects = (Result) result;
  55. logger.info("{}方法远程调用出参,返回code为:{} ,返回的message为{}",
  56. methodNameAndClassName, objects.getCode(), objects.getMessage());
  57. } else {
  58. logger.info("{}方法远程调用出参,返回为:{} ", methodNameAndClassName, result.toString());
  59. }
  60. }