项目出现的问题:Springboot3.0.2版本集成Tlog(1.5.2版本)开源框架时未输出TraceId等信息。
经过搜索得知问题原因为:在Java EE 8及更高版本中,javax.servlet.*包已经替换成了jakarta.servlet.*,但是tlog还没支持到。
解决方法:重写tlog中TLogServletFilter,TLogWebCommon两个关键类将javax.servlet包的内容替换成jakarta.servlet包的内容。
代码如下:先是TLogWebCommon
public class TLogWebCommon extends TLogRPCHandler { private static volatile TLogWebCommon tLogWebCommon; public static TLogWebCommon loadInstance() { if (tLogWebCommon == null) { synchronized (TLogWebCommon.class) { if (tLogWebCommon == null) { tLogWebCommon = new TLogWebCommon(); } } } return tLogWebCommon; } public void preHandle(HttpServletRequest request) { String traceId = request.getHeader(TLogConstants.TLOG_TRACE_KEY); String spanId = request.getHeader(TLogConstants.TLOG_SPANID_KEY); String preIvkApp = request.getHeader(TLogConstants.PRE_IVK_APP_KEY); String preIvkHost = request.getHeader(TLogConstants.PRE_IVK_APP_HOST); String preIp = request.getHeader(TLogConstants.PRE_IP_KEY); TLogLabelBean labelBean = new TLogLabelBean(preIvkApp, preIvkHost, preIp, traceId, spanId); processProviderSide(labelBean); } public void afterCompletion() { cleanThreadLocal(); } }
再是TLogFilter
public class TLogFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { if (servletRequest instanceof HttpServletRequest && servletResponse instanceof HttpServletResponse){ try{ TLogWebCommon.loadInstance().preHandle((HttpServletRequest)servletRequest); //把traceId放入response的header,为了方便有些人有这样的需求,从前端拿整条链路的traceId ((HttpServletResponse)servletResponse).addHeader(TLogConstants.TLOG_TRACE_KEY, TLogContext.getTraceId()); filterChain.doFilter(servletRequest, servletResponse); return; }finally { TLogWebCommon.loadInstance().afterCompletion(); } } filterChain.doFilter(servletRequest, servletResponse); } }
最后增加自己的过滤器:
@Configuration @ComponentScan(value = "com.yomahub.tlog") public class LogConfig { @Bean public FilterRegistrationBean<TLogFilter> loggingFilter() { FilterRegistrationBean<TLogFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new TLogFilter()); registrationBean.addUrlPatterns("/*"); // 拦截所有请求路径 registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); return registrationBean; } }
到此基本上就可以正常输出日志了!!!
另:如果自定义TranceId生成则可以重写接口或者继承实现类:
public class TestIdGenerator extends TLogIdGenerator {
@Override
public String generateTraceId() {
return String.valueOf(System.nanoTime());
}
}
或
public class TLogCostumeIdGenerator extends TLogDefaultIdGenerator {
@Override public String generateTraceId() { return "自己的标识"+ super.generateTraceId(); } }
配置文件中配置:
tlog.id-generator=com.yomahub.tlog.example.dubbo.id.TestIdGenerator
记录:如果gateway中未按照格式输出TraceId等日志信息,可能需要增加:
<!-- 增加如下的TLog MDC Listener --> <contextListener class="com.yomahub.tlog.core.enhance.logback.TLogLogbackTTLMdcListener"/>