feat(trace): 新增链路追踪模块(原 web 模块内组件)

This commit is contained in:
2025-03-26 20:41:46 +08:00
parent b5bfe5c681
commit 85285e56a8
8 changed files with 45 additions and 12 deletions

View File

@@ -1,84 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.web.autoconfigure.trace;
/**
* TLog 配置属性
*
* <p>
* 重写 TLog 配置以适配 Spring Boot 3.x
* </p>
*
* @author Bryan.Zhang
* @author Jasmine
* @see com.yomahub.tlog.springboot.property.TLogProperty
* @since 1.3.0
*/
public class TLogProperties {
/**
* 日志标签模板
*/
private String pattern;
/**
* 自动打印调用参数和时间
*/
private Boolean enableInvokeTimePrint;
/**
* 自定义 TraceId 生成器
*/
private String idGenerator;
/**
* MDC 模式
*/
private Boolean mdcEnable;
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
public Boolean getEnableInvokeTimePrint() {
return enableInvokeTimePrint;
}
public void setEnableInvokeTimePrint(Boolean enableInvokeTimePrint) {
this.enableInvokeTimePrint = enableInvokeTimePrint;
}
public String getIdGenerator() {
return idGenerator;
}
public void setIdGenerator(String idGenerator) {
this.idGenerator = idGenerator;
}
public Boolean getMdcEnable() {
return mdcEnable;
}
public void setMdcEnable(Boolean mdcEnable) {
this.mdcEnable = mdcEnable;
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.web.autoconfigure.trace;
import cn.hutool.core.text.CharSequenceUtil;
import com.yomahub.tlog.context.TLogContext;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* TLog 过滤器
*
* <p>
* 重写 TLog 配置以适配 Spring Boot 3.x
* </p>
*
* @author Bryan.Zhang
* @author Jasmine
* @see com.yomahub.tlog.web.filter.TLogServletFilter
* @since 1.3.0
*/
public class TLogServletFilter implements Filter {
private final TraceProperties traceProperties;
public TLogServletFilter(TraceProperties traceProperties) {
this.traceProperties = traceProperties;
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest httpServletRequest && response instanceof HttpServletResponse httpServletResponse) {
try {
TLogWebCommon.loadInstance().preHandle(httpServletRequest);
// 把 traceId 放入 response 的 header为了方便有些人有这样的需求从前端拿整条链路的 traceId
String traceIdName = traceProperties.getTraceIdName();
if (CharSequenceUtil.isNotBlank(traceIdName)) {
httpServletResponse.addHeader(traceIdName, TLogContext.getTraceId());
}
chain.doFilter(request, response);
} finally {
TLogWebCommon.loadInstance().afterCompletion();
}
return;
}
chain.doFilter(request, response);
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.web.autoconfigure.trace;
import com.yomahub.tlog.constant.TLogConstants;
import com.yomahub.tlog.core.rpc.TLogLabelBean;
import com.yomahub.tlog.core.rpc.TLogRPCHandler;
import jakarta.servlet.http.HttpServletRequest;
/**
* TLog Web 通用拦截器
*
* <p>
* 重写 TLog 配置以适配 Spring Boot 3.x
* </p>
*
* @author Bryan.Zhang
* @author Jasmine
* @see com.yomahub.tlog.web.common.TLogWebCommon
* @since 1.3.0
*/
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();
}
}

View File

@@ -1,94 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.web.autoconfigure.trace;
import com.yomahub.tlog.id.TLogIdGenerator;
import com.yomahub.tlog.id.TLogIdGeneratorLoader;
import com.yomahub.tlog.spring.TLogPropertyInit;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* 链路跟踪自动配置
*
* @author Jasmine
* @author Charles7c
* @since 1.3.0
*/
@AutoConfiguration
@ConditionalOnWebApplication
@EnableConfigurationProperties(TraceProperties.class)
@ConditionalOnProperty(prefix = PropertiesConstants.WEB_TRACE, name = PropertiesConstants.ENABLED, havingValue = "true")
public class TraceAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(TraceAutoConfiguration.class);
private final TraceProperties traceProperties;
public TraceAutoConfiguration(TraceProperties traceProperties) {
this.traceProperties = traceProperties;
}
@Bean
@Primary
public TLogPropertyInit tLogPropertyInit(TLogIdGenerator tLogIdGenerator) {
TLogProperties tLogProperties = traceProperties.getTlog();
TLogPropertyInit tLogPropertyInit = new TLogPropertyInit();
tLogPropertyInit.setPattern(tLogProperties.getPattern());
tLogPropertyInit.setEnableInvokeTimePrint(tLogProperties.getEnableInvokeTimePrint());
tLogPropertyInit.setMdcEnable(tLogProperties.getMdcEnable());
// 设置自定义 TraceId 生成器
TLogIdGeneratorLoader.setIdGenerator(tLogIdGenerator);
return tLogPropertyInit;
}
/**
* TLog 过滤器配置
*/
@Bean
public FilterRegistrationBean<TLogServletFilter> tLogServletFilter() {
FilterRegistrationBean<TLogServletFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new TLogServletFilter(traceProperties));
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registration;
}
/**
* 自定义 Trace ID 生成器配置
*/
@Bean
@ConditionalOnMissingBean
public TLogIdGenerator tLogIdGenerator() {
return new TraceIdGenerator();
}
@PostConstruct
public void postConstruct() {
log.debug("[ContiNew Starter] - Auto Configuration 'Web-Trace' completed initialization.");
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.web.autoconfigure.trace;
import com.yomahub.tlog.id.TLogIdGenerator;
import com.yomahub.tlog.id.snowflake.UniqueIdGenerator;
/**
* TLog ID 生成器
*
* @author Jasmine
* @author Charles7c
* @since 1.3.0
*/
public class TraceIdGenerator extends TLogIdGenerator {
@Override
public String generateTraceId() {
return String.valueOf(UniqueIdGenerator.generateId());
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.web.autoconfigure.trace;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* 链路跟踪配置属性
*
* @author Charles7c
* @since 1.3.0
*/
@ConfigurationProperties(PropertiesConstants.WEB_TRACE)
public class TraceProperties {
/**
* 是否启用链路跟踪配置
*/
private boolean enabled = false;
/**
* 链路 ID 名称
*/
private String traceIdName = "traceId";
/**
* TLog 配置
*/
@NestedConfigurationProperty
private TLogProperties tlog;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getTraceIdName() {
return traceIdName;
}
public void setTraceIdName(String traceIdName) {
this.traceIdName = traceIdName;
}
public TLogProperties getTlog() {
return tlog;
}
public void setTlog(TLogProperties tlog) {
this.tlog = tlog;
}
}