Преглед изворни кода

add [重磅更新] 增加分布式日志框架 TLog

疯狂的狮子li пре 3 година
родитељ
комит
cbb0c98f98

+ 1 - 0
README.md

@@ -33,6 +33,7 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼
 | 分布式限流 | Redisson | [Redisson文档](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 全局、请求IP、集群ID 多种限流 |
 | 分布式锁 | Lock4j | [Lock4j官网](https://gitee.com/baomidou/lock4j) | 注解锁、工具锁 多种多样 |
 | 分布式幂等 | Lock4j | [Lock4j文档](https://gitee.com/baomidou/lock4j) | 基于分布式锁实现 |
+| 分布式日志 | TLog | [TLog文档](https://yomahub.com/tlog/docs) | 支持跟踪链路日志记录、性能分析、链路排查 |
 | 文件存储 | Minio | [Minio文档](https://docs.min.io/) | 本地存储 |
 | 文件存储 | 七牛、阿里、腾讯 | [OSS使用文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4359146&doc_id=1469725) | 云存储 |
 | 监控框架 | SpringBoot-Admin | [SpringBoot-Admin文档](https://codecentric.github.io/spring-boot-admin/current/) | 全方位服务监控 |

+ 30 - 0
pom.xml

@@ -36,6 +36,7 @@
         <redisson.version>3.16.3</redisson.version>
         <lock4j.version>2.2.1</lock4j.version>
         <dynamic-ds.version>3.4.1</dynamic-ds.version>
+        <tlog.version>1.3.2</tlog.version>
 
         <!-- jdk11 缺失依赖 jaxb-->
         <jaxb.version>3.0.1</jaxb.version>
@@ -204,6 +205,35 @@
                 <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
                 <version>${lock4j.version}</version>
             </dependency>
+
+            <dependency>
+                <groupId>com.yomahub</groupId>
+                <artifactId>tlog-spring-boot-configuration</artifactId>
+                <version>${tlog.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.yomahub</groupId>
+                <artifactId>tlog-webroot</artifactId>
+                <version>${tlog.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>javassist</artifactId>
+                        <groupId>org.javassist</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>guava</artifactId>
+                        <groupId>com.google.guava</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <dependency>
+                <groupId>com.yomahub</groupId>
+                <artifactId>tlog-feign</artifactId>
+                <version>${tlog.version}</version>
+            </dependency>
+
             <!-- 定时任务-->
             <dependency>
                 <groupId>com.ruoyi</groupId>

+ 4 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -59,6 +59,10 @@ logging:
     org.springframework: warn
   config: classpath:logback.xml
 
+# tlog 全局访问性能拦截
+tlog:
+  enable-invoke-time-print: true
+
 # Spring配置
 spring:
   application:

+ 5 - 5
ruoyi-admin/src/main/resources/logback.xml

@@ -7,7 +7,7 @@
 
 	<!-- 控制台输出 -->
 	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
-		<encoder>
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
 			<pattern>${console.log.pattern}</pattern>
             <charset>utf-8</charset>
 		</encoder>
@@ -22,7 +22,7 @@
             <!-- 日志最大 1天 -->
             <maxHistory>1</maxHistory>
         </rollingPolicy>
-        <encoder>
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
             <pattern>${log.pattern}</pattern>
             <charset>utf-8</charset>
         </encoder>
@@ -42,7 +42,7 @@
 			<!-- 日志最大的历史 60天 -->
 			<maxHistory>60</maxHistory>
 		</rollingPolicy>
-		<encoder>
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
 			<pattern>${log.pattern}</pattern>
 		</encoder>
 		<filter class="ch.qos.logback.classic.filter.LevelFilter">
@@ -64,7 +64,7 @@
 			<!-- 日志最大的历史 60天 -->
 			<maxHistory>60</maxHistory>
         </rollingPolicy>
-        <encoder>
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
             <pattern>${log.pattern}</pattern>
         </encoder>
         <filter class="ch.qos.logback.classic.filter.LevelFilter">
@@ -86,7 +86,7 @@
             <!-- 日志最大的历史 60天 -->
             <maxHistory>60</maxHistory>
         </rollingPolicy>
-        <encoder>
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
             <pattern>${log.pattern}</pattern>
         </encoder>
     </appender>

+ 15 - 0
ruoyi-common/pom.xml

@@ -156,6 +156,21 @@
             <groupId>com.baomidou</groupId>
             <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>com.yomahub</groupId>
+            <artifactId>tlog-spring-boot-configuration</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.yomahub</groupId>
+            <artifactId>tlog-webroot</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.yomahub</groupId>
+            <artifactId>tlog-feign</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 85 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/Interceptor/PlusWebInvokeTimeInterceptor.java

@@ -0,0 +1,85 @@
+package com.ruoyi.framework.Interceptor;
+
+import cn.hutool.core.map.MapUtil;
+import com.alibaba.ttl.TransmittableThreadLocal;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.yomahub.tlog.context.TLogContext;
+import com.yomahub.tlog.web.interceptor.AbsTLogWebHandlerMethodInterceptor;
+import com.yomahub.tlog.web.wrapper.RequestWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.StopWatch;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * 重写Tlog web的调用时间统计拦截器
+ *
+ * @author Lion Li
+ * @since 3.3.0
+ */
+@Slf4j
+public class PlusWebInvokeTimeInterceptor extends AbsTLogWebHandlerMethodInterceptor {
+
+    private final TransmittableThreadLocal<StopWatch> invokeTimeTL = new TransmittableThreadLocal<>();
+
+    @Override
+    public boolean preHandleByHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        if (TLogContext.enableInvokeTimePrint()) {
+            String url = request.getMethod() + " " + request.getRequestURI();
+
+            // 打印请求参数
+            if (isJsonRequest(request)) {
+                    String jsonParam = new RequestWrapper(request).getBodyString();
+                    log.info("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
+            } else {
+                Map<String, String[]> parameterMap = request.getParameterMap();
+                if (MapUtil.isNotEmpty(parameterMap)) {
+                    String parameters = JsonUtils.toJsonString(parameterMap);
+                    log.info("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
+                } else {
+                    log.info("[PLUS]开始请求 => URL[{}],无参数", url);
+                }
+            }
+
+            StopWatch stopWatch = new StopWatch();
+            invokeTimeTL.set(stopWatch);
+            stopWatch.start();
+        }
+        return true;
+    }
+
+    @Override
+    public void postHandleByHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+
+    }
+
+    @Override
+    public void afterCompletionByHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        if (TLogContext.enableInvokeTimePrint()) {
+            StopWatch stopWatch = invokeTimeTL.get();
+            stopWatch.stop();
+            log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
+            invokeTimeTL.remove();
+        }
+    }
+
+    /**
+     * 判断本次请求的数据类型是否为json
+     *
+     * @param request request
+     * @return boolean
+     */
+    private boolean isJsonRequest(HttpServletRequest request) {
+        String contentType = request.getContentType();
+        if (contentType != null) {
+            return StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE);
+        }
+        return false;
+    }
+
+}

+ 11 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java

@@ -1,10 +1,13 @@
 package com.ruoyi.framework.config;
 
+import com.ruoyi.framework.Interceptor.PlusWebInvokeTimeInterceptor;
+import com.yomahub.tlog.web.interceptor.TLogWebInterceptor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
@@ -20,6 +23,14 @@ public class ResourcesConfig implements WebMvcConfigurer {
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
     }
 
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 全局链路跟踪拦截器
+        registry.addInterceptor(new TLogWebInterceptor());
+        // 全局访问性能拦截
+        registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
+    }
+
     /**
      * 跨域配置
      */

+ 49 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java

@@ -0,0 +1,49 @@
+package com.ruoyi.framework.config;
+
+import com.yomahub.tlog.core.aop.AspectLogAop;
+import com.yomahub.tlog.feign.filter.TLogFeignFilter;
+import com.yomahub.tlog.spring.TLogPropertyInit;
+import com.yomahub.tlog.spring.TLogSpringAware;
+import com.yomahub.tlog.springboot.property.TLogProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.core.annotation.Order;
+
+/**
+ * 整合 TLog 框架配置
+ *
+ * @author Lion Li
+ * @since 3.3.0
+ */
+@Order(-999)
+@Configuration
+@Import(TLogProperty.class)
+public class TLogConfig {
+
+    @Bean
+    public TLogPropertyInit tLogPropertyInit(TLogProperty tLogProperty) {
+        TLogPropertyInit tLogPropertyInit = new TLogPropertyInit();
+        tLogPropertyInit.setPattern(tLogProperty.getPattern());
+        tLogPropertyInit.setEnableInvokeTimePrint(tLogProperty.enableInvokeTimePrint());
+        tLogPropertyInit.setIdGenerator(tLogProperty.getIdGenerator());
+        tLogPropertyInit.setMdcEnable(tLogProperty.getMdcEnable());
+        return tLogPropertyInit;
+    }
+
+    @Bean
+    public TLogSpringAware tLogSpringAware(){
+        return new TLogSpringAware();
+    }
+
+    @Bean
+    public AspectLogAop aspectLogAop() {
+        return new AspectLogAop();
+    }
+
+    @Bean
+    public TLogFeignFilter tLogFeignFilter() {
+        return new TLogFeignFilter();
+    }
+
+}