文章目录
-
- 项目背景
- [✅ 解决方案:重写 TLog 核心类适配 Spring Boot 3.5.13](#✅ 解决方案:重写 TLog 核心类适配 Spring Boot 3.5.13)
-
- [1️⃣ 添加 TLog 依赖](#1️⃣ 添加 TLog 依赖)
- [2️⃣ 创建适配 Jakarta Servlet 的 `TLogWebCommon`](#2️⃣ 创建适配 Jakarta Servlet 的
TLogWebCommon) - [3️⃣ 创建适配 Jakarta Servlet 的 `TLogFilter`](#3️⃣ 创建适配 Jakarta Servlet 的
TLogFilter) - [4️⃣ 注册 Filter](#4️⃣ 注册 Filter)
- [5️⃣ 修改日志配置文件(Logback 示例)](#5️⃣ 修改日志配置文件(Logback 示例))
- [📝 关键配置说明](#📝 关键配置说明)
-
- [1️⃣ 日志格式中的变量](#1️⃣ 日志格式中的变量)
- [2️⃣ 可选配置(`application.yml`)](#2️⃣ 可选配置(
application.yml))
- [⚠️ 注意事项](#⚠️ 注意事项)
项目背景
在 Spring Boot 3.5.13 中直接接入 TLog 会遇到问题,因为 TLog 的最新版本(如 1.5.2)是基于 javax.servlet 包名构建的,而 Spring Boot 3.x 使用的是 jakarta.servlet 包名,两者不兼容 。
不过,这个问题已经有成熟的解决方案,可以通过重写 TLog 的核心类来适配 Jakarta EE 规范 。
✅ 解决方案:重写 TLog 核心类适配 Spring Boot 3.5.13
1️⃣ 添加 TLog 依赖
xml
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>tlog-all-spring-boot-starter</artifactId>
<version>1.5.2</version>
</dependency>
2️⃣ 创建适配 Jakarta Servlet 的 TLogWebCommon
java
package com.yourproject.tlog.adapter;
import com.yomahub.tlog.context.TLogContext;
import com.yomahub.tlog.core.rpc.TLogLabelBean;
import com.yomahub.tlog.core.rpc.TLogRPCHandler;
import com.yomahub.tlog.web.TLogWebCommon;
import jakarta.servlet.http.HttpServletRequest;
public class JakartaTLogWebCommon extends TLogRPCHandler {
private static volatile JakartaTLogWebCommon instance;
public static JakartaTLogWebCommon loadInstance() {
if (instance == null) {
synchronized (JakartaTLogWebCommon.class) {
if (instance == null) {
instance = new JakartaTLogWebCommon();
}
}
}
return instance;
}
public void preHandle(HttpServletRequest request) {
String traceId = request.getHeader(TLogWebCommon.TLOG_TRACE_KEY);
String spanId = request.getHeader(TLogWebCommon.TLOG_SPANID_KEY);
String preIvkApp = request.getHeader(TLogWebCommon.PRE_IVK_APP_KEY);
String preIvkHost = request.getHeader(TLogWebCommon.PRE_IVK_APP_HOST);
String preIp = request.getHeader(TLogWebCommon.PRE_IP_KEY);
TLogLabelBean labelBean = new TLogLabelBean(preIvkApp, preIvkHost, preIp, traceId, spanId);
processProviderSide(labelBean);
}
public void afterCompletion() {
TLogContext.remove();
}
}
3️⃣ 创建适配 Jakarta Servlet 的 TLogFilter
java
package com.yourproject.tlog.adapter;
import com.yomahub.tlog.context.TLogContext;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JakartaTLogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
JakartaTLogWebCommon.loadInstance().preHandle(httpRequest);
String traceId = TLogContext.getTraceId();
if (traceId != null) {
httpResponse.setHeader("X-Trace-Id", traceId);
}
chain.doFilter(request, response);
} finally {
JakartaTLogWebCommon.loadInstance().afterCompletion();
}
} else {
chain.doFilter(request, response);
}
}
}
4️⃣ 注册 Filter
java
package com.yourproject.config;
import com.yourproject.tlog.adapter.JakartaTLogFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@Configuration
public class TLogConfig {
@Bean
public FilterRegistrationBean<JakartaTLogFilter> tlogFilter() {
FilterRegistrationBean<JakartaTLogFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new JakartaTLogFilter());
registration.addUrlPatterns("/*");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
registration.setName("jakartaTLogFilter");
return registration;
}
}
5️⃣ 修改日志配置文件(Logback 示例)
在 logback-spring.xml 中,使用 TLog 提供的 AspectLogbackEncoder:
xml
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%X{spanId}] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
📝 关键配置说明
1️⃣ 日志格式中的变量
| 变量 | 说明 |
|---|---|
%X{traceId} |
全局链路 ID(整个请求链路唯一) |
%X{spanId} |
调用跨度 ID(标识当前调用层级) |
2️⃣ 可选配置(application.yml)
yaml
tlog:
enable-invoke-time-print: true # 打印调用耗时
⚠️ 注意事项
| 问题 | 解决方法 |
|---|---|
| TLog 与 Spring Boot 3.x 不直接兼容 | 使用上述适配类,将 javax.servlet 替换为 jakarta.servlet |
| TraceId 不显示 | 检查 logback-spring.xml 中的 encoder 是否为 AspectLogbackEncoder |
| 异步线程中 TraceId 丢失 | 使用 TLogInheritableTask 包装任务,或 TLogThreadPoolExecutor |
| Feign 调用不传递 TraceId | TLog 已内置支持 ,确保引入 tlog-all-spring-boot-starter 即可 |
按上述步骤配置后,TLog 就能在 Spring Boot 3.5.13 中正常工作了。如果还有其他问题,欢迎继续交流。