feat(log): 添加traceId

This commit is contained in:
黄斌峰
2026-08-10 07:31:46 +08:00
parent 667bf66489
commit 2a1b90c6cb
10 changed files with 81 additions and 16 deletions
@@ -25,10 +25,12 @@
*/
package org.springblade.core.cloud.feign;
import org.slf4j.MDC;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.core.tool.utils.ThreadLocalUtil;
import org.springframework.http.HttpHeaders;
@@ -57,6 +59,13 @@ public class BladeFeignRequestInterceptor implements RequestInterceptor {
values.forEach(value -> requestTemplate.header(key, value))
);
}
if (!requestTemplate.headers().containsKey(BladeConstant.TRACE_ID_HEADER)) {
// 不包含traceId请求头,且traceId不为空,则添加
String traceId = MDC.get(BladeConstant.MDC_TRACE_ID_KEY);
if (StringUtil.isNotBlank(traceId)) {
requestTemplate.header(BladeConstant.TRACE_ID_HEADER, traceId);
}
}
// 如果是 API Key 认证则跳过设置
if (AuthUtil.isApiKeyRequest()) {
return;
@@ -25,6 +25,7 @@
*/
package org.springblade.core.context;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springblade.core.tool.utils.ThreadLocalUtil;
import org.springframework.lang.Nullable;
@@ -37,6 +38,7 @@ import java.util.concurrent.Callable;
*
* @author L.cm
*/
@Slf4j
public class BladeCallableWrapper<V> implements Callable<V> {
private final Callable<V> delegate;
private final Map<String, Object> tlMap;
@@ -62,6 +64,9 @@ public class BladeCallableWrapper<V> implements Callable<V> {
}
try {
return delegate.call();
} catch (Exception e) {
log.error("异步任务执行异常", e);
throw e;
} finally {
tlMap.clear();
if (mdcMap != null) {
@@ -25,6 +25,7 @@
*/
package org.springblade.core.context;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springblade.core.tool.utils.ThreadLocalUtil;
import org.springframework.lang.Nullable;
@@ -36,6 +37,7 @@ import java.util.Map;
*
* @author L.cm
*/
@Slf4j
public class BladeRunnableWrapper implements Runnable {
private final Runnable delegate;
private final Map<String, Object> tlMap;
@@ -61,6 +63,9 @@ public class BladeRunnableWrapper implements Runnable {
}
try {
delegate.run();
} catch (Exception e) {
log.error("异步任务执行异常", e);
throw e;
} finally {
tlMap.clear();
if (mdcMap != null) {
@@ -171,4 +171,18 @@ public interface BladeConstant {
*/
String DEFAULT_UNAUTHORIZED_MESSAGE = "签名认证失败";
/**
* mdc trace id key
*/
String MDC_TRACE_ID_KEY = "traceId";
/**
* trace id header
*/
String TRACE_ID_HEADER = "bs-trace-id";
/**
* 默认线程池名称
*/
String DEFAULT_THREAD_EXECUTOR_NAME = "dtpExecutor1";
}
@@ -30,6 +30,7 @@ import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springblade.core.log.utils.LogTraceUtil;
import org.springblade.core.tool.utils.StringUtil;
/**
* 为异步方法添加traceId
@@ -45,11 +46,17 @@ public class LogTraceAspect {
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
boolean clean = false;
try {
if (StringUtil.isBlank(LogTraceUtil.getTraceIdFromMDC())) {
LogTraceUtil.insert();
clean = true;
}
return point.proceed();
} finally {
if (clean) {
LogTraceUtil.remove();
}
}
}
}
@@ -25,9 +25,13 @@
*/
package org.springblade.core.log.filter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springblade.core.log.utils.LogTraceUtil;
import jakarta.servlet.*;
import org.springblade.core.tool.constant.BladeConstant;
import java.io.IOException;
/**
@@ -43,15 +47,20 @@ public class LogTraceFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
boolean flag = LogTraceUtil.insert();
String traceId = null;
if (request instanceof HttpServletRequest httpServletRequest) {
traceId = httpServletRequest.getHeader(BladeConstant.TRACE_ID_HEADER);
}
traceId = LogTraceUtil.insert(traceId);
try {
if (response instanceof HttpServletResponse httpServletResponse) {
httpServletResponse.addHeader(BladeConstant.TRACE_ID_HEADER, traceId);
}
chain.doFilter(request, response);
} finally {
if (flag) {
LogTraceUtil.remove();
}
}
}
@Override
public void destroy() {
@@ -26,6 +26,7 @@
package org.springblade.core.log.utils;
import org.slf4j.MDC;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.StringUtil;
/**
@@ -34,7 +35,6 @@ import org.springblade.core.tool.utils.StringUtil;
* @author Chill
*/
public class LogTraceUtil {
private static final String UNIQUE_ID = "traceId";
/**
* 获取日志追踪id格式
@@ -43,23 +43,39 @@ public class LogTraceUtil {
return StringUtil.randomUUID();
}
/**
* 从mdc获取日志追踪id
* @return
*/
public static String getTraceIdFromMDC() {
return MDC.get(BladeConstant.MDC_TRACE_ID_KEY);
}
/**
* 插入traceId
*/
public static boolean insert() {
MDC.put(UNIQUE_ID, getTraceId());
return true;
public static String insert() {
return LogTraceUtil.insert(null);
}
/**
* 移除traceId
*/
public static boolean remove() {
MDC.remove(UNIQUE_ID);
MDC.remove(BladeConstant.MDC_TRACE_ID_KEY);
return true;
}
public static String getTraceIdFromMDC() {
return MDC.get(UNIQUE_ID);
/**
* 插入traceId
* @param traceId
* @return
*/
public static String insert(String traceId) {
if (traceId == null) {
traceId = getTraceId();
}
MDC.put(BladeConstant.MDC_TRACE_ID_KEY, traceId);
return traceId;
}
}
@@ -10,7 +10,7 @@
<conversionRule conversionWord="wEx" class="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr([%X{traceId:-N/A}]){yellow} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
@@ -10,7 +10,7 @@
<conversionRule conversionWord="wEx" class="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr([%X{traceId:-N/A}]){yellow} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
@@ -10,7 +10,7 @@
<conversionRule conversionWord="wEx" class="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr([%X{traceId:-N/A}]){yellow} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">