SGTY 5 tháng trước cách đây
mục cha
commit
b092325712

+ 13 - 1
common/pom.xml

@@ -6,7 +6,7 @@
 
 	<groupId>com.diagbot</groupId>
 	<artifactId>common</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
+	<version>0.0.1.1-SNAPSHOT</version>
 	<packaging>jar</packaging>
 
 	<name>common</name>
@@ -115,6 +115,18 @@
 			<artifactId>aspectjweaver</artifactId>
 			<version>1.9.5</version>
 		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-autoconfigure</artifactId>
+			<version>2.1.7.RELEASE</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>io.github.openfeign</groupId>
+			<artifactId>feign-core</artifactId>
+			<version>10.4.0</version>
+			<scope>provided</scope>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 41 - 0
common/src/main/java/com/diagbot/MonitorAutoConfiguration.java

@@ -0,0 +1,41 @@
+package com.diagbot;
+
+
+import com.diagbot.annotation.EnableMonitor;
+import com.diagbot.aop.InterfaceLogAspect;
+import com.diagbot.interceptor.CustomInterceptor;
+import com.diagbot.interceptor.FeignRequestInterceptor;
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+@ConditionalOnBean(annotation = { EnableMonitor.class})
+public class MonitorAutoConfiguration implements WebMvcConfigurer {
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(new CustomInterceptor())
+                .addPathPatterns("/**").excludePathPatterns("/static/**", "/css/**", "/js/**"); // 排除静态资源
+    }
+
+    @Bean
+    @Lazy
+    public InterfaceLogAspect interfaceLogAspect() {
+        return new InterfaceLogAspect();
+    }
+
+    @Bean
+    @Lazy
+    @ConditionalOnClass({
+        RequestInterceptor.class, RequestTemplate.class})
+    public FeignRequestInterceptor feignRequestInterceptor() {
+        return new FeignRequestInterceptor();
+    }
+}

+ 21 - 0
common/src/main/java/com/diagbot/annotation/EnableMonitor.java

@@ -0,0 +1,21 @@
+package com.diagbot.annotation;
+
+import org.springframework.cache.annotation.EnableCaching;
+
+import java.lang.annotation.*;
+
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@EnableCaching
+public @interface EnableMonitor {
+
+    String pointcut();
+
+    /**
+     * 统计接口耗时
+     * @return
+     */
+    //boolean stopWatch() default false;
+}

+ 64 - 0
common/src/main/java/com/diagbot/aop/InterfaceLogAspect.java

@@ -0,0 +1,64 @@
+package com.diagbot.aop;
+
+import com.diagbot.util.ObjectsUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StopWatch;
+
+import java.lang.reflect.Parameter;
+import java.util.HashMap;
+import java.util.Map;
+
+@Aspect
+@Slf4j
+@Order(999)
+public class InterfaceLogAspect {
+
+    @Around("(execution(public * com.diagbot.web..*(..)) || execution(public * com.diagbot.facade..*(..)) ||" +
+            "execution(public * com.diagbot.service..*(..)) || execution(public * com.diagbot.mapper..*(..)) " +
+            "|| execution(public * com.diagbot.client..*(..)) " +
+            "|| execution(public * com.diagbot.util..*(..)) " +
+            "|| execution(public * com.diagbot.aop..*(..)) " +
+            ") || (execution(public * com.lantone.qc.kernel..*(..)) && !execution(public * com.lantone.qc.kernel..config..*(..))) ")
+    public Object interfaceAround(ProceedingJoinPoint joinPoint) throws Throwable {
+        String classSimpleName = joinPoint.getSignature().getDeclaringType().getSimpleName();
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Parameter[] argNames = signature.getMethod().getParameters();
+        String methodName = classSimpleName + "#" + joinPoint.getSignature().getName();
+
+        Object retVal = null;
+        StopWatch clock = new StopWatch();
+        clock.start();
+        logLargeText("request:"+methodName+","+ObjectsUtil.argsToString(joinPoint.getArgs()));
+        try {
+            retVal = joinPoint.proceed(joinPoint.getArgs());
+        } finally {
+            clock.stop();
+            //超过10s的请求
+            if(clock.getTotalTimeMillis()>10000) {
+                log.error("{} -- {} ms", methodName, clock.getTotalTimeMillis());
+            }
+        }
+        logLargeText("response:"+methodName+","+ObjectsUtil.objectToString(retVal));
+        return retVal;
+    }
+
+    static final int chunkSize = 1500; // 每块字符数
+    public void logLargeText(String largeText) {
+        log.info(largeText);
+        /* if(largeText.length()<chunkSize){
+            log.info(largeText);
+            return;
+        }
+
+        for (int i = 0; i < largeText.length(); i += chunkSize) {
+            int end = Math.min(i + chunkSize, largeText.length());
+            log.info("Chunk: {}", largeText.substring(i, end));
+        }*/
+    }
+}

+ 27 - 0
common/src/main/java/com/diagbot/interceptor/CustomInterceptor.java

@@ -0,0 +1,27 @@
+package com.diagbot.interceptor;
+
+import com.diagbot.util.TraceIdUtil;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+public class CustomInterceptor implements HandlerInterceptor {
+ 
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        TraceIdUtil.initTraceId(request);
+        response.addHeader(TraceIdUtil.TRACE_ID_KEY,TraceIdUtil.getTraceId());
+        return true;
+    }
+ 
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+        // 处理请求处理完视图渲染之前的逻辑
+
+    }
+ 
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+    }
+}

