Updates to Brave 5.12 and introduces SpanHandler (#1632)

`SpanHandler` is the base type for the now deprecated `FinishedSpanHandler`.

Notable, it can not just handle things at the end of a recording, but also the
beginning.

For example, this permits set-once baggage without the HTTP abstraction:
```java
static final BaggageField EPOCH_SECONDS = BaggageField.create("epoch_seconds");

static final class RootOnlyBaggage extends SpanHandler {
  @Override
  public boolean begin(TraceContext context, MutableSpan span, @Nullable TraceContext parent) {
    if (EPOCH_SECONDS.getValue(context) == null) { // only set at the first span
      long epochSeconds = System.currentTimeMillis() / 1000;
      EPOCH_SECONDS.updateValue(context, String.valueOf(epochSeconds));
    }
    return true;
  }

  @Override public boolean end(TraceContext context, MutableSpan span, Cause cause) {
    Tags.BAGGAGE_FIELD.tag(EPOCH_SECONDS, context, span);
    return true;
  }
}
```

As the parent is available, it can also facilitate advanced tasks like counting
children, or summarizing entire local roots.

See https://github.com/openzipkin/brave/tree/master/brave/src/test/java/brave/features/handler
and https://github.com/openzipkin/brave/blob/master/brave/src/main/java/brave/handler/SpanHandler.java for more
This commit is contained in:
Adrian Cole
2020-05-16 14:01:38 +08:00
committed by GitHub
parent d4088dec9c
commit b1d39ce291
21 changed files with 82 additions and 74 deletions

View File

@@ -33,7 +33,7 @@
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
<brave.version>5.11.2</brave.version>
<brave.version>5.12.0</brave.version>
<okhttp.version>3.14.6</okhttp.version>
</properties>

View File

@@ -33,7 +33,7 @@
|spring.sleuth.messaging.rabbit.remote-service-name | rabbitmq |
|spring.sleuth.opentracing.enabled | true |
|spring.sleuth.propagation-keys | | List of fields that are referenced the same in-process as it is on the wire. For example, the name "x-vcap-request-id" would be set as-is including the prefix. <p> Note: {@code fieldName} will be implicitly lower-cased. @see brave.propagation.ExtraFieldPropagation.FactoryBuilder#addField(String)
|spring.sleuth.propagation.tag.enabled | true | Enables a {@link TagPropagationFinishedSpanHandler} that adds extra propagated fields to span tags.
|spring.sleuth.propagation.tag.enabled | true | Enables a {@link TagPropagationSpanHandler} that adds extra propagated fields to span tags.
|spring.sleuth.propagation.tag.whitelisted-keys | | A list of keys to be put from extra propagation fields to span tags.
|spring.sleuth.reactor.decorate-on-each | true | When true decorates on each operator, will be less performing, but logging will always contain the tracing entries in each operator. When false decorates on last operator, will be more performing, but logging might not always contain the tracing entries.
|spring.sleuth.reactor.enabled | true | When true enables instrumentation for reactor.

View File

@@ -971,17 +971,17 @@ spring.zipkin.service.name: myService
=== Customization of Reported Spans
Before reporting spans (for example, to Zipkin) you may want to modify that span in some way.
You can do so by using the `FinishedSpanHandler` interface.
You can do so by implementing a `SpanHandler`.
In Sleuth, we generate spans with a fixed name.
Some users want to modify the name depending on values of tags.
You can implement the `FinishedSpanHandler` interface to alter that name.
You can implement the `SpanHandler` interface to alter that name.
The following example shows how to register two beans that implement `FinishedSpanHandler`:
The following example shows how to register two beans that implement `SpanHandler`:
[source,java]
----
include::{project-root}//spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/FinishedSpanHandlerTests.java[tags=finishedSpanHandler,indent=0]
include::{project-root}//spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java[tags=spanHandler,indent=0]
----
The preceding example results in changing the name of the reported span to `foo bar`, just before it gets reported (for example, to Zipkin).

View File

@@ -264,7 +264,7 @@
<spring-cloud-stream.version>Horsham.SR3</spring-cloud-stream.version>
<spring-cloud-netflix.version>2.2.3.BUILD-SNAPSHOT</spring-cloud-netflix.version>
<spring-cloud-openfeign.version>2.2.3.BUILD-SNAPSHOT</spring-cloud-openfeign.version>
<brave.version>5.11.2</brave.version>
<brave.version>5.12.0</brave.version>
<spring-security-boot-autoconfigure.version>2.1.7.RELEASE</spring-security-boot-autoconfigure.version>
<spring-cloud-aws.version>2.2.1.RELEASE</spring-cloud-aws.version>
<disable.nohttp.checks>false</disable.nohttp.checks>

View File

@@ -21,7 +21,7 @@ import zipkin2.Span;
/**
* Deprecated Span Adjuster.
*
* @deprecated use {@link brave.handler.FinishedSpanHandler}
* @deprecated use {@link brave.handler.SpanHandler}
* @author Marcin Grzejszczak
*/
@Deprecated

View File

@@ -25,7 +25,7 @@ import brave.ErrorParser;
import brave.Tracer;
import brave.Tracing;
import brave.TracingCustomizer;
import brave.handler.FinishedSpanHandler;
import brave.handler.SpanHandler;
import brave.propagation.B3Propagation;
import brave.propagation.CurrentTraceContext;
import brave.propagation.CurrentTraceContextCustomizer;
@@ -94,7 +94,7 @@ public class TraceAutoConfiguration {
List<SpanAdjuster> spanAdjusters = new ArrayList<>();
@Autowired(required = false)
List<FinishedSpanHandler> finishedSpanHandlers = new ArrayList<>();
List<SpanHandler> spanHandlers = new ArrayList<>();
@Autowired(required = false)
ExtraFieldPropagation.FactoryBuilder extraFieldPropagationFactoryBuilder;
@@ -121,8 +121,8 @@ public class TraceAutoConfiguration {
spanReporters != null ? spanReporters : Collections.emptyList()))
.traceId128Bit(sleuthProperties.isTraceId128())
.supportsJoin(sleuthProperties.isSupportsJoin());
for (FinishedSpanHandler finishedSpanHandlerFactory : this.finishedSpanHandlers) {
builder.addFinishedSpanHandler(finishedSpanHandlerFactory);
for (SpanHandler spanHandlerFactory : this.spanHandlers) {
builder.addSpanHandler(spanHandlerFactory);
}
for (TracingCustomizer customizer : this.tracingCustomizers) {
customizer.customize(builder);

View File

@@ -16,8 +16,8 @@
package org.springframework.cloud.sleuth.log;
import brave.internal.HexCodec;
import brave.internal.Nullable;
import brave.internal.codec.HexCodec;
import brave.propagation.CurrentTraceContext;
import brave.propagation.TraceContext;
import org.slf4j.Logger;

View File

@@ -16,7 +16,7 @@
package org.springframework.cloud.sleuth.propagation;
import brave.handler.FinishedSpanHandler;
import brave.handler.SpanHandler;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -45,8 +45,7 @@ public class SleuthTagPropagationAutoConfiguration {
protected static class TagPropagationConfiguration {
@Bean
static FinishedSpanHandler sleuthFinishedSpanHandler(
SleuthProperties sleuthProperties,
static SpanHandler tagPropagationSpanHandler(SleuthProperties sleuthProperties,
SleuthTagPropagationProperties tagPropagationProperties) {
return new TagPropagationFinishedSpanHandler(sleuthProperties,
tagPropagationProperties);

View File

@@ -34,8 +34,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
public class SleuthTagPropagationProperties {
/**
* Enables a {@link TagPropagationFinishedSpanHandler} that adds extra propagated
* fields to span tags.
* Enables a {@link TagPropagationSpanHandler} that adds extra propagated fields to
* span tags.
*/
private boolean enabled = true;

View File

@@ -17,7 +17,7 @@
package org.springframework.cloud.sleuth.sampler;
import brave.TracingCustomizer;
import brave.handler.FinishedSpanHandler;
import brave.handler.SpanHandler;
import brave.sampler.Sampler;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
@@ -48,7 +48,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
* <ul>
* <li>{@code zipkin2.reporter.Reporter} - what's used by Zipkin or others like
* Stackdriver</li>
* <li>{@link FinishedSpanHandler} - only accepts sampled data</li>
* <li>{@link SpanHandler} - only accepts sampled data</li>
* <li>{@link TracingCustomizer} - can configure one of the above</li>
* </ul>
*
@@ -69,8 +69,8 @@ final class SamplerCondition extends AnyNestedCondition {
}
@ConditionalOnBean(FinishedSpanHandler.class)
static final class FinishedSpanHandlerAvailable {
@ConditionalOnBean(SpanHandler.class)
static final class SpanHandlerAvailable {
}

View File

@@ -18,8 +18,8 @@ package org.springframework.cloud.sleuth;
import brave.Span;
import brave.Tracer;
import brave.handler.FinishedSpanHandler;
import brave.handler.MutableSpan;
import brave.handler.SpanHandler;
import brave.propagation.TraceContext;
import brave.sampler.Sampler;
import org.assertj.core.api.BDDAssertions;
@@ -42,10 +42,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Marcin Grzejszczak
*/
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = FinishedSpanHandlerTests.FinishedSpanHandlerAspectTestsConfig.class,
@SpringBootTest(classes = SpanHandlerTests.SpanHandlerAspectTestsConfig.class,
webEnvironment = NONE)
public class FinishedSpanHandlerTests {
public class SpanHandlerTests {
@Autowired
ArrayListSpanReporter reporter;
@@ -65,7 +64,7 @@ public class FinishedSpanHandlerTests {
@Configuration
@EnableAutoConfiguration(exclude = IntegrationAutoConfiguration.class)
static class FinishedSpanHandlerAspectTestsConfig {
static class SpanHandlerAspectTestsConfig {
@Bean
Sampler sampler() {
@@ -77,12 +76,13 @@ public class FinishedSpanHandlerTests {
return new ArrayListSpanReporter();
}
// tag::finishedSpanHandler[]
// tag::spanHandler[]
@Bean
FinishedSpanHandler handlerOne() {
return new FinishedSpanHandler() {
SpanHandler handlerOne() {
return new SpanHandler() {
@Override
public boolean handle(TraceContext traceContext, MutableSpan span) {
public boolean end(TraceContext traceContext, MutableSpan span,
Cause cause) {
span.name("foo");
return true; // keep this span
}
@@ -90,16 +90,17 @@ public class FinishedSpanHandlerTests {
}
@Bean
FinishedSpanHandler handlerTwo() {
return new FinishedSpanHandler() {
SpanHandler handlerTwo() {
return new SpanHandler() {
@Override
public boolean handle(TraceContext traceContext, MutableSpan span) {
public boolean end(TraceContext traceContext, MutableSpan span,
Cause cause) {
span.name(span.name() + " bar");
return true; // keep this span
}
};
}
// end::finishedSpanHandler[]
// end::spanHandler[]
}

View File

@@ -17,6 +17,7 @@
package org.springframework.cloud.sleuth.autoconfig;
import brave.propagation.B3Propagation;
import brave.propagation.B3Propagation.Format;
import brave.propagation.B3SinglePropagation;
import brave.propagation.ExtraFieldPropagation;
import brave.propagation.Propagation;
@@ -33,6 +34,12 @@ import org.springframework.context.support.GenericApplicationContext;
public class TraceAutoConfigurationPropagationCustomizationTests {
// Default for spring-messaging is on 2.2.x is MULTI, though 3.x it is
// SINGLE_NO_PARENT
// spring-cloud/spring-cloud-sleuth#1607
Propagation.Factory defaultB3Propagation = B3Propagation.newFactoryBuilder()
.injectFormat(Format.MULTI).build();
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class));
@@ -40,7 +47,7 @@ public class TraceAutoConfigurationPropagationCustomizationTests {
public void stillCreatesDefault() {
this.contextRunner.run((context) -> {
BDDAssertions.then(context.getBean(Propagation.Factory.class))
.isEqualTo(B3Propagation.FACTORY);
.isEqualTo(defaultB3Propagation);
});
}

View File

@@ -18,8 +18,8 @@ package org.springframework.cloud.sleuth.sampler;
import brave.Tracing;
import brave.TracingCustomizer;
import brave.handler.FinishedSpanHandler;
import brave.handler.MutableSpan;
import brave.handler.SpanHandler;
import brave.propagation.TraceContext;
import brave.sampler.RateLimitingSampler;
import brave.sampler.Sampler;
@@ -52,12 +52,11 @@ public class SamplerAutoConfigurationTests {
}
@Test
public void should_use_RateLimitedSampler_withFinishedSpanHandler() {
this.contextRunner.withUserConfiguration(WithFinishedSpanHandler.class)
.run((context -> {
final Sampler bean = context.getBean(Sampler.class);
BDDAssertions.then(bean).isInstanceOf(RateLimitingSampler.class);
}));
public void should_use_RateLimitedSampler_withSpanHandler() {
this.contextRunner.withUserConfiguration(WithSpanHandler.class).run((context -> {
final Sampler bean = context.getBean(Sampler.class);
BDDAssertions.then(bean).isInstanceOf(RateLimitingSampler.class);
}));
}
@Test
@@ -138,13 +137,13 @@ public class SamplerAutoConfigurationTests {
}
@Configuration
static class WithFinishedSpanHandler {
static class WithSpanHandler {
@Bean
FinishedSpanHandler finishedSpanHandler() {
return new FinishedSpanHandler() {
SpanHandler spanHandler() {
return new SpanHandler() {
@Override
public boolean handle(TraceContext context, MutableSpan span) {
public boolean end(TraceContext context, MutableSpan span, Cause cause) {
return true;
}
};

View File

@@ -31,8 +31,8 @@
<name>spring-cloud-sleuth-dependencies</name>
<description>Spring Cloud Sleuth Dependencies</description>
<properties>
<brave.version>5.11.2</brave.version>
<brave.opentracing.version>0.36.2</brave.opentracing.version>
<brave.version>5.12.0</brave.version>
<brave.opentracing.version>0.37.0</brave.opentracing.version>
<grpc.spring.boot.version>3.4.1</grpc.spring.boot.version>
</properties>
<dependencyManagement>
@@ -69,6 +69,12 @@
<groupId>io.opentracing.brave</groupId>
<artifactId>brave-opentracing</artifactId>
<version>${brave.opentracing.version}</version>
<exclusions>
<exclusion>
<groupId>io.zipkin.brave</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- GRPC -->
<dependency>

View File

@@ -70,11 +70,6 @@
<artifactId>spring-cloud-sleuth-sample-test-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>zipkin</artifactId>
<version>2.19.3</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -105,10 +105,6 @@
<artifactId>awaitility</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>zipkin</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>

View File

@@ -79,6 +79,10 @@
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-kafka</artifactId>

View File

@@ -21,8 +21,8 @@ import java.util.concurrent.TimeoutException;
import brave.Span;
import brave.Tracing;
import brave.handler.FinishedSpanHandler;
import brave.handler.MutableSpan;
import brave.handler.SpanHandler;
import brave.propagation.TraceContext;
import brave.sampler.Sampler;
import okhttp3.mockwebserver.MockWebServer;
@@ -405,10 +405,11 @@ public class ZipkinAutoConfigurationTests {
protected static class HandlerHanldersConfig {
@Bean
FinishedSpanHandler handlerOne() {
return new FinishedSpanHandler() {
SpanHandler handlerOne() {
return new SpanHandler() {
@Override
public boolean handle(TraceContext traceContext, MutableSpan span) {
public boolean end(TraceContext traceContext, MutableSpan span,
Cause cause) {
span.name("foo");
return true; // keep this span
}
@@ -416,10 +417,11 @@ public class ZipkinAutoConfigurationTests {
}
@Bean
FinishedSpanHandler handlerTwo() {
return new FinishedSpanHandler() {
SpanHandler handlerTwo() {
return new SpanHandler() {
@Override
public boolean handle(TraceContext traceContext, MutableSpan span) {
public boolean end(TraceContext traceContext, MutableSpan span,
Cause cause) {
span.name(span.name() + " bar");
return true; // keep this span
}

View File

@@ -5,7 +5,7 @@
<suppressions>
<suppress files=".*/test/.*" checks="JavadocVariable"/>
<suppress files=".*ReactorSleuth\.java" checks="InnerAssignment"/>
<suppress files=".*FinishedSpanHandlerTests.*" checks="LineLengthCheck"/>
<suppress files=".*SpanHandlerTests.*" checks="LineLengthCheck"/>
<suppress files=".*GrpcTracingIntegrationTests.*" checks="LineLengthCheck"/>
<suppress files=".*IgnoreAutoConfiguredSkipPatternsIntegrationTests.*" checks="LineLengthCheck"/>
<suppress files=".*RestTemplateTraceAspectIntegrationTests.*" checks="LineLengthCheck"/>
@@ -16,7 +16,7 @@
<suppress files=".*SleuthNewSpanParserAnnotationDisableTests.*" checks="LineLengthCheck"/>
<suppress files=".*SpanAdjusterTests.*" checks="LineLengthCheck"/>
<suppress files=".*SpringDataInstrumentationTests.*" checks="LineLengthCheck"/>
<suppress files=".*TagPropagationFinishedSpanHandlerTest.*" checks="LineLengthCheck"/>
<suppress files=".*TagPropagationSpanHandlerTest.*" checks="LineLengthCheck"/>
<suppress files=".*TraceAsyncIntegrationTests.*" checks="LineLengthCheck"/>
<suppress files=".*TraceAutoConfigurationWithDisabledSleuthTests.*" checks="LineLengthCheck"/>
<suppress files=".*TraceFilterIntegrationTests.*" checks="LineLengthCheck"/>

View File

@@ -23,8 +23,8 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import brave.Span.Kind;
import brave.handler.FinishedSpanHandler;
import brave.handler.MutableSpan;
import brave.handler.SpanHandler;
import brave.http.HttpRequest;
import brave.http.HttpRequestParser;
import brave.propagation.CurrentTraceContext;
@@ -174,11 +174,10 @@ public class TraceFilterWebIntegrationTests {
}
@Bean
FinishedSpanHandler uncaughtExceptionThrown(
CurrentTraceContext currentTraceContext) {
return new FinishedSpanHandler() {
SpanHandler uncaughtExceptionThrown(CurrentTraceContext currentTraceContext) {
return new SpanHandler() {
@Override
public boolean handle(TraceContext context, MutableSpan span) {
public boolean end(TraceContext context, MutableSpan span, Cause cause) {
if (span.kind() != Kind.SERVER || span.error() == null
|| !log.isErrorEnabled()) {
return true; // don't add overhead as we only log server errors

View File

@@ -34,10 +34,10 @@ import org.reactivestreams.Subscription;
import reactor.core.publisher.BaseSubscriber;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import zipkin2.Span;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static brave.Span.Kind.CLIENT;
import static org.assertj.core.api.Assertions.assertThat;
/**
@@ -161,7 +161,7 @@ abstract class ITSpringConfiguredReactorClient
assertThat(server.getRequestCount()).isOne();
reporter.takeRemoteSpanWithError(Span.Kind.CLIENT, "CANCELLED");
this.spanHandler.takeRemoteSpanWithErrorMessage(CLIENT, "CANCELLED");
}
}