diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index a938c9242..b159bdc9a 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -34,6 +34,7 @@ 1.8 1.8 2.1.0.M1 + 5.4.3 @@ -65,6 +66,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.boot spring-boot-configuration-processor @@ -108,6 +113,21 @@ ${jmh.version} provided + + com.squareup.okhttp3 + okhttp + 3.11.0 + provided + + + io.zipkin.brave + brave-instrumentation-httpclient + ${brave.version} + + + org.apache.httpcomponents + httpclient + diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/SleuthBenchmarkingSpringApp.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java similarity index 98% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/SleuthBenchmarkingSpringApp.java rename to benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java index 3a0b7dfca..b14491b47 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/SleuthBenchmarkingSpringApp.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.app; +package org.springframework.cloud.sleuth.benchmarks.app.mvc; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java new file mode 100644 index 000000000..a9b3e58f1 --- /dev/null +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java @@ -0,0 +1,96 @@ +/* + * Copyright 2013-2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.springframework.cloud.sleuth.benchmarks.app.webflux; + +import brave.Tracer; +import brave.sampler.Sampler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent; +import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.util.SocketUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import zipkin2.Span; +import zipkin2.reporter.Reporter; + +import java.util.regex.Pattern; + + +/** + * @author alvin + */ +@SpringBootApplication +@RestController +public class SleuthBenchmarkingSpringWebFluxApp implements ApplicationListener { + + private static final Log log = LogFactory.getLog(SleuthBenchmarkingSpringWebFluxApp.class); + + public int port; + + @RequestMapping("/foo") + public Mono foo() { + return Mono.just("foo"); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + SkipPatternProvider patternProvider() { + return () -> Pattern.compile(""); + } + + + @Bean + NettyReactiveWebServerFactory nettyReactiveWebServerFactory(@Value("${server.port:0}") int serverPort) { + log.info("Starting container at port [" + serverPort + "]"); + return new NettyReactiveWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); + } + + public static void main(String... args) { + new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) + .web(WebApplicationType.REACTIVE) + .application() + .run(args); + } + + @Bean + public Reporter reporter() { + return Reporter.NOOP; + } + + + + @Override + public void onApplicationEvent(ReactiveWebServerInitializedEvent event) { + this.port = event.getWebServer().getPort(); + } +} + diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java index a25cc1385..faa2f2f5b 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java @@ -31,7 +31,7 @@ import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.annotations.Threads; import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; import org.springframework.context.ConfigurableApplicationContext; import static org.assertj.core.api.BDDAssertions.then; @@ -75,4 +75,4 @@ public class AnnotationBenchmarks { throws Exception { then(context.sleuth.newSpan()).isEqualTo("continued"); } -} \ No newline at end of file +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java index 36655d45c..aec98b55c 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java @@ -30,7 +30,7 @@ import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.annotations.Threads; import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; import org.springframework.context.ConfigurableApplicationContext; import static org.assertj.core.api.BDDAssertions.then; @@ -86,4 +86,4 @@ public class AsyncBenchmarks { throws Exception { then(context.tracedAsyncMethodHavingBean.async().get()).isEqualTo("async"); } -} \ No newline at end of file +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java index 8e627118e..eaf456195 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java @@ -39,7 +39,7 @@ import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.annotations.Threads; import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.http.MediaType; import org.springframework.mock.web.MockFilterChain; @@ -167,4 +167,4 @@ public class HttpFilterBenchmarks { return () -> "vanilla"; } } -} \ No newline at end of file +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/ProcessLauncherState.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/ProcessLauncherState.java index 8c4f1978f..1250cded9 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/ProcessLauncherState.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/ProcessLauncherState.java @@ -30,7 +30,7 @@ import java.util.List; import org.openjdk.jmh.util.FileUtils; import org.openjdk.jmh.util.Utils; -import org.springframework.cloud.sleuth.benchmarks.app.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; public class ProcessLauncherState { @@ -140,4 +140,4 @@ public class ProcessLauncherState { public File getHome() { return home; } -} \ No newline at end of file +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java index a9ceb6e41..836341c4c 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java @@ -34,7 +34,7 @@ import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.annotations.Threads; import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.benchmarks.app.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.web.client.MockMvcClientHttpRequestFactory; import org.springframework.test.web.servlet.MockMvc; @@ -96,4 +96,4 @@ public class RestTemplateBenchmark { then(context.tracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo"); } -} \ No newline at end of file +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java new file mode 100644 index 000000000..77aa164ee --- /dev/null +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java @@ -0,0 +1,185 @@ +/* + * Copyright 2013-2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; + +import brave.Tracing; +import brave.http.HttpTracing; +import brave.httpclient.TracingHttpClientBuilder; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; +import brave.sampler.Sampler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.benchmarks.app.webflux.SleuthBenchmarkingSpringWebFluxApp; +import org.springframework.context.ConfigurableApplicationContext; +import zipkin2.reporter.Reporter; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +@Measurement(iterations = 5, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(3) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(2) +@State(Scope.Benchmark) +public class SpringWebFluxBenchmarks { + + protected ConfigurableApplicationContext applicationContext; + protected SleuthBenchmarkingSpringWebFluxApp springWebFluxApp; + CloseableHttpClient client; + CloseableHttpClient tracedClient; + CloseableHttpClient unsampledClient; + + protected static TraceContext defaultTraceContext = + TraceContext.newBuilder().traceIdHigh(333L).traceId(444L).spanId(3).sampled(true).build(); + + public String getBaseUrl() { + return baseUrl; + } + + private String baseUrl; + + protected CloseableHttpClient newClient(HttpTracing httpTracing) { + return TracingHttpClientBuilder.create(httpTracing) + .disableAutomaticRetries() + .build(); + } + + protected CloseableHttpClient newClient() { + return HttpClients.custom() + .disableAutomaticRetries() + .build(); + } + + protected void get(CloseableHttpClient client) throws Exception { + EntityUtils.consume(client.execute(new HttpGet(getBaseUrl())).getEntity()); + } + + protected void close(CloseableHttpClient client) throws IOException { + client.close(); + } + + + @Setup + public void setup() { + ConfigurableApplicationContext context = initContext(); + this.applicationContext = context; + this.springWebFluxApp = this.applicationContext.getBean( + SleuthBenchmarkingSpringWebFluxApp.class); + baseUrl = "http://127.0.0.1:" + springWebFluxApp.port + "/foo"; + client = newClient(); + tracedClient = newClient(HttpTracing.create( + Tracing.newBuilder().spanReporter(Reporter.NOOP).build() + )); + unsampledClient = newClient(HttpTracing.create( + Tracing.newBuilder().sampler(Sampler.NEVER_SAMPLE).spanReporter(Reporter.NOOP).build() + )); + postSetUp(); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) + .web(WebApplicationType.REACTIVE) + .application(); + customSpringApplication(application); + return application + .run(runArgs()); + } + + protected void customSpringApplication(SpringApplication springApplication) { + + } + + protected void postSetUp() { + } + + + protected String[] runArgs() { + return new String[]{"--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContext", + "--spring.sleuth.enabled=true"}; + } + + + @TearDown + public void clean() throws Exception { + close(client); + close(unsampledClient); + close(tracedClient); + Tracing.current().close(); + try { + + this.applicationContext.close(); + } catch (Exception ig) { + + } + } + + @Benchmark + public void client_get() throws Exception { + get(client); + } + + @Benchmark + public void unsampledClient_get() throws Exception { + get(unsampledClient); + } + + @Benchmark + public void tracedClient_get() throws Exception { + get(tracedClient); + } + + @Benchmark + public void tracedClient_get_resumeTrace() throws Exception { + try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext().newScope(defaultTraceContext)) { + get(tracedClient); + } + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(".*" + SpringWebFluxBenchmarks.class.getSimpleName() + ".*") + .build(); + + new Runner(opt).run(); + } + + +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutReactorSleuthSpringWebFluxBenchmarks.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutReactorSleuthSpringWebFluxBenchmarks.java new file mode 100644 index 000000000..01a082d29 --- /dev/null +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutReactorSleuthSpringWebFluxBenchmarks.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; + +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +/** + * @author alvin + */ +public class WithOutReactorSleuthSpringWebFluxBenchmarks extends SpringWebFluxBenchmarks { + + @Override + protected String[] runArgs() { + return new String[]{"--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContext", + "--spring.sleuth.enabled=true", + "--spring.sleuth.reactor.enabled=false" + + }; + } + + @Override + protected void postSetUp() { + super.postSetUp(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(".*" + WithOutReactorSleuthSpringWebFluxBenchmarks.class.getSimpleName() + ".*") + .build(); + + new Runner(opt).run(); + } +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutSleuthSpringWebFluxBenchmarks.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutSleuthSpringWebFluxBenchmarks.java new file mode 100644 index 000000000..f0d53f2c9 --- /dev/null +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutSleuthSpringWebFluxBenchmarks.java @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; + +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +/** + * @author alvin + */ +public class WithOutSleuthSpringWebFluxBenchmarks extends SpringWebFluxBenchmarks { + + @Override + protected String[] runArgs() { + return new String[]{"--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContext", + "--spring.sleuth.enabled=false"}; + } + + @Override + protected void postSetUp() { + super.postSetUp(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(".*" + WithOutSleuthSpringWebFluxBenchmarks.class.getSimpleName() + ".*") + .build(); + + new Runner(opt).run(); + } +} diff --git a/benchmarks/src/main/resources/application.yml b/benchmarks/src/main/resources/application.yml index 81bf8e0be..246f23e1c 100644 --- a/benchmarks/src/main/resources/application.yml +++ b/benchmarks/src/main/resources/application.yml @@ -1,3 +1,3 @@ logging.level: org.springframework: ERROR - org.springframework.cloud.sleuth.benchmarks: INFO \ No newline at end of file + org.springframework.cloud.sleuth.benchmarks: INFO diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java index fb349bac1..0c5078ccb 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriber.java @@ -16,11 +16,11 @@ package org.springframework.cloud.sleuth.instrument.reactor; -import java.util.concurrent.atomic.AtomicBoolean; - import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.reactivestreams.Subscriber; @@ -38,23 +38,25 @@ final class ScopePassingSpanSubscriber implements SpanSubscription { private static final Log log = LogFactory.getLog(ScopePassingSpanSubscriber.class); - private final Span span; - private final Subscriber subscriber; private final Context context; + private final CurrentTraceContext currentTraceContext; + private final TraceContext traceContext; private final Tracer tracer; private Subscription s; ScopePassingSpanSubscriber(Subscriber subscriber, Context ctx, - Tracing tracing) { + Tracing tracing) { this.subscriber = subscriber; this.tracer = tracing.tracer(); - Span root = ctx != null ? ctx.getOrDefault(Span.class, this.tracer.currentSpan()) + this.currentTraceContext = tracing.currentTraceContext(); + Span root = ctx != null ? ctx.hasKey(Span.class) ? ctx.get(Span.class) + : this.tracer.currentSpan() : null; - this.span = root; + this.traceContext = root == null ? null : root.context(); this.context = ctx != null && root != null ? ctx.put(Span.class, root) : ctx != null ? ctx : Context.empty(); if (log.isTraceEnabled()) { @@ -65,42 +67,43 @@ final class ScopePassingSpanSubscriber implements SpanSubscription { @Override public void onSubscribe(Subscription subscription) { this.s = subscription; - try (Tracer.SpanInScope inScope = this.tracer.withSpanInScope(this.span)) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(this.traceContext)) { this.subscriber.onSubscribe(this); } } @Override public void request(long n) { - try (Tracer.SpanInScope inScope = this.tracer.withSpanInScope(this.span)) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(this.traceContext)) { this.s.request(n); } } @Override public void cancel() { - try (Tracer.SpanInScope inScope = this.tracer.withSpanInScope(this.span)) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(this.traceContext)) { this.s.cancel(); } + } @Override public void onNext(T o) { - try (Tracer.SpanInScope inScope = this.tracer.withSpanInScope(this.span)) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(this.traceContext)) { this.subscriber.onNext(o); } } @Override public void onError(Throwable throwable) { - try (Tracer.SpanInScope inScope = this.tracer.withSpanInScope(this.span)) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(this.traceContext)) { this.subscriber.onError(throwable); } } @Override public void onComplete() { - try (Tracer.SpanInScope inScope = this.tracer.withSpanInScope(this.span)) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(this.traceContext)) { this.subscriber.onComplete(); } } @@ -110,8 +113,4 @@ final class ScopePassingSpanSubscriber implements SpanSubscription { return this.context; } - private void clearSpan() { - this.tracer.withSpanInScope(null); - } - } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriptionProvider.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriptionProvider.java index 851439bbd..917717109 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriptionProvider.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriptionProvider.java @@ -63,7 +63,7 @@ class SpanSubscriptionProvider implements Supplier> { } SpanSubscription newCoreSubscriber(Tracing tracing) { - return new SpanSubscriber<>(this.subscriber, this.context, tracing, this.name); + return new ScopePassingSpanSubscriber<>(this.subscriber, this.context, tracing); } private Tracing tracing() {