Spring Boot 3 tlog 适配

文章目录

    • 项目背景
    • [✅ 解决方案:重写 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 中正常工作了。如果还有其他问题,欢迎继续交流。

相关推荐
Hui Baby2 分钟前
Spring Security
java·后端·spring
leoZ23114 分钟前
Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践
vue.js·spring boot·架构
IT笔记33 分钟前
【Rust】Rust Match 模式匹配详解
java·开发语言·rust
逝水无殇1 小时前
C# 运算符重载详解
开发语言·后端·c#
我才是银古1 小时前
构建 Java GIS 工具库:从碎片化 API 到统一抽象的设计实践
java·gis·geotools·gdal·esri
苏三说技术1 小时前
2026编程圈很火的10个Skills
后端
TPBoreas1 小时前
配置信息防泄露方案:.env 环境隔离详解(dotenv-java)
java·开发语言
用户8356290780511 小时前
使用 Python 自动化 Excel 公式和函数:完整指南
后端·python
敲代码的嘎仔2 小时前
实习日志day6--实习日志day6--title命名规范化&businessType纠正&补充缺失的@Log注解&报警与通信模块补充&产出阶段总结文档
java·开发语言·人工智能·git·python·实习·大二
编程(变成)小辣鸡2 小时前
Spring事务失效场景
java·后端·spring