Support Brave's joint spans
Brave has a feature called joint spans that was enabled by default with Spring Cloud Sleuth (and Boot 2.x). This has changed with Micrometer Tracing and Boot 3.x. In order to make migration simpler, joint spans should be set through a property. This is a Brave+B3-only feature, W3C is not supported by Brave and OTel does not have this capability. See gh-35165
This commit is contained in:
@@ -54,12 +54,14 @@ import io.micrometer.tracing.exporter.SpanFilter;
|
||||
import io.micrometer.tracing.exporter.SpanReporter;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.IncompatibleConfigurationException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
@@ -71,6 +73,7 @@ import org.springframework.core.env.Environment;
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Jonatan Ivanov
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class)
|
||||
@@ -97,14 +100,19 @@ public class BraveAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Tracing braveTracing(Environment environment, List<SpanHandler> spanHandlers,
|
||||
public Tracing braveTracing(Environment environment, TracingProperties properties, List<SpanHandler> spanHandlers,
|
||||
List<TracingCustomizer> tracingCustomizers, CurrentTraceContext currentTraceContext,
|
||||
Factory propagationFactory, Sampler sampler) {
|
||||
if (properties.getPropagation().getType() == PropagationType.W3C
|
||||
&& properties.getBrave().isSpanJoiningSupported()) {
|
||||
throw new IncompatibleConfigurationException("management.tracing.propagation.type",
|
||||
"management.tracing.brave.span-joining-supported");
|
||||
}
|
||||
String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
|
||||
Builder builder = Tracing.newBuilder()
|
||||
.currentTraceContext(currentTraceContext)
|
||||
.traceId128Bit(true)
|
||||
.supportsJoin(false)
|
||||
.supportsJoin(properties.getBrave().isSpanJoiningSupported())
|
||||
.propagationFactory(propagationFactory)
|
||||
.sampler(sampler)
|
||||
.localServiceName(applicationName);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
* Configuration properties for tracing.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Jonatan Ivanov
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@ConfigurationProperties("management.tracing")
|
||||
@@ -50,6 +51,11 @@ public class TracingProperties {
|
||||
*/
|
||||
private final Propagation propagation = new Propagation();
|
||||
|
||||
/**
|
||||
* Brave configuration.
|
||||
*/
|
||||
private final Brave brave = new Brave();
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
@@ -70,6 +76,10 @@ public class TracingProperties {
|
||||
return this.propagation;
|
||||
}
|
||||
|
||||
public Brave getBrave() {
|
||||
return this.brave;
|
||||
}
|
||||
|
||||
public static class Sampling {
|
||||
|
||||
/**
|
||||
@@ -194,4 +204,23 @@ public class TracingProperties {
|
||||
|
||||
}
|
||||
|
||||
public static class Brave {
|
||||
|
||||
/**
|
||||
* Whether the propagation type and tracing backend support sharing the span ID
|
||||
* between client and server spans. Requires B3 propagation and a compatible
|
||||
* backend.
|
||||
*/
|
||||
private boolean spanJoiningSupported = false;
|
||||
|
||||
public boolean isSpanJoiningSupported() {
|
||||
return this.spanJoiningSupported;
|
||||
}
|
||||
|
||||
public void setSpanJoiningSupported(boolean spanJoiningSupported) {
|
||||
this.spanJoiningSupported = spanJoiningSupported;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfigurationTests.SpanHandlerConfiguration.AdditionalSpanHandler;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.context.properties.IncompatibleConfigurationException;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -50,12 +51,14 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link BraveAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Jonatan Ivanov
|
||||
*/
|
||||
class BraveAutoConfigurationTests {
|
||||
|
||||
@@ -216,17 +219,45 @@ class BraveAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupportJoinedSpans() {
|
||||
void shouldNotSupportJoinedSpansByDefault() {
|
||||
this.contextRunner.run((context) -> {
|
||||
Tracing tracing = context.getBean(Tracing.class);
|
||||
Span parentSpan = tracing.tracer().nextSpan();
|
||||
Span childSpan = tracing.tracer().joinSpan(parentSpan.context());
|
||||
assertThat(parentSpan.context().traceIdString()).isEqualTo(childSpan.context().traceIdString());
|
||||
assertThat(parentSpan.context().spanIdString()).isEqualTo(childSpan.context().parentIdString());
|
||||
assertThat(parentSpan.context().spanIdString()).isNotEqualTo(childSpan.context().spanIdString());
|
||||
assertThat(childSpan.context().traceIdString()).isEqualTo(parentSpan.context().traceIdString());
|
||||
assertThat(childSpan.context().spanIdString()).isNotEqualTo(parentSpan.context().spanIdString());
|
||||
assertThat(childSpan.context().parentIdString()).isEqualTo(parentSpan.context().spanIdString());
|
||||
assertThat(parentSpan.context().parentIdString()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupportJoinedSpansIfB3UsedAndBackendSupportsIt() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("management.tracing.propagation.type=B3",
|
||||
"management.tracing.brave.span-joining-supported=true")
|
||||
.run((context) -> {
|
||||
Tracing tracing = context.getBean(Tracing.class);
|
||||
Span parentSpan = tracing.tracer().nextSpan();
|
||||
Span childSpan = tracing.tracer().joinSpan(parentSpan.context());
|
||||
assertThat(childSpan.context().traceIdString()).isEqualTo(parentSpan.context().traceIdString());
|
||||
assertThat(childSpan.context().spanIdString()).isEqualTo(parentSpan.context().spanIdString());
|
||||
assertThat(childSpan.context().parentIdString()).isNull();
|
||||
assertThat(parentSpan.context().parentIdString()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailIfSupportJoinedSpansIsEnabledAndW3cIsChosen() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("management.tracing.propagation.type=W3C",
|
||||
"management.tracing.brave.span-joining-supported=true")
|
||||
.run((context) -> assertThatThrownBy(() -> context.getBean(Tracing.class)).rootCause()
|
||||
.isExactlyInstanceOf(IncompatibleConfigurationException.class)
|
||||
.hasMessage(
|
||||
"The following configuration properties have incompatible values: [management.tracing.propagation.type, management.tracing.brave.span-joining-supported]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
void compositeSpanHandlerShouldBeFirstSpanHandler() {
|
||||
|
||||
Reference in New Issue
Block a user