Merge pull request #35165 from jonatan-ivanov

* pr/35165:
  Support Brave's joint spans

Closes gh-35165
This commit is contained in:
Jonatan Ivanov
2023-05-03 17:24:43 -07:00
3 changed files with 75 additions and 7 deletions

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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() {