IntefaceLogRequiredAOP.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package com.yihu.iot.aop;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.google.common.collect.Lists;
  5. import com.yihu.iot.dao.gateway.GcTokenDao;
  6. import com.yihu.iot.service.platform.IotInterfaceLogService;
  7. import com.yihu.iot.service.useragent.UserAgent;
  8. import com.yihu.jw.entity.iot.gateway.GcToken;
  9. import org.apache.commons.lang.StringUtils;
  10. import org.aspectj.lang.ProceedingJoinPoint;
  11. import org.aspectj.lang.annotation.Around;
  12. import org.aspectj.lang.annotation.Aspect;
  13. import org.aspectj.lang.annotation.Pointcut;
  14. import org.aspectj.lang.reflect.MethodSignature;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.stereotype.Component;
  19. import org.springframework.web.context.request.RequestContextHolder;
  20. import org.springframework.web.context.request.ServletRequestAttributes;
  21. import org.springframework.web.multipart.MultipartFile;
  22. import javax.servlet.http.HttpServletRequest;
  23. import javax.servlet.http.HttpServletResponse;
  24. import java.lang.reflect.Method;
  25. import java.util.Enumeration;
  26. import java.util.HashMap;
  27. import java.util.List;
  28. import java.util.Map;
  29. /**
  30. * 接口调用日志记录
  31. * Created by yeshijie on 2020/06/09.
  32. */
  33. @Aspect
  34. @Component
  35. public class IntefaceLogRequiredAOP {
  36. private Logger logger = LoggerFactory.getLogger(IntefaceLogRequiredAOP.class);
  37. @Autowired
  38. private UserAgent userAgent;
  39. @Autowired
  40. private IotInterfaceLogService iotInterfaceLogService;
  41. @Autowired
  42. private GcTokenDao gcTokenDaoDao;
  43. //Controller层切点路径
  44. @Pointcut("execution(* com.yihu.iot..*.*(..))")
  45. public void controllerAspect() {
  46. }
  47. public IntefaceLogRequiredAOP() {
  48. //System.out.println("Observer---------------------------------------");
  49. }
  50. @Around("controllerAspect() && @annotation(com.yihu.iot.aop.IntefaceLogRequired)")
  51. public Object addIntefaceLog(ProceedingJoinPoint point) throws Throwable {
  52. Object o = null;
  53. HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
  54. HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
  55. String error = "";
  56. try {
  57. MethodSignature signature = (MethodSignature) point.getSignature();
  58. Method method = signature.getMethod();
  59. String params = getMethodParams(point);
  60. long start = System.currentTimeMillis();
  61. Object result = point.proceed();
  62. long end = System.currentTimeMillis();
  63. String deleteSensitiveContent = deleteSensitiveContent(result);
  64. JSONObject responseJson = JSONObject.parseObject(deleteSensitiveContent);
  65. Integer state = responseJson.getInteger("status")==200?1:0;
  66. Map<String,String> paramsMap = getMehtodParam(request);
  67. try {
  68. String appid = paramsMap.get("appId");
  69. if(StringUtils.isEmpty(appid)){
  70. //如果没有传appid,则从token中取
  71. String accesstoken = request.getHeader("accesstoken");
  72. GcToken gcToken = gcTokenDaoDao.findByToken(accesstoken);
  73. appid = gcToken.getAppid();
  74. }
  75. iotInterfaceLogService.saveLog(appid,params,deleteSensitiveContent, request,state,method.getName());
  76. }catch (Exception e){
  77. e.printStackTrace();
  78. }
  79. logger.info("结束请求方法:[{}] 参数:[{}] 返回结果[{}] 耗时:[{}]毫秒 ",
  80. method.getName(), params, deleteSensitiveContent, end - start);
  81. return result;
  82. }catch (Exception e){
  83. e.printStackTrace();
  84. //return o;
  85. }
  86. o = point.proceed();
  87. return o;
  88. }
  89. private String getMethodName(ProceedingJoinPoint joinPoint) {
  90. String methodName = joinPoint.getSignature().toShortString();
  91. String shortMethodNameSuffix = "(..)";
  92. if (methodName.endsWith(shortMethodNameSuffix)) {
  93. methodName = methodName.substring(0, methodName.length() - shortMethodNameSuffix.length());
  94. }
  95. return methodName;
  96. }
  97. private Map<String,String> getMehtodParam(HttpServletRequest request){
  98. Map<String,String> params = new HashMap<String,String>();
  99. Enumeration<String> e = request.getParameterNames();
  100. while(e.hasMoreElements()){
  101. String p = e.nextElement();
  102. if("logData".equals(p)){
  103. continue;
  104. }
  105. if("base64".equals(p)){
  106. continue;
  107. }
  108. params.put(p, request.getParameter(p));
  109. }
  110. return params;
  111. }
  112. private String getMethodParams(ProceedingJoinPoint joinPoint){
  113. Object[] arguments = joinPoint.getArgs();
  114. StringBuilder sb = new StringBuilder();
  115. if(arguments ==null || arguments.length <= 0){
  116. return sb.toString();
  117. }
  118. for (Object arg : arguments) {
  119. //移除敏感内容
  120. String paramStr;
  121. if (arg instanceof HttpServletResponse) {
  122. paramStr = HttpServletResponse.class.getSimpleName();
  123. } else if (arg instanceof HttpServletRequest) {
  124. paramStr = HttpServletRequest.class.getSimpleName();
  125. } else if (arg instanceof MultipartFile) {
  126. long size = ((MultipartFile) arg).getSize();
  127. paramStr = MultipartFile.class.getSimpleName() + " size:" + size;
  128. } else {
  129. paramStr = deleteSensitiveContent(arg);
  130. }
  131. sb.append(paramStr).append(",");
  132. }
  133. return sb.deleteCharAt(sb.length() - 1).toString();
  134. }
  135. /**
  136. * 删除参数中的敏感内容
  137. * @param obj 参数对象
  138. * @return 去除敏感内容后的参数对象
  139. */
  140. public static String deleteSensitiveContent(Object obj) {
  141. JSONObject jsonObject = new JSONObject();
  142. if (obj == null || obj instanceof Exception) {
  143. return jsonObject.toJSONString();
  144. }
  145. String param = JSON.toJSONString(obj);
  146. try {
  147. jsonObject = JSONObject.parseObject(param);
  148. }catch (Exception e) {
  149. return String.valueOf(obj);
  150. }
  151. List<String> sensitiveFieldList = getSensitiveFieldList();
  152. for (String sensitiveField : sensitiveFieldList) {
  153. if (jsonObject.containsKey(sensitiveField)) {
  154. jsonObject.put(sensitiveField, "******");
  155. }
  156. }
  157. return jsonObject.toJSONString();
  158. }
  159. /**
  160. * 敏感字段列表(当然这里你可以更改为可配置的)
  161. */
  162. private static List<String> getSensitiveFieldList() {
  163. List<String> sensitiveFieldList = Lists.newArrayList();
  164. sensitiveFieldList.add("pwd");
  165. sensitiveFieldList.add("password");
  166. return sensitiveFieldList;
  167. }
  168. }