LogAspect.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package com.steerinfo.dil.aspect;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.steerinfo.dil.annotaion.LogAround;
  5. import com.steerinfo.dil.mapper.LogResultMapper;
  6. import com.steerinfo.dil.model.LogResult;
  7. import com.steerinfo.dil.util.DataChange;
  8. import com.steerinfo.framework.controller.RESTfulResult;
  9. import lombok.extern.java.Log;
  10. import org.apache.log4j.Logger;
  11. import org.aspectj.lang.ProceedingJoinPoint;
  12. import org.aspectj.lang.Signature;
  13. import org.aspectj.lang.annotation.Around;
  14. import org.aspectj.lang.annotation.Aspect;
  15. import org.aspectj.lang.annotation.Pointcut;
  16. import org.aspectj.lang.reflect.MethodSignature;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.beans.factory.annotation.Value;
  19. import org.springframework.stereotype.Component;
  20. import java.lang.reflect.Method;
  21. import java.text.DateFormat;
  22. import java.text.SimpleDateFormat;
  23. import java.util.*;
  24. /**
  25. * 日志 Aspect切面,编写切入点的方法
  26. */
  27. @Aspect
  28. @Component
  29. public class LogAspect {
  30. @Value("${prefix.logPrefix}")
  31. private String logPrefix;
  32. @Autowired
  33. LogResultMapper logResultMapper;
  34. static final Logger log = Logger.getLogger(LogAspect.class);
  35. private DateFormat format =new SimpleDateFormat("yyyy-MM-dd");
  36. /**
  37. * 定义切入点,所有该注解为切入点
  38. */
  39. @Pointcut("@annotation(com.steerinfo.dil.annotaion.LogAround)")
  40. public void AroundPointCut(){}
  41. /**
  42. * 环绕通知 @Around,日志文件同时记录方法的入参出参,数据库只保留成功的出参
  43. * @param point
  44. * @return
  45. *
  46. * @throws Throwable
  47. */
  48. @Around("AroundPointCut()")
  49. public Object around(ProceedingJoinPoint point) throws Throwable {
  50. //获取该切点处的方法及入参
  51. Method method = ((MethodSignature) point.getSignature()).getMethod();
  52. Object[] requestParams = point.getArgs();
  53. JSONObject map = null ;
  54. for(Object param:requestParams){
  55. if(param!=null && param instanceof Map){
  56. map = JSONObject.parseObject(JSONObject.toJSONString(param));
  57. break;
  58. }
  59. }
  60. if(map==null || map.get("userId")==null ||map.get("userName") ==null){
  61. log.error("缺乏日志必要参数"+map);
  62. return new RESTfulResult("500","缺乏日志必要参数"+map,"缺乏日志必要参数"+map);
  63. }
  64. //获取切点处的注解及其参数
  65. LogAround logAround = method.getAnnotation(LogAround.class);
  66. String[] foreignKeys = logAround.foreignKeys();
  67. String[] foreignKeyTypes = logAround.foreignKeyTypes();
  68. String description = logAround.description();
  69. //获取方法签名
  70. Signature signature = point.getSignature();
  71. String methodName = method.getName();
  72. log.info("执行===" + methodName + "===开始");
  73. log.info("方法描述:" + description);
  74. log.info("方法名:" + signature);
  75. log.info("方法参数:" + map);
  76. //记录当前时间
  77. Date beginTime = new Date();
  78. //执行方法,并取得返回值
  79. Object response = null;
  80. try{
  81. response = point.proceed();
  82. }catch (Exception e){
  83. //记录错误日志
  84. log.error("执行===" + methodName + "===异常:"+ e.getClass().getName());
  85. log.error("方法描述:" + description);
  86. log.error("方法名:" + signature);
  87. log.error("方法参数:" + requestParams);
  88. throw e;
  89. }
  90. //解析返回值,记录日志
  91. try{
  92. RESTfulResult result = JSONObject.parseObject(JSONObject.toJSONString(response),RESTfulResult.class);
  93. //获取执行时间
  94. long exeCost = System.currentTimeMillis() - beginTime.getTime();
  95. if(RESTfulResult.SUCCEED.equals(result.getStatus())){
  96. //执行成功,记录正常日志
  97. log.info("方法返回:" + JSON.toJSONString(result));
  98. log.info("执行时间(ms):"+exeCost);
  99. log.info("执行===" + methodName + "===成功");
  100. try{
  101. //data数组
  102. List<Map<String,Object>> datas = new ArrayList<>();
  103. //记录到数据库
  104. List<LogResult> logResults=new ArrayList<>();
  105. //检查返回data类型
  106. if(result.getData() instanceof Map){
  107. Map<String,Object> data =(Map) result.getData();
  108. datas.add(data);
  109. }else if(result.getData() instanceof List){
  110. datas =(List) result.getData();
  111. }else{
  112. throw new Exception("无法处理的数据类型!");
  113. }
  114. //批量处理
  115. for(Map<String,Object> data : datas){
  116. for(int i=0 ; i<foreignKeys.length ; i++){
  117. if(data.get(foreignKeys[i]) != null){
  118. LogResult logResult=new LogResult();
  119. logResult.setLogId(logResultMapper.nextId());
  120. logResult.setForeignKeyId(DataChange.dataToBigDecimal(data.get(foreignKeys[i])));
  121. logResult.setForeignKeyType(foreignKeyTypes[i]);
  122. logResult.setLogContent(map.get("userName")+":"+result.getMessage());
  123. logResult.setMethodName(""+signature);
  124. logResult.setMethodDescription(description);
  125. logResult.setInsertTime(beginTime);
  126. logResult.setExeCost(DataChange.dataToBigDecimal(exeCost));
  127. logResult.setFilePath(logPrefix+format.format(beginTime));
  128. logResult.setInsertUsername(""+map.get("userId"));
  129. logResult.setRemark("自动记录");
  130. logResults.add(logResult);
  131. }
  132. }
  133. }
  134. if(logResults.size() > 0){
  135. logResultMapper.batchInsert(logResults);
  136. }else{
  137. throw new Exception("目标foreignKey不存在!");
  138. }
  139. }catch (Exception e){
  140. log.info("记录日志失败:"+e.getMessage());
  141. }
  142. }else{
  143. //记录失败日志
  144. log.info("方法返回:" + JSON.toJSONString(result));
  145. log.info("执行时间(ms):"+exeCost);
  146. log.info("执行===" + methodName + "===失败");
  147. }
  148. }catch (Exception e){
  149. //记录错误日志
  150. log.error("===日志解析、记录失败===:\n"+ e.getMessage());
  151. }
  152. return response;
  153. }
  154. }