|
@@ -0,0 +1,181 @@
|
|
|
|
|
+package com.uas.ps.httplog.intercept;
|
|
|
|
|
+
|
|
|
|
|
+import com.uas.ps.core.util.CollectionUtils;
|
|
|
|
|
+import com.uas.ps.core.util.IpHelper;
|
|
|
|
|
+import com.uas.ps.core.util.StringUtils;
|
|
|
|
|
+import com.uas.ps.httplog.annotation.HttpLog;
|
|
|
|
|
+import org.aspectj.lang.JoinPoint;
|
|
|
|
|
+import org.aspectj.lang.annotation.*;
|
|
|
|
|
+import org.aspectj.lang.reflect.MethodSignature;
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
+import org.springframework.web.context.request.RequestContextHolder;
|
|
|
|
|
+import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
|
|
+
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
+import java.lang.reflect.Method;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * listen http request using AOP
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author sunyj
|
|
|
|
|
+ * @since 2018/2/5 10:17
|
|
|
|
|
+ */
|
|
|
|
|
+@Aspect
|
|
|
|
|
+public class HttpLogIntercept {
|
|
|
|
|
+
|
|
|
|
|
+ private Logger logger = LoggerFactory.getLogger(getClass());
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * trace id
|
|
|
|
|
+ */
|
|
|
|
|
+ private ThreadLocal<String> traceIdThreadLocal = new ThreadLocal<>();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * request time
|
|
|
|
|
+ */
|
|
|
|
|
+ private ThreadLocal<Long> requestTimeThreadLocal = new ThreadLocal<>();
|
|
|
|
|
+
|
|
|
|
|
+ @Pointcut("@annotation(com.uas.ps.httplog.annotation.HttpLog) " +
|
|
|
|
|
+ "&& (@annotation(org.springframework.web.bind.annotation.RequestMapping)" +
|
|
|
|
|
+ "|| @annotation(org.springframework.web.bind.annotation.GetMapping)" +
|
|
|
|
|
+ "|| @annotation(org.springframework.web.bind.annotation.PostMapping)" +
|
|
|
|
|
+ "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)" +
|
|
|
|
|
+ "|| @annotation(org.springframework.web.bind.annotation.PutMapping)" +
|
|
|
|
|
+ "|| @annotation(org.springframework.web.bind.annotation.PatchMapping))")
|
|
|
|
|
+ public void log() {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Before("log()")
|
|
|
|
|
+ public void beforeRequest(JoinPoint joinPoint) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ HttpLog httpLog = getAnnotation(joinPoint);
|
|
|
|
|
+ if (httpLog == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ HttpServletRequest request = getRequest();
|
|
|
|
|
+ // assign one uuid to this request
|
|
|
|
|
+ traceIdThreadLocal.set(UUID.randomUUID().toString());
|
|
|
|
|
+ requestTimeThreadLocal.set(System.currentTimeMillis());
|
|
|
|
|
+
|
|
|
|
|
+ // print trace id, requested url, source ip
|
|
|
|
|
+ StringBuilder message = new StringBuilder();
|
|
|
|
|
+ message.append("Request... ")
|
|
|
|
|
+ .append("traceId:").append(traceIdThreadLocal.get())
|
|
|
|
|
+ .append(", url:").append(getRequestPath(request))
|
|
|
|
|
+ .append(", method:").append(request.getMethod())
|
|
|
|
|
+ .append(", ip:").append(IpHelper.getIp(request));
|
|
|
|
|
+
|
|
|
|
|
+ // print request parameters excluding the specified
|
|
|
|
|
+ List<String> exclude = httpLog.exclude().length > 0 ? Arrays.asList(httpLog.exclude()) : new ArrayList<String>();
|
|
|
|
|
+ if (!CollectionUtils.isEmpty(request.getParameterMap())) {
|
|
|
|
|
+ message.append(", params:{");
|
|
|
|
|
+ Set<Map.Entry<String, String[]>> entries = request.getParameterMap().entrySet();
|
|
|
|
|
+ for (Map.Entry<String, String[]> entry : entries) {
|
|
|
|
|
+ String key = entry.getKey();
|
|
|
|
|
+ if (!exclude.contains(key))
|
|
|
|
|
+ if (!message.toString().endsWith(", params:{")) {
|
|
|
|
|
+ message.append(", ");
|
|
|
|
|
+ }
|
|
|
|
|
+ message.append(key).append("=").append(toString(entry.getValue()));
|
|
|
|
|
+ }
|
|
|
|
|
+ message.append("}");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // print specified headers
|
|
|
|
|
+ List<String> includeHeaders = httpLog.includeHeaders().length < 1 ? new ArrayList<String>() : Arrays.asList(httpLog.includeHeaders());
|
|
|
|
|
+ if (includeHeaders.size() > 0) {
|
|
|
|
|
+ message.append(", headers:{");
|
|
|
|
|
+ for (String includeHeader : includeHeaders) {
|
|
|
|
|
+ if (!message.toString().endsWith(", headers:{")) {
|
|
|
|
|
+ message.append(", ");
|
|
|
|
|
+ }
|
|
|
|
|
+ message.append(includeHeader).append("=").append(request.getHeader(includeHeader));
|
|
|
|
|
+ }
|
|
|
|
|
+ message.append("}");
|
|
|
|
|
+ }
|
|
|
|
|
+ logger.info(message.toString());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ logger.error("Failed to print http log", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @AfterReturning(pointcut = "log()", returning = "result")
|
|
|
|
|
+ public void afterRequest(JoinPoint joinPoint, Object result) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ HttpLog httpLog = getAnnotation(joinPoint);
|
|
|
|
|
+ if (httpLog != null) {
|
|
|
|
|
+ // print trace id, time spent, result
|
|
|
|
|
+ StringBuilder message = new StringBuilder();
|
|
|
|
|
+ message.append("Result... ")
|
|
|
|
|
+ .append("traceId:").append(traceIdThreadLocal.get())
|
|
|
|
|
+ .append(", spent:").append(System.currentTimeMillis() - requestTimeThreadLocal.get()).append("ms");
|
|
|
|
|
+ if (!httpLog.excludeResult()) {
|
|
|
|
|
+ message.append(", result:").append(result);
|
|
|
|
|
+ }
|
|
|
|
|
+ logger.info(message.toString());
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ logger.error("Failed to print http log", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @AfterThrowing(pointcut = "log()", throwing = "exception")
|
|
|
|
|
+ public void afterRequest(JoinPoint joinPoint, Exception exception) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ HttpLog httpLog = getAnnotation(joinPoint);
|
|
|
|
|
+ if (httpLog != null) {
|
|
|
|
|
+ // print trace id, time spent, exception
|
|
|
|
|
+ StringBuilder message = new StringBuilder();
|
|
|
|
|
+ message.append("Result... ")
|
|
|
|
|
+ .append("traceId:").append(traceIdThreadLocal.get())
|
|
|
|
|
+ .append(", spent:").append(System.currentTimeMillis() - requestTimeThreadLocal.get()).append("ms");
|
|
|
|
|
+ if (httpLog.printStackTrace()) {
|
|
|
|
|
+ logger.error(message.toString(), exception);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ message.append("\n").append(exception.toString());
|
|
|
|
|
+ logger.error(message.toString());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ logger.error("Failed to print http log", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * get HttpLog annotation
|
|
|
|
|
+ */
|
|
|
|
|
+ private HttpLog getAnnotation(JoinPoint joinPoint) {
|
|
|
|
|
+ MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
|
|
|
|
+ Method method = methodSignature.getMethod();
|
|
|
|
|
+ return method.getAnnotation(HttpLog.class);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * get HttpServletRequest
|
|
|
|
|
+ */
|
|
|
|
|
+ private HttpServletRequest getRequest() {
|
|
|
|
|
+ return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * get requested path
|
|
|
|
|
+ */
|
|
|
|
|
+ private String getRequestPath(HttpServletRequest request) {
|
|
|
|
|
+ return !StringUtils.isEmpty(request.getServletPath()) ? request.getServletPath() : request.getPathInfo();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * convert an array to str
|
|
|
|
|
+ */
|
|
|
|
|
+ private String toString(Object[] array) {
|
|
|
|
|
+ if (array == null || array.length == 0) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ } else if (array.length == 1) {
|
|
|
|
|
+ return String.valueOf(array[0]);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return Arrays.toString(array);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|