+ 12 - 0
common/src/main/java/com/diagbot/interceptor/FeignRequestInterceptor.java

@@ -0,0 +1,12 @@
+package com.diagbot.interceptor;
+
+import com.diagbot.util.TraceIdUtil;
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+
+public class FeignRequestInterceptor implements RequestInterceptor {
+    @Override
+    public void apply(RequestTemplate template) {
+        template.header(TraceIdUtil.TRACE_ID_KEY, TraceIdUtil.getTraceId());
+    }
+}

+ 50 - 0
common/src/main/java/com/diagbot/util/ObjectsUtil.java

@@ -0,0 +1,50 @@
+package com.diagbot.util;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.commons.lang3.ArrayUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @Author: 刘一刀
+ * @Description: 
+ * @Date: 17:41 2022/3/16
+ */
+public class ObjectsUtil {
+
+    public static String argsToString(Object[] args) {
+        StringBuilder sb = new StringBuilder();
+        if (ArrayUtils.isNotEmpty(args)) {
+            for (int i = 0; i < args.length; i++) {
+                if(i>0){
+                    sb.append(",");
+                }
+                sb.append(objectToString(args[i]));
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String objectToString(Object o) {
+        if (Objects.isNull(o)) {
+            return "null";
+        }
+        try {
+            String s = "";
+            if(o instanceof HttpServletRequest){
+                HttpServletRequest httpServletRequest = (HttpServletRequest) o;
+                Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
+                if(parameterMap!=null && parameterMap.size()>0) {
+                    s = JSON.toJSONString(parameterMap);
+                }
+            }else {
+                return JSON.toJSONString(o);
+            }
+        } catch (Exception e) {
+            return o.toString();
+        }
+        return "";
+    }
+}

+ 90 - 0
common/src/main/java/com/diagbot/util/TraceIdUtil.java

@@ -0,0 +1,90 @@
+package com.diagbot.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.MDC;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class TraceIdUtil {
+
+    public static final String TRACE_ID_KEY = "Trace-Id";
+
+    public static final String TRACE_ID_VALUE_DEFAULT = "000000";
+
+    public static void setTraceId(String traceId) {
+        //如果参数为空,则设置默认traceId
+        //将traceId放到MDC中
+        MDC.put(TRACE_ID_KEY, traceId);
+    }
+
+    public static String getTraceId() {
+        String traceId = MDC.get(TRACE_ID_KEY);
+
+        return StringUtils.isNotBlank(traceId) ? traceId : TRACE_ID_VALUE_DEFAULT;
+    }
+
+    /**
+     * generate traceId: https://help.aliyun.com/document_detail/151840.html
+     */
+    public static String genTraceId()  {
+
+        try {
+            StringBuilder sb = new StringBuilder();
+            InetAddress addr = InetAddress.getLocalHost();
+            if (null == addr) {
+                return TRACE_ID_VALUE_DEFAULT;
+            }
+            String addrStr = addr.getHostAddress();
+            if (null == addrStr) {
+                return TRACE_ID_VALUE_DEFAULT;
+            }
+            String[] addrArr = addrStr.split("\\.");
+            if (addrArr.length != 4) {
+                return TRACE_ID_VALUE_DEFAULT;
+            }
+
+            sb.append(StringUtils.leftPad(Integer.toHexString(Integer.valueOf(addrArr[0]))  , 2, "0"))
+                    .append(StringUtils.leftPad(Integer.toHexString(Integer.valueOf(addrArr[1]))  , 2, "0"))
+                    .append(StringUtils.leftPad(Integer.toHexString(Integer.valueOf(addrArr[2]))  , 2, "0"))
+                    .append(StringUtils.leftPad(Integer.toHexString(Integer.valueOf(addrArr[3]))  , 2, "0"))
+                    .append(System.currentTimeMillis())
+                    .append(ThreadLocalRandom.current().nextInt(1000, 10000))
+                    .append(getCurrentPID());
+
+            return sb.toString();
+        } catch (Exception e) {
+            return TRACE_ID_VALUE_DEFAULT;
+        }
+    }
+
+    public static String getCurrentPID() {
+        try {
+            // 获取当前进程的PID(通过调用系统命令)
+            String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
+            return processName.split("@")[0];
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return ThreadLocalRandom.current().nextInt(10000, 100000)+"";
+    }
+
+    public static void initTraceId(HttpServletRequest request) {
+        String traceId = "";
+        if (request != null) {
+            //get traceId from request
+            traceId = request.getHeader(TraceIdUtil.TRACE_ID_KEY);
+        }
+        //generate new traceId
+        if (StringUtils.isBlank(traceId) || TRACE_ID_VALUE_DEFAULT.equals(traceId)){
+            traceId = TraceIdUtil.genTraceId();
+        }
+
+        TraceIdUtil.setTraceId(traceId);
+    }
+
+    public static void main(String[] args) {
+        System.out.println(TraceIdUtil.genTraceId());
+    }
+}

+ 2 - 0
common/src/resources/META-INF/spring.factories

@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.diagbot.MonitorAutoConfiguration