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 中正常工作了。如果还有其他问题,欢迎继续交流。

相关推荐
弹简特2 分钟前
【Java项目-轻聊】01-项目演示+项目介绍+准备工作+项目源码
java
luck_bor18 分钟前
File类&递归作业
java·开发语言
武子康37 分钟前
Java-07 深入浅出 MyBatis数据库一对多关系模型实战:表结构设计与查询实现
java·后端
花椒技术1 小时前
企业内部 Agent 落地复盘:Gateway、Skill 和二次确认如何串起受控业务执行
后端·agent·ai编程
REDcker3 小时前
Linux OverlayFS详解
java·linux·运维
Royzst3 小时前
xml知识点
java·服务器·前端
我是一颗柠檬3 小时前
【MySQL全面教学】MySQL事务与ACID Day9(2026年)
数据库·后端·mysql
枕星而眠3 小时前
数据结构八大排序详解(一):四大简单排序
c语言·数据结构·c++·后端
IT_陈寒3 小时前
React useEffect闭包陷阱差点把我整失业了
前端·人工智能·后端
鱼鳞_3 小时前
苍穹外卖-Day08(缓存套餐)
java·redis·缓存