Browse Source

feat: 添加日志

xdd 2 weeks ago
parent
commit
5e5d200015

+ 43 - 0
fs-admin/src/main/java/com/fs/core/config/LogInterceptor.java

@@ -0,0 +1,43 @@
+package com.fs.core.config;
+
+
+
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.UUID;
+
+
+/**
+ * @description: 日志拦截器
+ * @author: xdd
+ * @date: 2025/3/13
+ */
+@Component
+public class LogInterceptor implements HandlerInterceptor {
+
+    private static final String traceId = "traceId";
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+        String tid = UUID.randomUUID().toString().replace("-", "");
+        //可以考虑让客户端传入链路ID,但需保证一定的复杂度唯一性;如果没使用默认UUID自动生成
+        if (!StringUtils.isEmpty(request.getHeader("traceId"))) {
+            tid = request.getHeader("traceId");
+        }
+        MDC.put(traceId, tid);
+        return true;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
+                                Exception ex) {
+        // 请求处理完成后,清除MDC中的traceId,以免造成内存泄漏
+        MDC.remove(traceId);
+    }
+
+}

+ 35 - 0
fs-admin/src/main/java/com/fs/core/config/MyThreadPoolTaskExecutor.java

@@ -0,0 +1,35 @@
+package com.fs.core.config;
+
+import com.fs.core.util.ThreadMdcUtil;
+import org.slf4j.MDC;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+/**
+ * @description:
+ * @author: xdd
+ * @date: 2025/3/13
+ */
+public final class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
+    public MyThreadPoolTaskExecutor() {
+        super();
+    }
+
+    @Override
+    public void execute(Runnable task) {
+        super.execute(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
+    }
+
+
+    @Override
+    public <T> Future<T> submit(Callable<T> task) {
+        return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
+    }
+
+    @Override
+    public Future<?> submit(Runnable task) {
+        return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
+    }
+}

+ 9 - 3
fs-admin/src/main/java/com/fs/core/config/ResourcesConfig.java

@@ -15,7 +15,7 @@ import com.fs.core.interceptor.RepeatSubmitInterceptor;
 
 /**
  * 通用配置
- * 
+ *
 
  */
 @Configuration
@@ -24,6 +24,9 @@ public class ResourcesConfig implements WebMvcConfigurer
     @Autowired
     private RepeatSubmitInterceptor repeatSubmitInterceptor;
 
+    @Autowired
+    private LogInterceptor logInterceptor;
+
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry)
     {
@@ -41,7 +44,10 @@ public class ResourcesConfig implements WebMvcConfigurer
     @Override
     public void addInterceptors(InterceptorRegistry registry)
     {
-        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
+        registry.addInterceptor(repeatSubmitInterceptor)
+                .addPathPatterns("/**");
+        registry.addInterceptor(logInterceptor)
+                .addPathPatterns("/**");
     }
 
     /**
@@ -63,4 +69,4 @@ public class ResourcesConfig implements WebMvcConfigurer
         source.registerCorsConfiguration("/**", config);
         return new CorsFilter(source);
     }
-}
+}

+ 1 - 1
fs-admin/src/main/java/com/fs/core/config/ThreadPoolConfig.java

@@ -32,7 +32,7 @@ public class ThreadPoolConfig
     @Bean(name = "threadPoolTaskExecutor")
     public ThreadPoolTaskExecutor threadPoolTaskExecutor()
     {
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        ThreadPoolTaskExecutor executor = new MyThreadPoolTaskExecutor();
         executor.setMaxPoolSize(maxPoolSize);
         executor.setCorePoolSize(corePoolSize);
         executor.setQueueCapacity(queueCapacity);

+ 79 - 0
fs-admin/src/main/java/com/fs/core/util/ThreadMdcUtil.java

@@ -0,0 +1,79 @@
+package com.fs.core.util;
+
+/**
+ * @description:
+ * @author: xdd
+ * @date: 2025/3/13
+ * @Description:
+ */
+
+import org.slf4j.MDC;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+
+/**
+ * @Description:
+ */
+public final class ThreadMdcUtil {
+    private static final String traceId = "traceId";
+
+    // 获取唯一性标识
+    public static String generateTraceId() {
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+
+    public static void setTraceIdIfAbsent() {
+        if (MDC.get(traceId) == null) {
+            MDC.put(traceId, generateTraceId());
+        }
+    }
+
+    /**
+     * 用于父线程向线程池中提交任务时,将自身MDC中的数据复制给子线程
+     *
+     * @param callable
+     * @param context
+     * @param <T>
+     * @return
+     */
+    public static<T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
+        return () -> {
+            if (context == null) {
+                MDC.clear();
+            } else {
+                MDC.setContextMap(context);
+            }
+            setTraceIdIfAbsent();
+            try {
+                return callable.call();
+            } finally {
+                MDC.clear();
+            }
+        };
+    }
+
+    /**
+     * 用于父线程向线程池中提交任务时,将自身MDC中的数据复制给子线程
+     *
+     * @param runnable
+     * @param context
+     * @return
+     */
+    public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
+        return () -> {
+            if (context == null) {
+                MDC.clear();
+            } else {
+                MDC.setContextMap(context);
+            }
+            setTraceIdIfAbsent();
+            try {
+                runnable.run();
+            } finally {
+                MDC.clear();
+            }
+        };
+    }
+}

