1 package com.example.aspect;
2
3 import com.google.common.collect.Maps;
4 import org.apache.commons.lang3.ArrayUtils;
5 import org.apache.commons.lang3.builder.ToStringBuilder;
6 import org.apache.commons.lang3.builder.ToStringStyle;
7 import org.aspectj.lang.ProceedingJoinPoint;
8 import org.aspectj.lang.annotation.*;
9 import org.aspectj.lang.reflect.MethodSignature;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 import org.springframework.stereotype.Component;
13 import org.springframework.web.multipart.MultipartFile;
14
15 import java.lang.reflect.Method;
16 import java.sql.Time;
17 import java.sql.Timestamp;
18 import java.util.*;
19
20 /**
21 * 日志切面
22 *
23 * @author mingtian
24 */
25 @Aspect
26 @Component
27 public class WorkFlowLogAspect {
28
29 /**
30 * 打印日志
31 */
32 private final Logger logger = LoggerFactory.getLogger(WorkFlowLogAspect.class);
33
34 private static MapprimitiveMap = Maps.newHashMap();
35
36 static {
37 primitiveMap.put(Boolean.class, Boolean.TYPE);
38 primitiveMap.put(Byte.class, Byte.TYPE);
39 primitiveMap.put(Character.class, Character.TYPE);
40 primitiveMap.put(Short.class, Short.TYPE);
41 primitiveMap.put(Integer.class, Integer.TYPE);
42 primitiveMap.put(Long.class, Long.TYPE);
43 primitiveMap.put(Float.class, Float.TYPE);
44 primitiveMap.put(Double.class, Double.TYPE);
45 primitiveMap.put(String.class, String.class);
46 primitiveMap.put(Calendar.class, Calendar.class);
47 primitiveMap.put(Date.class, Date.class);
48 primitiveMap.put(java.sql.Date.class, java.sql.Date.class);
49 primitiveMap.put(Timestamp.class, Timestamp.class);
50 primitiveMap.put(Time.class, Time.class);
51 }
52
53
54 /**
55 * 日志处理
56 *
57 * @param joinPoint
58 * @return
59 * @throws Throwable
60 */
61 @Around(value = "execution(* com.example.web.controller..*(..))" + " || execution(* com.example.service..*(..))")
62 public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
63 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
64 Method method = methodSignature.getMethod();
65 String fullMethodName = joinPoint.getTarget().getClass().getName() + "." + method.getName();
66 Object[] args = joinPoint.getArgs();
67
68 Object result = null;
69 long startTime = Calendar.getInstance().getTimeInMillis();
70 logger.info(">>>>>>>>>>>>>>> access method:{} params:{}", fullMethodName, appendArgs(methodSignature, args));
71 try {
72 result = joinPoint.proceed(args);
73 long endTime = Calendar.getInstance().getTimeInMillis();
74 logger.info("<<<<<<<<<<<<<< success method:{} 耗时:{}毫秒", fullMethodName, (endTime - startTime));
75 return result;
76 } catch (Throwable e) {
77 long endTime = Calendar.getInstance().getTimeInMillis();
78 logger.error("<<<<<<<<<<<<<< error method:{} 耗时:{}毫秒", fullMethodName, (endTime - startTime), e);
79 throw e;
80 }
81 }
82
83
84 private String appendArgs(MethodSignature methodSignature, Object[] args) {
85 StringBuilder stringBuilder = new StringBuilder();
86 String[] parameterNames = methodSignature.getParameterNames();
87 Class[] classes = methodSignature.getParameterTypes();
88 if (ArrayUtils.isEmpty(parameterNames)) {
89 return stringBuilder.toString();
90 }
91 int size = Math.min(ArrayUtils.getLength(parameterNames), ArrayUtils.getLength(args));
92 stringBuilder.append("{");
93 for (int i = 0; i < size; i++) {
94 if (isFile(classes[i])) {
95 continue;
96 }
97 stringBuilder.append(parameterNames[i]).append("=");
98 if (args[i] != null) {
99 if (isPrimitive(args[i].getClass())) {
100 stringBuilder.append(args[i]);
101 } else {
102 if (List.class.isAssignableFrom(classes[i])) {
103 List tempCollection = (List) args[i];
104 Object[] tempArray = tempCollection.toArray();
105 stringBuilder.append(ToStringBuilder.reflectionToString(tempArray, ToStringStyle.SHORT_PREFIX_STYLE));
106 } else {
107 stringBuilder.append(ToStringBuilder.reflectionToString(args[i], ToStringStyle.SHORT_PREFIX_STYLE));
108 }
109 }
110 } else {
111 stringBuilder.append("null");
112 }
113 if (i != size - 1) {
114 stringBuilder.append(",");
115 }
116 }
117 stringBuilder.append("}");
118 return stringBuilder.toString();
119 }
120
121 /**
122 * 对于包装类 String类型 日期类型 以及number的子类型
123 *
124 * @param clazz
125 * @return
126 */
127 private boolean isPrimitive(Class clazz) {
128 if (clazz.isPrimitive() || primitiveMap.containsKey(clazz)) {
129 return true;
130 }
131 if (Number.class.isAssignableFrom(clazz)) {
132 return true;
133 }
134 return false;
135 }
136
137 /**
138 * 文件上传字段不打印
139 *
140 * @param clazz
141 * @return
142 */
143 private boolean isFile(Class clazz) {
144 if (MultipartFile.class.isAssignableFrom(clazz)) {
145 return true;
146 }
147 if ((clazz.isArray()) && (MultipartFile.class.isAssignableFrom(clazz.getComponentType()))) {
148 return true;
149 }
150 return false;
151 }
152
153 }