Stops propagating Sleuth 1.x spring-messaging headers
To reduce confusion and overhead, the following custom spring-messaging headers added in Sleuth 1.0 are no longer sent, and a log warning is issued once if they are by outside code. * spanId * spanSampled * spanParentSpanId * spanTraceId * spanFlags Sending the above headers actually increases the headers by up to 10 because they are duplicated in the "native" part of messages. This overhead is extreme especially if messages never leave the process. The solution is to only send [b3 single format](https://github.com/openzipkin/b3-propagation#single-header), which has been in sleuth since 2.0 and is compatible with JMS. The B3 single format is always parsed and takes precedence, even if multiple headers are sent, so this is a safe change. Note: Unlike RPC, messaging spans never join with their parent. Better performance is achieved by not propagating the producer's parentId downstream. Note: Deprecated spring-messaging headers such "spanTraceId" as are still read in Sleuth 3.x. However, they will not be at some point in the future. Please pay attention to the log messages and update your code if you are accidentally using them.
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -132,13 +132,6 @@
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- force latest reactor-netty -->
|
||||
<dependency>
|
||||
<groupId>io.projectreactor.netty</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
<version>0.9.6.RELEASE</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-dependencies</artifactId>
|
||||
|
||||
@@ -72,11 +72,16 @@ public class TraceBaggageAutoConfiguration {
|
||||
* To override the underlying context format, override this bean and set the delegate
|
||||
* to what you need. {@link BaggagePropagation.FactoryBuilder} will unwrap itself if
|
||||
* no fields are configured.
|
||||
*
|
||||
* <p>
|
||||
* This will use {@link B3Propagation.Format#SINGLE_NO_PARENT} for non-remote spans,
|
||||
* such as for messaging. Note: it will still parse incoming multi-header spans.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BaggagePropagation.FactoryBuilder baggagePropagationFactoryBuilder() {
|
||||
return BaggagePropagation.newFactoryBuilder(B3Propagation.FACTORY);
|
||||
return BaggagePropagation.newFactoryBuilder(B3Propagation.newFactoryBuilder()
|
||||
.injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -19,8 +19,11 @@ package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import brave.propagation.Propagation;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -45,25 +48,19 @@ enum MessageHeaderPropagation
|
||||
|
||||
private static final Log log = LogFactory.getLog(MessageHeaderPropagation.class);
|
||||
|
||||
private static final Set<String> DEPRECATED_HEADERS = new LinkedHashSet<>();
|
||||
|
||||
private static final Map<String, String> LEGACY_HEADER_MAPPING = new HashMap<>();
|
||||
|
||||
private static final String TRACE_ID_NAME = "X-B3-TraceId";
|
||||
|
||||
private static final String SPAN_ID_NAME = "X-B3-SpanId";
|
||||
|
||||
private static final String PARENT_SPAN_ID_NAME = "X-B3-ParentSpanId";
|
||||
|
||||
private static final String SAMPLED_NAME = "X-B3-Sampled";
|
||||
|
||||
private static final String FLAGS_NAME = "X-B3-Flags";
|
||||
|
||||
static {
|
||||
LEGACY_HEADER_MAPPING.put(TRACE_ID_NAME, TraceMessageHeaders.TRACE_ID_NAME);
|
||||
LEGACY_HEADER_MAPPING.put(SPAN_ID_NAME, TraceMessageHeaders.SPAN_ID_NAME);
|
||||
LEGACY_HEADER_MAPPING.put(PARENT_SPAN_ID_NAME,
|
||||
LEGACY_HEADER_MAPPING.put("X-B3-TraceId", TraceMessageHeaders.TRACE_ID_NAME);
|
||||
LEGACY_HEADER_MAPPING.put("X-B3-SpanId", TraceMessageHeaders.SPAN_ID_NAME);
|
||||
LEGACY_HEADER_MAPPING.put("X-B3-ParentSpanId",
|
||||
TraceMessageHeaders.PARENT_ID_NAME);
|
||||
LEGACY_HEADER_MAPPING.put(SAMPLED_NAME, TraceMessageHeaders.SAMPLED_NAME);
|
||||
LEGACY_HEADER_MAPPING.put(FLAGS_NAME, TraceMessageHeaders.SPAN_FLAGS_NAME);
|
||||
LEGACY_HEADER_MAPPING.put("X-B3-Sampled", TraceMessageHeaders.SAMPLED_NAME);
|
||||
LEGACY_HEADER_MAPPING.put("X-B3-Flags", TraceMessageHeaders.SPAN_FLAGS_NAME);
|
||||
DEPRECATED_HEADERS.addAll(LEGACY_HEADER_MAPPING.keySet());
|
||||
DEPRECATED_HEADERS.addAll(LEGACY_HEADER_MAPPING.values());
|
||||
}
|
||||
|
||||
static Map<String, ?> propagationHeaders(Map<String, ?> headers,
|
||||
@@ -119,8 +116,15 @@ enum MessageHeaderPropagation
|
||||
return nativeAccessor;
|
||||
}
|
||||
|
||||
static final AtomicBoolean LOGGED_PUT_DEPRECATED_HEADER = new AtomicBoolean();
|
||||
|
||||
@Override
|
||||
public void put(MessageHeaderAccessor accessor, String key, String value) {
|
||||
if (DEPRECATED_HEADERS.contains(key)
|
||||
&& LOGGED_PUT_DEPRECATED_HEADER.compareAndSet(false, true)) {
|
||||
log.warn("Please update your code so that it uses the 'b3' header "
|
||||
+ "instead of " + key);
|
||||
}
|
||||
try {
|
||||
doPut(accessor, key, value);
|
||||
}
|
||||
@@ -130,10 +134,6 @@ enum MessageHeaderPropagation
|
||||
+ "] from message", ex);
|
||||
}
|
||||
}
|
||||
String legacyKey = LEGACY_HEADER_MAPPING.get(key);
|
||||
if (legacyKey != null) {
|
||||
doPut(accessor, legacyKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void doPut(MessageHeaderAccessor accessor, String key, String value) {
|
||||
@@ -188,7 +188,14 @@ enum MessageHeaderPropagation
|
||||
return null;
|
||||
}
|
||||
|
||||
static final AtomicBoolean LOGGED_GET_DEPRECATED_HEADER = new AtomicBoolean();
|
||||
|
||||
private String doGet(MessageHeaderAccessor accessor, String key) {
|
||||
if (DEPRECATED_HEADERS.contains(key)
|
||||
&& LOGGED_GET_DEPRECATED_HEADER.compareAndSet(false, true)) {
|
||||
log.warn("Please update your code so that it uses the 'b3' header "
|
||||
+ "instead of " + key);
|
||||
}
|
||||
if (accessor instanceof NativeMessageHeaderAccessor) {
|
||||
NativeMessageHeaderAccessor nativeAccessor = (NativeMessageHeaderAccessor) accessor;
|
||||
String result = nativeAccessor.getFirstNativeHeader(key);
|
||||
|
||||
@@ -23,7 +23,9 @@ package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.4
|
||||
* @deprecated Since 3.0 these headers should not be used anymore as "b3" is sent instead
|
||||
*/
|
||||
@Deprecated
|
||||
public final class TraceMessageHeaders {
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.autoconfig;
|
||||
|
||||
import brave.Tracing;
|
||||
import brave.baggage.BaggagePropagation;
|
||||
import brave.propagation.B3Propagation;
|
||||
import brave.propagation.B3SinglePropagation;
|
||||
@@ -41,8 +42,8 @@ public class TraceAutoConfigurationPropagationCustomizationTests {
|
||||
@Test
|
||||
public void stillCreatesDefault() {
|
||||
this.contextRunner.run((context) -> {
|
||||
BDDAssertions.then(context.getBean(Propagation.Factory.class))
|
||||
.isEqualTo(B3Propagation.FACTORY);
|
||||
BDDAssertions.then(context.getBean(Tracing.class).propagation())
|
||||
.isInstanceOf(B3Propagation.class);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -52,8 +53,7 @@ public class TraceAutoConfigurationPropagationCustomizationTests {
|
||||
.withPropertyValues("spring.sleuth.baggage.remote-fields=country-code")
|
||||
.run((context) -> {
|
||||
BDDAssertions.then(context.getBean(Propagation.Factory.class))
|
||||
.hasFieldOrPropertyWithValue("delegate",
|
||||
B3Propagation.FACTORY);
|
||||
.extracting("delegate").isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ public class TraceAutoConfigurationPropagationCustomizationTests {
|
||||
public void defaultValueUsedWhenApplicationNameNotSet() {
|
||||
this.contextRunner.withPropertyValues("spring.application.name=")
|
||||
.run((context) -> {
|
||||
BDDAssertions.then(context.getBean(Propagation.Factory.class))
|
||||
.isEqualTo(B3Propagation.FACTORY);
|
||||
BDDAssertions.then(context.getBean(Tracing.class).propagation())
|
||||
.isInstanceOf(B3Propagation.class);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -56,26 +56,26 @@ public class MessageHeaderPropagationTest
|
||||
@Test
|
||||
public void testGetByteArrayValue() {
|
||||
MessageHeaderAccessor carrier = carrier();
|
||||
carrier.setHeader("X-B3-TraceId", "48485a3953bb6124".getBytes());
|
||||
carrier.setHeader("X-B3-TraceId", "48485a3953bb6124000000".getBytes());
|
||||
String value = MessageHeaderPropagation.INSTANCE.get(carrier, "X-B3-TraceId");
|
||||
assertThat(value).isEqualTo("48485a3953bb6124000000");
|
||||
carrier.setHeader("b3", "48485a3953bb6124-1234".getBytes());
|
||||
carrier.setHeader("b3", "48485a3953bb6124000000-1234".getBytes());
|
||||
String value = MessageHeaderPropagation.INSTANCE.get(carrier, "b3");
|
||||
assertThat(value).isEqualTo("48485a3953bb6124000000-1234");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStringValue() {
|
||||
MessageHeaderAccessor carrier = carrier();
|
||||
carrier.setHeader("X-B3-TraceId", "48485a3953bb6124");
|
||||
carrier.setHeader("X-B3-TraceId", "48485a3953bb61240000000");
|
||||
String value = MessageHeaderPropagation.INSTANCE.get(carrier, "X-B3-TraceId");
|
||||
assertThat(value).isEqualTo("48485a3953bb61240000000");
|
||||
carrier.setHeader("B3", "48485a3953bb6124-1234");
|
||||
carrier.setHeader("B3", "48485a3953bb61240000000-1234");
|
||||
String value = MessageHeaderPropagation.INSTANCE.get(carrier, "B3");
|
||||
assertThat(value).isEqualTo("48485a3953bb61240000000-1234");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNullValue() {
|
||||
MessageHeaderAccessor carrier = carrier();
|
||||
carrier.setHeader("X-B3-TraceId", "48485a3953bb6124");
|
||||
carrier.setHeader("X-B3-TraceId", "48485a3953bb61240000000");
|
||||
carrier.setHeader("B3", "48485a3953bb6124-1234");
|
||||
carrier.setHeader("B3", "48485a3953bb61240000000-1234");
|
||||
String value = MessageHeaderPropagation.INSTANCE.get(carrier, "non existent key");
|
||||
assertThat(value).isNull();
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class MessageHeaderPropagationTest
|
||||
MessageHeaderAccessor carrier = carrier();
|
||||
carrier.setHeader(NativeMessageHeaderAccessor.NATIVE_HEADERS,
|
||||
"{spanTraceId=[123], spanId=[456], spanSampled=[0]}");
|
||||
MessageHeaderPropagation.INSTANCE.get(carrier, "X-B3-SpanId");
|
||||
MessageHeaderPropagation.INSTANCE.get(carrier, "b3");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,7 +94,7 @@ public class MessageHeaderPropagationTest
|
||||
carrier.setHeader(NativeMessageHeaderAccessor.NATIVE_HEADERS,
|
||||
"{spanTraceId=[123], spanId=[456], spanSampled=[0]}");
|
||||
MessageHeaderPropagation.removeAnyTraceHeaders(carrier,
|
||||
Collections.singletonList("X-B3-SpanId"));
|
||||
Collections.singletonList("b3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,7 +102,7 @@ public class MessageHeaderPropagationTest
|
||||
MessageHeaderAccessor carrier = carrier();
|
||||
carrier.setHeader(NativeMessageHeaderAccessor.NATIVE_HEADERS,
|
||||
"{spanTraceId=[123], spanId=[456], spanSampled=[0]}");
|
||||
MessageHeaderPropagation.INSTANCE.put(carrier, "X-B3-SpanId", "1234");
|
||||
MessageHeaderPropagation.INSTANCE.put(carrier, "b3", "1234");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,40 +40,38 @@ public abstract class PropagationSetterTest<C, K> {
|
||||
|
||||
@Test
|
||||
public void set() throws Exception {
|
||||
K key = keyFactory().create("X-B3-TraceId");
|
||||
setter().put(carrier(), key, "48485a3953bb6124");
|
||||
K key = keyFactory().create("b3");
|
||||
setter().put(carrier(), key, "1");
|
||||
|
||||
assertThat(read(carrier(), key)).containsExactly("48485a3953bb6124");
|
||||
assertThat(read(carrier(), key)).containsExactly("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void set128() throws Exception {
|
||||
K key = keyFactory().create("X-B3-TraceId");
|
||||
setter().put(carrier(), key, "463ac35c9f6413ad48485a3953bb6124");
|
||||
K key = keyFactory().create("b3");
|
||||
setter().put(carrier(), key, "1");
|
||||
|
||||
assertThat(read(carrier(), key))
|
||||
.containsExactly("463ac35c9f6413ad48485a3953bb6124");
|
||||
assertThat(read(carrier(), key)).containsExactly("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTwoKeys() throws Exception {
|
||||
K key1 = keyFactory().create("X-B3-TraceId");
|
||||
K key2 = keyFactory().create("X-B3-SpanId");
|
||||
setter().put(carrier(), key1, "463ac35c9f6413ad48485a3953bb6124");
|
||||
setter().put(carrier(), key2, "48485a3953bb6124");
|
||||
K key1 = keyFactory().create("b3");
|
||||
K key2 = keyFactory().create("baggage");
|
||||
setter().put(carrier(), key1, "1");
|
||||
setter().put(carrier(), key2, "country-code=FO");
|
||||
|
||||
assertThat(read(carrier(), key1))
|
||||
.containsExactly("463ac35c9f6413ad48485a3953bb6124");
|
||||
assertThat(read(carrier(), key2)).containsExactly("48485a3953bb6124");
|
||||
assertThat(read(carrier(), key1)).containsExactly("1");
|
||||
assertThat(read(carrier(), key2)).containsExactly("country-code=FO");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reset() throws Exception {
|
||||
K key = keyFactory().create("X-B3-TraceId");
|
||||
setter().put(carrier(), key, "48485a3953bb6124");
|
||||
setter().put(carrier(), key, "463ac35c9f6413ad");
|
||||
K key = keyFactory().create("b3");
|
||||
setter().put(carrier(), key, "0");
|
||||
setter().put(carrier(), key, "1");
|
||||
|
||||
assertThat(read(carrier(), key)).containsExactly("463ac35c9f6413ad");
|
||||
assertThat(read(carrier(), key)).containsExactly("1");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import brave.Tracing;
|
||||
import brave.propagation.B3Propagation;
|
||||
import brave.propagation.StrictCurrentTraceContext;
|
||||
import brave.propagation.TraceContext;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import zipkin2.Span;
|
||||
@@ -45,6 +46,8 @@ import org.springframework.messaging.support.ExecutorSubscribableChannel;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.messaging.support.NativeMessageHeaderAccessor;
|
||||
|
||||
import static brave.propagation.B3Propagation.Format.SINGLE;
|
||||
import static brave.propagation.B3SingleFormat.parseB3SingleFormat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.messaging.support.NativeMessageHeaderAccessor.NATIVE_HEADERS;
|
||||
|
||||
@@ -55,6 +58,10 @@ public class TracingChannelInterceptorTest {
|
||||
List<Span> spans = new ArrayList<>();
|
||||
|
||||
Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext)
|
||||
// SINGLE_NO_PARENT more appropriate for messaging, but we check parent
|
||||
// hereTraceMessageHeaders
|
||||
.propagationFactory(
|
||||
B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build())
|
||||
.spanReporter(this.spans::add).build();
|
||||
|
||||
ChannelInterceptor interceptor = TracingChannelInterceptor.create(tracing);
|
||||
@@ -92,8 +99,7 @@ public class TracingChannelInterceptorTest {
|
||||
|
||||
this.channel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat(this.channel.receive().getHeaders()).containsKeys("X-B3-TraceId",
|
||||
"X-B3-SpanId", "X-B3-Sampled", "nativeHeaders");
|
||||
assertThat(this.channel.receive().getHeaders()).containsKey("b3");
|
||||
assertThat(this.spans).hasSize(1).flatExtracting(Span::kind)
|
||||
.containsExactly(Span.Kind.PRODUCER);
|
||||
}
|
||||
@@ -105,8 +111,7 @@ public class TracingChannelInterceptorTest {
|
||||
this.directChannel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat(this.message).isNotNull();
|
||||
assertThat(this.message.getHeaders()).containsKeys("X-B3-TraceId", "X-B3-SpanId",
|
||||
"X-B3-Sampled", "nativeHeaders");
|
||||
assertThat(this.message.getHeaders()).containsKeys("b3", "nativeHeaders");
|
||||
assertThat(this.spans).flatExtracting(Span::kind).contains(Span.Kind.CONSUMER,
|
||||
Span.Kind.PRODUCER);
|
||||
}
|
||||
@@ -118,8 +123,7 @@ public class TracingChannelInterceptorTest {
|
||||
this.channel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS))
|
||||
.containsOnlyKeys("X-B3-TraceId", "X-B3-SpanId", "X-B3-Sampled",
|
||||
"spanTraceId", "spanId", "spanSampled");
|
||||
.containsOnlyKeys("b3");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,12 +136,11 @@ public class TracingChannelInterceptorTest {
|
||||
this.channel.addInterceptor(producerSideOnly(this.interceptor));
|
||||
|
||||
this.channel.send(MessageBuilder.withPayload("foo")
|
||||
.setHeader("X-B3-TraceId", "000000000000000a")
|
||||
.setHeader("X-B3-ParentSpanId", "000000000000000a")
|
||||
.setHeader("X-B3-SpanId", "000000000000000b").build());
|
||||
.setHeader("b3", "000000000000000a-000000000000000b-1").build());
|
||||
|
||||
assertThat(this.channel.receive().getHeaders()).containsEntry("X-B3-ParentSpanId",
|
||||
"000000000000000b");
|
||||
TraceContext receiveContext = parseB3SingleFormat(
|
||||
this.channel.receive().getHeaders().get("b3", String.class)).context();
|
||||
assertThat(receiveContext.parentIdString()).isEqualTo("000000000000000b");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -147,16 +150,16 @@ public class TracingChannelInterceptorTest {
|
||||
NativeMessageHeaderAccessor accessor = new NativeMessageHeaderAccessor() {
|
||||
};
|
||||
|
||||
accessor.setNativeHeader("X-B3-TraceId", "000000000000000a");
|
||||
accessor.setNativeHeader("X-B3-ParentSpanId", "000000000000000a");
|
||||
accessor.setNativeHeader("X-B3-SpanId", "000000000000000b");
|
||||
accessor.setNativeHeader("b3",
|
||||
"000000000000000a-000000000000000b-1-000000000000000a");
|
||||
|
||||
this.channel.send(MessageBuilder.withPayload("foo")
|
||||
.copyHeaders(accessor.toMessageHeaders()).build());
|
||||
|
||||
assertThat((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS))
|
||||
.containsEntry("X-B3-ParentSpanId",
|
||||
Collections.singletonList("000000000000000b"));
|
||||
TraceContext receiveContext = parseB3SingleFormat(
|
||||
((List) ((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS))
|
||||
.get("b3")).get(0).toString()).context();
|
||||
assertThat(receiveContext.parentIdString()).isEqualTo("000000000000000b");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,8 +172,8 @@ public class TracingChannelInterceptorTest {
|
||||
|
||||
this.channel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat(this.channel.receive().getHeaders()).containsKeys("X-B3-TraceId",
|
||||
"X-B3-SpanId", "X-B3-Sampled", "nativeHeaders");
|
||||
assertThat(this.channel.receive().getHeaders()).containsKeys("b3",
|
||||
"nativeHeaders");
|
||||
assertThat(this.spans).hasSize(1).flatExtracting(Span::kind)
|
||||
.containsExactly(Span.Kind.CONSUMER);
|
||||
}
|
||||
@@ -182,8 +185,7 @@ public class TracingChannelInterceptorTest {
|
||||
this.channel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS))
|
||||
.containsOnlyKeys("X-B3-TraceId", "X-B3-SpanId", "X-B3-Sampled",
|
||||
"spanTraceId", "spanId", "spanSampled");
|
||||
.containsOnlyKeys("b3");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,8 +197,8 @@ public class TracingChannelInterceptorTest {
|
||||
|
||||
channel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat(messages.get(0).getHeaders()).doesNotContainKeys("X-B3-TraceId",
|
||||
"X-B3-SpanId", "X-B3-Sampled", "nativeHeaders");
|
||||
assertThat(messages.get(0).getHeaders()).doesNotContainKeys("b3",
|
||||
"nativeHeaders");
|
||||
assertThat(this.spans).flatExtracting(Span::kind)
|
||||
.containsExactly(Span.Kind.CONSUMER, null);
|
||||
}
|
||||
@@ -215,8 +217,7 @@ public class TracingChannelInterceptorTest {
|
||||
|
||||
channel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat(messages.get(0).getHeaders()).doesNotContainKeys("X-B3-TraceId",
|
||||
"X-B3-SpanId", "X-B3-Sampled");
|
||||
assertThat(messages.get(0).getHeaders()).doesNotContainKeys("b3");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -229,7 +230,7 @@ public class TracingChannelInterceptorTest {
|
||||
channel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
assertThat((Map) messages.get(0).getHeaders().get(NATIVE_HEADERS))
|
||||
.doesNotContainKeys("X-B3-TraceId", "X-B3-SpanId", "X-B3-Sampled");
|
||||
.doesNotContainKeys("b3");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -264,27 +265,23 @@ public class TracingChannelInterceptorTest {
|
||||
Map<String, Object> errorChannelHeaders = new HashMap<>();
|
||||
errorChannelHeaders.put(MessageHeaders.REPLY_CHANNEL, errorsReplyChannel);
|
||||
errorChannelHeaders.put(MessageHeaders.ERROR_CHANNEL, errorsReplyChannel);
|
||||
this.channel
|
||||
.send(new ErrorMessage(
|
||||
new MessagingException(MessageBuilder.withPayload("hi")
|
||||
.setHeader(TraceMessageHeaders.TRACE_ID_NAME,
|
||||
"000000000000000a")
|
||||
.setHeader(TraceMessageHeaders.SPAN_ID_NAME,
|
||||
"000000000000000a")
|
||||
.setReplyChannel(deadReplyChannel)
|
||||
.setErrorChannel(deadReplyChannel).build()),
|
||||
errorChannelHeaders));
|
||||
this.channel.send(new ErrorMessage(
|
||||
new MessagingException(MessageBuilder.withPayload("hi")
|
||||
.setHeader("b3", "000000000000000a-000000000000000a")
|
||||
.setReplyChannel(deadReplyChannel)
|
||||
.setErrorChannel(deadReplyChannel).build()),
|
||||
errorChannelHeaders));
|
||||
|
||||
this.message = this.channel.receive();
|
||||
|
||||
assertThat(this.message).isNotNull();
|
||||
String spanId = this.message.getHeaders().get(TraceMessageHeaders.SPAN_ID_NAME,
|
||||
String.class);
|
||||
assertThat(spanId).isNotNull();
|
||||
String traceId = this.message.getHeaders().get(TraceMessageHeaders.TRACE_ID_NAME,
|
||||
String.class);
|
||||
assertThat(traceId).isEqualTo("000000000000000a");
|
||||
assertThat(spanId).isNotEqualTo("000000000000000a");
|
||||
|
||||
// Parse fails if trace or span ID are missing
|
||||
TraceContext context = parseB3SingleFormat(
|
||||
this.message.getHeaders().get("b3", String.class)).context();
|
||||
|
||||
assertThat(context.traceIdString()).isEqualTo("000000000000000a");
|
||||
assertThat(context.spanIdString()).isNotEqualTo("000000000000000a");
|
||||
assertThat(this.spans).hasSize(2);
|
||||
assertThat(this.message.getHeaders().getReplyChannel())
|
||||
.isSameAs(errorsReplyChannel);
|
||||
@@ -318,21 +315,16 @@ public class TracingChannelInterceptorTest {
|
||||
public void errorMessageHeadersWithNullPayloadRetained() {
|
||||
this.channel.addInterceptor(this.interceptor);
|
||||
Map<String, Object> errorChannelHeaders = new HashMap<>();
|
||||
errorChannelHeaders.put(TraceMessageHeaders.TRACE_ID_NAME, "000000000000000a");
|
||||
errorChannelHeaders.put(TraceMessageHeaders.SPAN_ID_NAME, "000000000000000a");
|
||||
errorChannelHeaders.put("b3", "000000000000000a-000000000000000a");
|
||||
this.channel.send(new ErrorMessage(new MessagingException("exception"),
|
||||
errorChannelHeaders));
|
||||
|
||||
this.message = this.channel.receive();
|
||||
|
||||
assertThat(this.message).isNotNull();
|
||||
String spanId = this.message.getHeaders().get(TraceMessageHeaders.SPAN_ID_NAME,
|
||||
String.class);
|
||||
assertThat(spanId).isNotNull();
|
||||
String traceId = this.message.getHeaders().get(TraceMessageHeaders.TRACE_ID_NAME,
|
||||
String.class);
|
||||
assertThat(traceId).isEqualTo("000000000000000a");
|
||||
assertThat(spanId).isNotEqualTo("000000000000000a");
|
||||
TraceContext receiveContext = parseB3SingleFormat(
|
||||
this.message.getHeaders().get("b3", String.class)).context();
|
||||
assertThat(receiveContext.traceIdString()).isEqualTo("000000000000000a");
|
||||
assertThat(receiveContext.spanIdString()).isNotEqualTo("000000000000000a");
|
||||
assertThat(this.spans).hasSize(2);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.MapEntry.entry;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
|
||||
@@ -82,10 +83,8 @@ public class BraveTracerTest {
|
||||
|
||||
@Test
|
||||
public void extractTraceContext() {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("X-B3-TraceId", "0000000000000001");
|
||||
map.put("X-B3-SpanId", "0000000000000002");
|
||||
map.put("X-B3-Sampled", "1");
|
||||
Map<String, String> map = singletonMap("b3",
|
||||
"0000000000000001-0000000000000002-1");
|
||||
|
||||
BraveSpanContext openTracingContext = this.opentracing
|
||||
.extract(Format.Builtin.HTTP_HEADERS, new TextMapAdapter(map));
|
||||
@@ -97,9 +96,7 @@ public class BraveTracerTest {
|
||||
@Test
|
||||
public void extractBaggage() {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("X-B3-TraceId", "0000000000000001");
|
||||
map.put("X-B3-SpanId", "0000000000000002");
|
||||
map.put("X-B3-Sampled", "1");
|
||||
map.put("b3", "0000000000000001-0000000000000002-1");
|
||||
map.put("country-code", "FO");
|
||||
|
||||
BraveSpanContext openTracingContext = this.opentracing
|
||||
@@ -111,10 +108,8 @@ public class BraveTracerTest {
|
||||
|
||||
@Test
|
||||
public void extractTraceContextTextMap() {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("X-B3-TraceId", "0000000000000001");
|
||||
map.put("X-B3-SpanId", "0000000000000002");
|
||||
map.put("X-B3-Sampled", "1");
|
||||
Map<String, String> map = singletonMap("b3",
|
||||
"0000000000000001-0000000000000002-1");
|
||||
|
||||
BraveSpanContext openTracingContext = this.opentracing
|
||||
.extract(Format.Builtin.TEXT_MAP, new TextMapAdapter(map));
|
||||
@@ -126,9 +121,7 @@ public class BraveTracerTest {
|
||||
@Test
|
||||
public void extractTraceContextCaseInsensitive() {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("X-B3-TraceId", "0000000000000001");
|
||||
map.put("x-b3-spanid", "0000000000000002");
|
||||
map.put("x-b3-SaMpLeD", "1");
|
||||
map.put("B3", "0000000000000001-0000000000000002-1");
|
||||
map.put("other", "1");
|
||||
|
||||
BraveSpanContext openTracingContext = this.opentracing
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.cloud.sleuth.util.SpanUtil;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -55,13 +54,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
||||
*/
|
||||
public class TraceFilterTests {
|
||||
|
||||
static final String PARENT_ID = SpanUtil.idToHex(10L);
|
||||
static final String TRACE_ID_NAME = "X-B3-TraceId";
|
||||
static final String SPAN_ID_NAME = "X-B3-SpanId";
|
||||
static final String PARENT_SPAN_ID_NAME = "X-B3-ParentSpanId";
|
||||
static final String SAMPLED_ID_NAME = "X-B3-Sampled";
|
||||
static final String SPAN_FLAGS = "X-B3-Flags";
|
||||
|
||||
ArrayListSpanReporter reporter = new ArrayListSpanReporter();
|
||||
|
||||
Tracing tracing = Tracing.newBuilder()
|
||||
@@ -152,16 +144,15 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void startsNewTraceWithParentIdInHeaders() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(2L))
|
||||
.header(PARENT_SPAN_ID_NAME, SpanUtil.idToHex(3L))
|
||||
this.request = builder()
|
||||
.header("b3", "0000000000000002-0000000000000003-1-000000000000000a")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.filter.doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
then(Tracing.current().tracer().currentSpan()).isNull();
|
||||
then(this.reporter.getSpans()).hasSize(1);
|
||||
then(this.reporter.getSpans().get(0).id()).isEqualTo(PARENT_ID);
|
||||
then(this.reporter.getSpans().get(0).id()).isEqualTo("0000000000000003");
|
||||
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/")
|
||||
.containsEntry("http.method", HttpMethod.GET.toString());
|
||||
}
|
||||
@@ -169,10 +160,8 @@ public class TraceFilterTests {
|
||||
@Test
|
||||
public void continuesATraceWhenSpanNotSampled() throws Exception {
|
||||
AtomicReference<Span> span = new AtomicReference<>();
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(2L))
|
||||
.header(PARENT_SPAN_ID_NAME, SpanUtil.idToHex(3L))
|
||||
.header(SAMPLED_ID_NAME, 0).buildRequest(new MockServletContext());
|
||||
this.request = builder().header("b3", "0000000000000014-000000000000000a-0")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.filter.doFilter(this.request, this.response, (req, resp) -> {
|
||||
this.filterChain.doFilter(req, resp);
|
||||
@@ -180,7 +169,7 @@ public class TraceFilterTests {
|
||||
});
|
||||
|
||||
then(Tracing.current().tracer().currentSpan()).isNull();
|
||||
then(span.get().context().traceIdString()).isEqualTo(SpanUtil.idToHex(2L));
|
||||
then(span.get().context().traceIdString()).isEqualTo("0000000000000014");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -215,8 +204,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void continuesSpanFromHeaders() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "0000000000000014-000000000000000a")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.filter.doFilter(this.request, this.response, this.filterChain);
|
||||
@@ -232,8 +220,7 @@ public class TraceFilterTests {
|
||||
.addScopeDecorator(StrictScopeDecorator.create()).build())
|
||||
.spanReporter(this.reporter).supportsJoin(false).build();
|
||||
HttpTracing httpTracing = HttpTracing.create(tracing);
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "0000000000000014-000000000000000a")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
TracingFilter.create(httpTracing).doFilter(this.request, this.response,
|
||||
@@ -241,13 +228,12 @@ public class TraceFilterTests {
|
||||
|
||||
then(Tracing.current().tracer().currentSpan()).isNull();
|
||||
then(this.reporter.getSpans()).hasSize(1);
|
||||
then(this.reporter.getSpans().get(0).parentId()).isEqualTo(PARENT_ID);
|
||||
then(this.reporter.getSpans().get(0).parentId()).isEqualTo("000000000000000a");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAnnotateSpanWithErrorWhenExceptionIsThrown() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "0000000000000014-000000000000000a")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.filterChain = new MockFilterChain() {
|
||||
@@ -273,8 +259,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void detachesSpanWhenResponseStatusIsNot2xx() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "14-a")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.response.setStatus(404);
|
||||
@@ -285,8 +270,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void closesSpanWhenResponseStatusIs2xx() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "0000000000000014-000000000000000a")
|
||||
.buildRequest(new MockServletContext());
|
||||
this.response.setStatus(200);
|
||||
|
||||
@@ -298,8 +282,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void closesSpanWhenResponseStatusIs3xx() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "0000000000000014-000000000000000a")
|
||||
.buildRequest(new MockServletContext());
|
||||
this.response.setStatus(302);
|
||||
|
||||
@@ -311,8 +294,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void returns400IfSpanIsMalformedAndCreatesANewSpan() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, "asd")
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "asd")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.filter.doFilter(this.request, this.response, this.filterChain);
|
||||
@@ -324,9 +306,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void returns200IfSpanParentIsMalformedAndCreatesANewSpan() throws Exception {
|
||||
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
|
||||
.header(PARENT_SPAN_ID_NAME, "-")
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
|
||||
this.request = builder().header("b3", "asd")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.filter.doFilter(this.request, this.response, this.filterChain);
|
||||
@@ -337,10 +317,8 @@ public class TraceFilterTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void samplesASpanRegardlessOfTheSamplerWhenXB3FlagsIsPresentAndSetTo1()
|
||||
throws Exception {
|
||||
this.request = builder().header(SPAN_FLAGS, 1)
|
||||
.buildRequest(new MockServletContext());
|
||||
public void samplesASpanRegardlessOfTheSamplerWhenDebugIsPresent() throws Exception {
|
||||
this.request = builder().header("b3", "d").buildRequest(new MockServletContext());
|
||||
|
||||
neverSampleFilter().doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
@@ -348,38 +326,10 @@ public class TraceFilterTests {
|
||||
then(this.reporter.getSpans()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotOverrideTheSampledFlagWhenXB3FlagIsSetToOtherValueThan1()
|
||||
throws Exception {
|
||||
this.request = builder().header(SPAN_FLAGS, 0)
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
this.filter.doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
then(Tracing.current().tracer().currentSpan()).isNull();
|
||||
then(this.reporter.getSpans()).isNotEmpty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Test
|
||||
public void samplesWhenDebugFlagIsSetTo1AndOnlySpanIdIsSet() throws Exception {
|
||||
this.request = builder().header(SPAN_FLAGS, 1)
|
||||
.header(SPAN_ID_NAME, SpanUtil.idToHex(10L))
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
neverSampleFilter().doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
then(Tracing.current().tracer().currentSpan()).isNull();
|
||||
// It is ok to go without a trace ID, if sampling or debug is set
|
||||
then(this.reporter.getSpans()).hasSize(1).extracting("id")
|
||||
.isNotEqualTo(SpanUtil.idToHex(10L));
|
||||
}
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Test
|
||||
public void usesSamplingMechanismWhenIncomingTraceIsMalformed() throws Exception {
|
||||
this.request = builder().header(SPAN_FLAGS, 1)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(10L))
|
||||
this.request = builder().header("b3", "asd")
|
||||
.buildRequest(new MockServletContext());
|
||||
|
||||
neverSampleFilter().doFilter(this.request, this.response, this.filterChain);
|
||||
@@ -407,8 +357,7 @@ public class TraceFilterTests {
|
||||
|
||||
@Test
|
||||
public void samplesASpanDebugFlagWithInterceptor() throws Exception {
|
||||
this.request = builder().header(SPAN_FLAGS, 1)
|
||||
.buildRequest(new MockServletContext());
|
||||
this.request = builder().header("b3", "d").buildRequest(new MockServletContext());
|
||||
|
||||
neverSampleFilter().doFilter(this.request, this.response, this.filterChain);
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ public class TraceRestTemplateInterceptorTests {
|
||||
Map<String, String> headers = this.template.getForEntity("/", Map.class)
|
||||
.getBody();
|
||||
|
||||
// Default inject format for client spans is B3 multi
|
||||
then(headers.get("X-B3-TraceId")).isNotNull();
|
||||
then(headers.get("X-B3-SpanId")).isNotNull();
|
||||
}
|
||||
@@ -109,6 +110,7 @@ public class TraceRestTemplateInterceptorTests {
|
||||
span.finish();
|
||||
}
|
||||
|
||||
// Default inject format for client spans is B3 multi
|
||||
then(headers.get("X-B3-TraceId"))
|
||||
.isEqualTo(SpanUtil.idToHex(span.context().traceId()));
|
||||
then(headers.get("X-B3-SpanId"))
|
||||
@@ -205,7 +207,8 @@ public class TraceRestTemplateInterceptorTests {
|
||||
@RequestMapping("/")
|
||||
public Map<String, String> home(@RequestHeader HttpHeaders headers) {
|
||||
this.span = TraceRestTemplateInterceptorTests.this.tracer.currentSpan();
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
Map<String, String> map = new HashMap<>();
|
||||
// Default inject format for client spans is B3 multi
|
||||
addHeaders(map, headers, "X-B3-SpanId", "X-B3-TraceId", "X-B3-ParentSpanId");
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
|
||||
// This test uses B3 multi format as it is the default for client propagation
|
||||
public class TraceRequestHttpHeadersFilterTests {
|
||||
|
||||
StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create();
|
||||
|
||||
@@ -51,8 +51,7 @@ public class TraceResponseHttpHeadersFilterTests {
|
||||
HttpHeadersFilter filter = TraceResponseHttpHeadersFilter
|
||||
.create(this.httpTracing);
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.set("X-B3-TraceId", "52f112af7472aff0");
|
||||
httpHeaders.set("X-B3-SpanId", "53e6ab6fc5dfee58");
|
||||
httpHeaders.set("b3", "52f112af7472aff0-53e6ab6fc5dfee58");
|
||||
MockServerHttpRequest request = MockServerHttpRequest.post("foo/bar")
|
||||
.headers(httpHeaders).build();
|
||||
MockServerWebExchange exchange = MockServerWebExchange.builder(request).build();
|
||||
@@ -67,8 +66,7 @@ public class TraceResponseHttpHeadersFilterTests {
|
||||
HttpHeadersFilter filter = TraceResponseHttpHeadersFilter
|
||||
.create(this.httpTracing);
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.set("X-B3-TraceId", "52f112af7472aff0");
|
||||
httpHeaders.set("X-B3-SpanId", "53e6ab6fc5dfee58");
|
||||
httpHeaders.set("b3", "52f112af7472aff0-53e6ab6fc5dfee58");
|
||||
MockServerHttpRequest request = MockServerHttpRequest.post("foo/bar")
|
||||
.headers(httpHeaders).build();
|
||||
MockServerWebExchange exchange = MockServerWebExchange.builder(request).build();
|
||||
|
||||
@@ -32,6 +32,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import brave.Span;
|
||||
import brave.Tracer;
|
||||
import brave.Tracing;
|
||||
import brave.baggage.BaggagePropagation;
|
||||
import brave.propagation.B3Propagation;
|
||||
import brave.propagation.B3SingleFormat;
|
||||
import brave.propagation.SamplingFlags;
|
||||
import brave.propagation.TraceContextOrSamplingFlags;
|
||||
import brave.sampler.Sampler;
|
||||
@@ -90,6 +93,8 @@ import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.reactive.function.client.UnknownHttpStatusCodeException;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static brave.Span.Kind.CLIENT;
|
||||
import static brave.propagation.B3Propagation.Format.SINGLE_NO_PARENT;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@@ -100,11 +105,6 @@ import static org.assertj.core.api.BDDAssertions.then;
|
||||
@DirtiesContext
|
||||
public class WebClientTests {
|
||||
|
||||
static final String TRACE_ID_NAME = "X-B3-TraceId";
|
||||
static final String SPAN_ID_NAME = "X-B3-SpanId";
|
||||
static final String SAMPLED_NAME = "X-B3-Sampled";
|
||||
static final String PARENT_ID_NAME = "X-B3-ParentSpanId";
|
||||
|
||||
private static final Log log = LogFactory.getLog(WebClientTests.class);
|
||||
|
||||
@Autowired
|
||||
@@ -163,8 +163,7 @@ public class WebClientTests {
|
||||
ResponseEntity<String> response = provider.get(this);
|
||||
|
||||
Awaitility.await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> {
|
||||
then(getHeader(response, TRACE_ID_NAME)).isNull();
|
||||
then(getHeader(response, SPAN_ID_NAME)).isNull();
|
||||
then(getHeader(response, "b3")).isNull();
|
||||
List<zipkin2.Span> spans = this.reporter.getSpans();
|
||||
then(spans).isNotEmpty();
|
||||
Optional<zipkin2.Span> noTraceSpan = new ArrayList<>(spans).stream()
|
||||
@@ -220,8 +219,7 @@ public class WebClientTests {
|
||||
try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) {
|
||||
ResponseEntity<Map<String, String>> response = provider.get(this);
|
||||
|
||||
then(response.getBody().get(TRACE_ID_NAME.toLowerCase())).isNotNull();
|
||||
then(response.getBody().get(SAMPLED_NAME.toLowerCase())).isEqualTo("0");
|
||||
then(response.getBody().get("b3")).isNotNull().endsWith("-0"); // not sampled
|
||||
}
|
||||
finally {
|
||||
span.finish();
|
||||
@@ -250,8 +248,7 @@ public class WebClientTests {
|
||||
|
||||
// https://github.com/spring-cloud/spring-cloud-sleuth/issues/327
|
||||
// we don't want to respond with any tracing data
|
||||
then(getHeader(response, SAMPLED_NAME)).isNull();
|
||||
then(getHeader(response, TRACE_ID_NAME)).isNull();
|
||||
then(getHeader(response, "b3")).isNull();
|
||||
}
|
||||
finally {
|
||||
span.finish();
|
||||
@@ -480,7 +477,7 @@ public class WebClientTests {
|
||||
AtomicReference<String> traceId = new AtomicReference<>();
|
||||
try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span)) {
|
||||
this.webClientBuilder.filter((request, exchange) -> {
|
||||
traceId.set(request.headers().getFirst("X-B3-SpanId"));
|
||||
traceId.set(request.headers().getFirst("b3"));
|
||||
|
||||
return exchange.exchange(request);
|
||||
}).build().get().uri("http://localhost:" + this.port + "/traceid").retrieve()
|
||||
@@ -531,6 +528,13 @@ public class WebClientTests {
|
||||
configuration = SimpleLoadBalancerClientConfiguration.class)
|
||||
public static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
BaggagePropagation.FactoryBuilder baggagePropagationFactoryBuilder() {
|
||||
// Use b3 single format as it is less verbose
|
||||
return BaggagePropagation.newFactoryBuilder(B3Propagation.newFactoryBuilder()
|
||||
.injectFormat(CLIENT, SINGLE_NO_PARENT).build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
FooController fooController() {
|
||||
return new FooController();
|
||||
@@ -625,26 +629,21 @@ public class WebClientTests {
|
||||
@RestController
|
||||
public static class FooController {
|
||||
|
||||
@Autowired
|
||||
Tracer tracer;
|
||||
|
||||
Span span;
|
||||
|
||||
@RequestMapping(value = "/notrace", method = RequestMethod.GET)
|
||||
public String notrace(
|
||||
@RequestHeader(name = TRACE_ID_NAME, required = false) String traceId) {
|
||||
then(traceId).isNotNull();
|
||||
@RequestHeader(name = "b3", required = false) String b3Single) {
|
||||
then(b3Single).isNotNull();
|
||||
return "OK";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/traceid", method = RequestMethod.GET)
|
||||
public String traceId(@RequestHeader(TRACE_ID_NAME) String traceId,
|
||||
@RequestHeader(SPAN_ID_NAME) String spanId,
|
||||
@RequestHeader(PARENT_ID_NAME) String parentId) {
|
||||
then(traceId).isNotEmpty();
|
||||
then(parentId).isNotEmpty();
|
||||
then(spanId).isNotEmpty();
|
||||
return traceId;
|
||||
public String traceId(@RequestHeader("b3") String b3Single) {
|
||||
TraceContextOrSamplingFlags traceContext = B3SingleFormat
|
||||
.parseB3SingleFormat(b3Single);
|
||||
then(traceContext.context()).isNotNull();
|
||||
return b3Single;
|
||||
}
|
||||
|
||||
@RequestMapping("/")
|
||||
@@ -657,12 +656,10 @@ public class WebClientTests {
|
||||
}
|
||||
|
||||
@RequestMapping("/noresponse")
|
||||
public void noResponse(@RequestHeader(TRACE_ID_NAME) String traceId,
|
||||
@RequestHeader(SPAN_ID_NAME) String spanId,
|
||||
@RequestHeader(PARENT_ID_NAME) String parentId) {
|
||||
then(traceId).isNotEmpty();
|
||||
then(parentId).isNotEmpty();
|
||||
then(spanId).isNotEmpty();
|
||||
public void noResponse(@RequestHeader("b3") String b3Single) {
|
||||
TraceContextOrSamplingFlags traceContext = B3SingleFormat
|
||||
.parseB3SingleFormat(b3Single);
|
||||
then(traceContext.context()).isNotNull();
|
||||
}
|
||||
|
||||
public Span getSpan() {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static tools.SpanUtil.idToHex;
|
||||
|
||||
/**
|
||||
* Runnable that will send a request via the provide rest template to the given url. It
|
||||
@@ -39,9 +40,6 @@ import static org.assertj.core.api.BDDAssertions.then;
|
||||
*/
|
||||
public class RequestSendingRunnable implements Runnable {
|
||||
|
||||
static final String TRACE_ID_NAME = "X-B3-TraceId";
|
||||
static final String SPAN_ID_NAME = "X-B3-SpanId";
|
||||
|
||||
private static final Log log = LogFactory.getLog(RequestSendingRunnable.class);
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
@@ -75,8 +73,7 @@ public class RequestSendingRunnable implements Runnable {
|
||||
|
||||
private RequestEntity<Void> requestWithTraceId() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add(TRACE_ID_NAME, SpanUtil.idToHex(this.traceId));
|
||||
headers.add(SPAN_ID_NAME, SpanUtil.idToHex(this.spanId));
|
||||
headers.add("b3", idToHex(this.traceId) + "-" + idToHex(this.spanId));
|
||||
URI uri = URI.create(this.url);
|
||||
RequestEntity<Void> requestEntity = new RequestEntity<>(headers, HttpMethod.GET,
|
||||
uri);
|
||||
|
||||
@@ -100,10 +100,10 @@ public class ITTracingChannelInterceptorTests implements MessageHandler {
|
||||
// formerly known as TraceChannelInterceptorTest.executableSpanCreation
|
||||
@Test
|
||||
public void propagatesNoopSpan() {
|
||||
this.directChannel.send(
|
||||
MessageBuilder.withPayload("hi").setHeader("X-B3-Sampled", "0").build());
|
||||
this.directChannel
|
||||
.send(MessageBuilder.withPayload("hi").setHeader("b3", "0").build());
|
||||
|
||||
assertThat(this.message.getHeaders()).containsEntry("X-B3-Sampled", "0");
|
||||
assertThat(this.message.getHeaders()).containsEntry("b3", "0");
|
||||
|
||||
assertThat(this.currentSpan.isNoop()).isTrue();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
import brave.Span;
|
||||
import brave.Tracer;
|
||||
import brave.Tracing;
|
||||
import brave.propagation.B3SingleFormat;
|
||||
import brave.propagation.TraceContext;
|
||||
import brave.sampler.Sampler;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -80,19 +82,12 @@ public class TraceContextPropagationChannelInterceptorTests {
|
||||
Message<?> message = this.channel.receive(0);
|
||||
assertThat(message).as("message was null").isNotNull();
|
||||
|
||||
String spanId = message.getHeaders().get(TraceMessageHeaders.SPAN_ID_NAME,
|
||||
String.class);
|
||||
assertThat(spanId).as("spanId was equal to parent's id")
|
||||
String b3 = message.getHeaders().get("b3", String.class);
|
||||
// Trace and Span IDs are implicitly checked
|
||||
TraceContext extracted = B3SingleFormat.parseB3SingleFormat(b3).context();
|
||||
|
||||
assertThat(extracted.spanIdString()).as("spanId was equal to parent's id")
|
||||
.isNotEqualTo(expectedSpanId);
|
||||
|
||||
String traceId = message.getHeaders().get(TraceMessageHeaders.TRACE_ID_NAME,
|
||||
String.class);
|
||||
assertThat(traceId).as("traceId was null").isNotNull();
|
||||
|
||||
String parentId = message.getHeaders().get(TraceMessageHeaders.PARENT_ID_NAME,
|
||||
String.class);
|
||||
assertThat(parentId).as("parentId was not equal to parent's id")
|
||||
.isEqualTo(this.reporter.getSpans().get(0).id());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
import brave.Span;
|
||||
import brave.Tracer;
|
||||
import brave.Tracing;
|
||||
import brave.propagation.B3SingleFormat;
|
||||
import brave.propagation.TraceContext;
|
||||
import brave.sampler.Sampler;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -83,21 +85,12 @@ public class TraceStreamChannelInterceptorTests {
|
||||
Message<?> message = this.channel.receive(0);
|
||||
assertThat(message).as("message was null").isNotNull();
|
||||
|
||||
String spanId = message.getHeaders().get(TraceMessageHeaders.SPAN_ID_NAME,
|
||||
String.class);
|
||||
assertThat(spanId).as("spanId was equal to parent's id")
|
||||
String b3 = message.getHeaders().get("b3", String.class);
|
||||
// Trace and Span IDs are implicitly checked
|
||||
TraceContext extracted = B3SingleFormat.parseB3SingleFormat(b3).context();
|
||||
|
||||
assertThat(extracted.spanIdString()).as("spanId was equal to parent's id")
|
||||
.isNotEqualTo(expectedSpanId);
|
||||
|
||||
String traceId = message.getHeaders().get(TraceMessageHeaders.TRACE_ID_NAME,
|
||||
String.class);
|
||||
assertThat(traceId).as("traceId was null").isNotNull();
|
||||
|
||||
String parentId = message.getHeaders().get(TraceMessageHeaders.PARENT_ID_NAME,
|
||||
String.class);
|
||||
// [0] - producer
|
||||
// [1] - http:testsendmessage
|
||||
assertThat(parentId).as("parentId was not equal to parent's id")
|
||||
.isEqualTo(this.reporter.getSpans().get(1).id());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -28,14 +28,15 @@ import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import brave.Span;
|
||||
import brave.baggage.BaggagePropagation;
|
||||
import brave.http.HttpTracing;
|
||||
import brave.propagation.B3Propagation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.util.SpanUtil;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -49,6 +50,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.filter.GenericFilterBean;
|
||||
|
||||
import static brave.Span.Kind.CLIENT;
|
||||
import static brave.propagation.B3Propagation.Format.SINGLE_NO_PARENT;
|
||||
import static brave.propagation.B3SingleFormat.writeB3SingleFormat;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
@@ -57,9 +61,6 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
@DirtiesContext
|
||||
public class TraceCustomFilterResponseInjectorTests {
|
||||
|
||||
static final String TRACE_ID_NAME = "X-B3-TraceId";
|
||||
static final String SPAN_ID_NAME = "X-B3-SpanId";
|
||||
|
||||
@Autowired
|
||||
RestTemplate restTemplate;
|
||||
|
||||
@@ -80,7 +81,7 @@ public class TraceCustomFilterResponseInjectorTests {
|
||||
ResponseEntity<Map> responseEntity = this.restTemplate.exchange(requestEntity,
|
||||
Map.class);
|
||||
|
||||
then(responseEntity.getHeaders()).containsKeys(TRACE_ID_NAME, SPAN_ID_NAME)
|
||||
then(responseEntity.getHeaders()).containsKey("b3")
|
||||
.as("Trace headers must be present in response headers");
|
||||
}
|
||||
|
||||
@@ -90,6 +91,13 @@ public class TraceCustomFilterResponseInjectorTests {
|
||||
|
||||
int port;
|
||||
|
||||
@Bean
|
||||
BaggagePropagation.FactoryBuilder baggagePropagationFactoryBuilder() {
|
||||
// Use b3 single format as it is less verbose
|
||||
return BaggagePropagation.newFactoryBuilder(B3Propagation.newFactoryBuilder()
|
||||
.injectFormat(CLIENT, SINGLE_NO_PARENT).build());
|
||||
}
|
||||
|
||||
// tag::configuration[]
|
||||
@Bean
|
||||
HttpResponseInjectingTraceFilter responseInjectingTraceFilter(
|
||||
@@ -129,9 +137,7 @@ public class TraceCustomFilterResponseInjectorTests {
|
||||
FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
Span currentSpan = this.httpTracing.tracing().tracer().currentSpan();
|
||||
response.addHeader("X-B3-TraceId", currentSpan.context().traceIdString());
|
||||
response.addHeader("X-B3-SpanId",
|
||||
SpanUtil.idToHex(currentSpan.context().spanId()));
|
||||
response.addHeader("b3", writeB3SingleFormat(currentSpan.context()));
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,12 +69,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
@SpringBootTest(classes = TraceFilterIntegrationTests.Config.class)
|
||||
public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest {
|
||||
|
||||
static final String TRACE_ID_NAME = "X-B3-TraceId";
|
||||
static final String SPAN_ID_NAME = "X-B3-SpanId";
|
||||
static final String SAMPLED_NAME = "X-B3-Sampled";
|
||||
|
||||
private static Log logger = LogFactory.getLog(TraceFilterIntegrationTests.class);
|
||||
|
||||
private static Span span;
|
||||
|
||||
@Autowired
|
||||
@@ -244,72 +238,69 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest {
|
||||
}
|
||||
|
||||
private MvcResult whenSentPingWithTraceId(Long passedTraceId) throws Exception {
|
||||
return sendPingWithTraceId(TRACE_ID_NAME, passedTraceId);
|
||||
return sendPingWithTraceId(passedTraceId);
|
||||
}
|
||||
|
||||
private MvcResult whenSentInfoWithTraceId(Long passedTraceId) throws Exception {
|
||||
return sendRequestWithTraceId("/additionalContextPath/info", TRACE_ID_NAME,
|
||||
passedTraceId);
|
||||
return sendRequestWithTraceId("/additionalContextPath/info", passedTraceId);
|
||||
}
|
||||
|
||||
private MvcResult whenSentFutureWithTraceId(Long passedTraceId) throws Exception {
|
||||
return sendRequestWithTraceId("/future", TRACE_ID_NAME, passedTraceId);
|
||||
return sendRequestWithTraceId("/future", passedTraceId);
|
||||
}
|
||||
|
||||
private MvcResult whenSentDeferredWithTraceId(Long passedTraceId) throws Exception {
|
||||
return sendDeferredWithTraceId(TRACE_ID_NAME, passedTraceId);
|
||||
return sendDeferredWithTraceId(passedTraceId);
|
||||
}
|
||||
|
||||
private MvcResult whenSentToNonExistentEndpointWithTraceId(Long passedTraceId)
|
||||
throws Exception {
|
||||
return sendRequestWithTraceId("/exception/nonExistent", TRACE_ID_NAME,
|
||||
passedTraceId, HttpStatus.NOT_FOUND);
|
||||
return sendRequestWithTraceId("/exception/nonExistent", passedTraceId,
|
||||
HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
private MvcResult whenSentToExceptionThrowingEndpoint(Long passedTraceId)
|
||||
throws Exception {
|
||||
return sendRequestWithTraceId("/throwsException", TRACE_ID_NAME, passedTraceId,
|
||||
return sendRequestWithTraceId("/throwsException", passedTraceId,
|
||||
HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
private MvcResult sendPingWithTraceId(String headerName, Long traceId)
|
||||
throws Exception {
|
||||
return sendRequestWithTraceId("/ping", headerName, traceId);
|
||||
private MvcResult sendPingWithTraceId(Long traceId) throws Exception {
|
||||
return sendRequestWithTraceId("/ping", traceId);
|
||||
}
|
||||
|
||||
private MvcResult sendDeferredWithTraceId(String headerName, Long traceId)
|
||||
throws Exception {
|
||||
return sendRequestWithTraceId("/deferred", headerName, traceId);
|
||||
private MvcResult sendDeferredWithTraceId(Long traceId) throws Exception {
|
||||
return sendRequestWithTraceId("/deferred", traceId);
|
||||
}
|
||||
|
||||
private MvcResult sendRequestWithTraceId(String path, String headerName, Long traceId)
|
||||
throws Exception {
|
||||
private MvcResult sendRequestWithTraceId(String path, Long traceId) throws Exception {
|
||||
return this.mockMvc
|
||||
.perform(MockMvcRequestBuilders.get(path).accept(MediaType.TEXT_PLAIN)
|
||||
.header(headerName, SpanUtil.idToHex(traceId))
|
||||
.header(SPAN_ID_NAME, SpanUtil.idToHex(new Random().nextLong())))
|
||||
.header("b3",
|
||||
SpanUtil.idToHex(traceId) + "-"
|
||||
+ SpanUtil.idToHex(new Random().nextLong())))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
private MvcResult whenSentRequestWithTraceIdAndNoSpanId(Long traceId)
|
||||
throws Exception {
|
||||
return this.mockMvc
|
||||
.perform(MockMvcRequestBuilders.get("/ping").accept(MediaType.TEXT_PLAIN)
|
||||
.header(TRACE_ID_NAME, SpanUtil.idToHex(traceId)))
|
||||
return this.mockMvc.perform(MockMvcRequestBuilders.get("/ping")
|
||||
.accept(MediaType.TEXT_PLAIN).header("b3", SpanUtil.idToHex(traceId)))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
private MvcResult sendRequestWithTraceId(String path, String headerName, Long traceId,
|
||||
HttpStatus status) throws Exception {
|
||||
private MvcResult sendRequestWithTraceId(String path, Long traceId, HttpStatus status)
|
||||
throws Exception {
|
||||
return this.mockMvc
|
||||
.perform(MockMvcRequestBuilders.get(path).accept(MediaType.TEXT_PLAIN)
|
||||
.header(headerName, SpanUtil.idToHex(traceId))
|
||||
.header(SPAN_ID_NAME, SpanUtil.idToHex(new Random().nextLong())))
|
||||
.header("b3",
|
||||
SpanUtil.idToHex(traceId) + "-"
|
||||
+ SpanUtil.idToHex(new Random().nextLong())))
|
||||
.andExpect(status().is(status.value())).andReturn();
|
||||
}
|
||||
|
||||
private boolean notSampledHeaderIsPresent(MvcResult mvcResult) {
|
||||
return "0".equals(mvcResult.getResponse().getHeader(SAMPLED_NAME));
|
||||
return "0".equals(mvcResult.getResponse().getHeader("b3"));
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
|
||||
@@ -52,9 +52,6 @@ public class GH1102Tests {
|
||||
@Autowired
|
||||
TestRetry testRetry;
|
||||
|
||||
@Autowired
|
||||
ArrayListSpanReporter reporter;
|
||||
|
||||
@LocalServerPort
|
||||
int port;
|
||||
|
||||
@@ -73,6 +70,7 @@ public class GH1102Tests {
|
||||
foo.finish();
|
||||
}
|
||||
|
||||
// Default inject format for client spans is B3 multi
|
||||
BDDAssertions.then(this.testRetry.getHttpHeaders().get("x-b3-traceid"))
|
||||
.hasSize(1);
|
||||
}
|
||||
|
||||
@@ -155,8 +155,7 @@ public class TraceWebFluxTests {
|
||||
private ClientResponse whenNonSampledRequestIsSent(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/api/c2/10")
|
||||
.header("X-B3-SpanId", EXPECTED_TRACE_ID)
|
||||
.header("X-B3-TraceId", EXPECTED_TRACE_ID).header("X-B3-Sampled", "0")
|
||||
.header("b3", EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0")
|
||||
.exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user