+ 43 - 0
fs-user-app/src/main/java/com/fs/core/config/LogInterceptor.java

@@ -0,0 +1,43 @@
+package com.fs.core.config;
+
+
+
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.UUID;
+
+
+/**
+ * @description: 日志拦截器
+ * @author: xdd
+ * @date: 2025/3/13
+ */
+@Component
+public class LogInterceptor implements HandlerInterceptor {
+
+    private static final String traceId = "traceId";
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+        String tid = UUID.randomUUID().toString().replace("-", "");
+        //可以考虑让客户端传入链路ID,但需保证一定的复杂度唯一性;如果没使用默认UUID自动生成
+        if (!StringUtils.isEmpty(request.getHeader("traceId"))) {
+            tid = request.getHeader("traceId");
+        }
+        MDC.put(traceId, tid);
+        return true;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
+                                Exception ex) {
+        // 请求处理完成后,清除MDC中的traceId,以免造成内存泄漏
+        MDC.remove(traceId);
+    }
+
+}

+ 35 - 0
fs-user-app/src/main/java/com/fs/core/config/MyThreadPoolTaskExecutor.java

@@ -0,0 +1,35 @@
+package com.fs.core.config;
+
+import com.fs.core.util.ThreadMdcUtil;
+import org.slf4j.MDC;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+/**
+ * @description:
+ * @author: xdd
+ * @date: 2025/3/13
+ */
+public final class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
+    public MyThreadPoolTaskExecutor() {
+        super();
+    }
+
+    @Override
+    public void execute(Runnable task) {
+        super.execute(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
+    }
+
+
+    @Override
+    public <T> Future<T> submit(Callable<T> task) {
+        return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
+    }
+
+    @Override
+    public Future<?> submit(Runnable task) {
+        return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
+    }
+}

+ 7 - 2
fs-user-app/src/main/java/com/fs/core/config/ResourcesConfig.java

@@ -15,7 +15,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 /**
  * 通用配置
- * 
+ *
 
  */
 @Configuration
@@ -24,6 +24,9 @@ public class ResourcesConfig implements WebMvcConfigurer
     @Autowired
     private RepeatSubmitInterceptor repeatSubmitInterceptor;
 
+    @Autowired
+    private LogInterceptor logInterceptor;
+
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry)
     {
@@ -42,6 +45,8 @@ public class ResourcesConfig implements WebMvcConfigurer
     public void addInterceptors(InterceptorRegistry registry)
     {
         registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
+        registry.addInterceptor(logInterceptor)
+                .addPathPatterns("/**");
     }
 
     /**
@@ -63,4 +68,4 @@ public class ResourcesConfig implements WebMvcConfigurer
         source.registerCorsConfiguration("/**", config);
         return new CorsFilter(source);
     }
-}
+}

+ 2 - 2
fs-user-app/src/main/java/com/fs/core/config/ThreadPoolConfig.java

@@ -13,7 +13,7 @@ import java.util.concurrent.ThreadPoolExecutor;
 /**
  * 线程池配置
  *
- 
+
  **/
 @Configuration
 public class ThreadPoolConfig
@@ -33,7 +33,7 @@ public class ThreadPoolConfig
     @Bean(name = "threadPoolTaskExecutor")
     public ThreadPoolTaskExecutor threadPoolTaskExecutor()
     {
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        ThreadPoolTaskExecutor executor = new MyThreadPoolTaskExecutor();
         executor.setMaxPoolSize(maxPoolSize);
         executor.setCorePoolSize(corePoolSize);
         executor.setQueueCapacity(queueCapacity);

+ 79 - 0
fs-user-app/src/main/java/com/fs/core/util/ThreadMdcUtil.java

@@ -0,0 +1,79 @@
+package com.fs.core.util;
+
+/**
+ * @description:
+ * @author: xdd
+ * @date: 2025/3/13
+ * @Description:
+ */
+
+import org.slf4j.MDC;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+
+/**
+ * @Description:
+ */
+public final class ThreadMdcUtil {
+    private static final String traceId = "traceId";
+
+    // 获取唯一性标识
+    public static String generateTraceId() {
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+
+    public static void setTraceIdIfAbsent() {
+        if (MDC.get(traceId) == null) {
+            MDC.put(traceId, generateTraceId());
+        }
+    }
+
+    /**
+     * 用于父线程向线程池中提交任务时,将自身MDC中的数据复制给子线程
+     *
+     * @param callable
+     * @param context
+     * @param <T>
+     * @return
+     */
+    public static<T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
+        return () -> {
+            if (context == null) {
+                MDC.clear();
+            } else {
+                MDC.setContextMap(context);
+            }
+            setTraceIdIfAbsent();
+            try {
+                return callable.call();
+            } finally {
+                MDC.clear();
+            }
+        };
+    }
+
+    /**
+     * 用于父线程向线程池中提交任务时,将自身MDC中的数据复制给子线程
+     *
+     * @param runnable
+     * @param context
+     * @return
+     */
+    public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
+        return () -> {
+            if (context == null) {
+                MDC.clear();
+            } else {
+                MDC.setContextMap(context);
+            }
+            setTraceIdIfAbsent();
+            try {
+                runnable.run();
+            } finally {
+                MDC.clear();
+            }
+        };
+    }
+}