mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-11-04 18:59:22 +08:00 
			
		
		
		
	feat(trace): 新增链路追踪模块(原 web 模块内组件)
This commit is contained in:
		@@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.trace.autoconfigure;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,96 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.trace.autoconfigure;
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
import top.continew.starter.trace.filter.TLogServletFilter;
 | 
			
		||||
import top.continew.starter.trace.handler.TraceIdGenerator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 链路追踪自动配置
 | 
			
		||||
 *
 | 
			
		||||
 * @author Jasmine
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 1.3.0
 | 
			
		||||
 */
 | 
			
		||||
@AutoConfiguration
 | 
			
		||||
@ConditionalOnWebApplication
 | 
			
		||||
@EnableConfigurationProperties(TraceProperties.class)
 | 
			
		||||
@ConditionalOnProperty(prefix = PropertiesConstants.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 'Trace' completed initialization.");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.trace.autoconfigure;
 | 
			
		||||
 | 
			
		||||
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.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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,69 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.trace.filter;
 | 
			
		||||
 | 
			
		||||
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 top.continew.starter.trace.autoconfigure.TraceProperties;
 | 
			
		||||
import top.continew.starter.trace.handler.TLogWebCommon;
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.trace.handler;
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.trace.handler;
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
top.continew.starter.trace.autoconfigure.TraceAutoConfiguration
 | 
			
		||||
		Reference in New Issue
	
	Block a user