This commit is contained in:
2026-08-25 14:46:06 +08:00
parent 5abc7543ae
commit f325d57fc1
106 changed files with 3682 additions and 450 deletions
@@ -0,0 +1,18 @@
package com.baiyue.common.web;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
/** Enables synchronous Feign trace propagation without making Feign a required dependency. */
@AutoConfiguration(afterName = "org.springframework.cloud.openfeign.FeignAutoConfiguration")
@ConditionalOnClass(name = "feign.RequestInterceptor")
public class FeignTracePropagationAutoConfiguration {
@Bean
@ConditionalOnMissingBean(FeignTraceRequestInterceptor.class)
FeignTraceRequestInterceptor feignTraceRequestInterceptor() {
return new FeignTraceRequestInterceptor();
}
}
@@ -0,0 +1,41 @@
package com.baiyue.common.web;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import java.util.regex.Pattern;
/** Propagates the trusted synchronous request trace context to every Feign invocation. */
public final class FeignTraceRequestInterceptor implements RequestInterceptor, Ordered {
private static final Pattern SAFE_REQUEST_ID = Pattern.compile("[A-Za-z0-9._:-]{1,128}");
@Override
public void apply(RequestTemplate template) {
removeManagedHeaders(template);
String requestId = MDC.get(CorrelationContext.REQUEST_ID);
if (requestId != null && SAFE_REQUEST_ID.matcher(requestId).matches()) {
template.header(CorrelationContext.REQUEST_ID_HEADER, requestId);
}
String traceId = MDC.get(CorrelationContext.TRACE_ID);
if (TraceParent.validLegacyTraceId(traceId)) {
TraceParent outbound = TraceParent.outboundChild(traceId);
template.header(CorrelationContext.TRACE_ID_HEADER, outbound.traceId());
template.header(CorrelationContext.TRACE_PARENT_HEADER, outbound.value());
}
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
private void removeManagedHeaders(RequestTemplate template) {
template.removeHeader(CorrelationContext.REQUEST_ID_HEADER);
template.removeHeader(CorrelationContext.TRACE_ID_HEADER);
template.removeHeader(CorrelationContext.TRACE_PARENT_HEADER);
}
}
@@ -55,6 +55,14 @@ public record TraceParent(String traceId, String parentId, String traceFlags) {
return new TraceParent(traceId, randomNonZero(8), "00");
}
/** Creates a sampled outbound child for a trusted current trace ID. */
public static TraceParent outboundChild(String currentTraceId) {
if (!validLegacyTraceId(currentTraceId)) {
throw new IllegalArgumentException("Current trace ID is invalid");
}
return new TraceParent(currentTraceId.toLowerCase(java.util.Locale.ROOT), randomNonZero(8), "01");
}
public static boolean validLegacyTraceId(String value) {
return value != null && LEGACY_TRACE_ID.matcher(value).matches()
&& !ZERO_TRACE_ID.equalsIgnoreCase(value);