From 68f284d1cf9aa62ee451617c751f4c6a2aed15a4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 19 Feb 2021 21:00:27 +0100 Subject: [PATCH 01/78] Opened API, added methods required for Wavefront integration with OTel (#1852) --- .../cloud/sleuth/exporter/FinishedSpan.java | 6 ++++++ .../sleuth/brave/bridge/BraveFinishedSpan.java | 15 ++++++++++++--- .../sleuth/brave/bridge/BraveTraceContext.java | 8 ++++---- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java index 14063d155..73d4d121a 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java @@ -76,6 +76,12 @@ public interface FinishedSpan { @Nullable String getRemoteIp(); + /** + * @return span's local ip + */ + @Nullable + String getLocalIp(); + /** * @return span's remote port */ diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java index 810cd5d57..e24700ae0 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveFinishedSpan.java @@ -30,11 +30,11 @@ import org.springframework.cloud.sleuth.exporter.FinishedSpan; * @author Marcin Grzejszczak * @since 3.0.0 */ -class BraveFinishedSpan implements FinishedSpan { +public class BraveFinishedSpan implements FinishedSpan { private final MutableSpan mutableSpan; - BraveFinishedSpan(MutableSpan mutableSpan) { + public BraveFinishedSpan(MutableSpan mutableSpan) { this.mutableSpan = mutableSpan; } @@ -78,6 +78,11 @@ class BraveFinishedSpan implements FinishedSpan { return this.mutableSpan.remoteIp(); } + @Override + public String getLocalIp() { + return this.mutableSpan.localIp(); + } + @Override public int getRemotePort() { return this.mutableSpan.remotePort(); @@ -106,10 +111,14 @@ class BraveFinishedSpan implements FinishedSpan { return this.mutableSpan.remoteServiceName(); } - static FinishedSpan fromBrave(MutableSpan mutableSpan) { + public static FinishedSpan fromBrave(MutableSpan mutableSpan) { return new BraveFinishedSpan(mutableSpan); } + public static MutableSpan toBrave(FinishedSpan mutableSpan) { + return ((BraveFinishedSpan) mutableSpan).mutableSpan; + } + @Override public String toString() { return "BraveFinishedSpan{" + "mutableSpan=" + mutableSpan + '}'; diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java index 9684cef4a..f1d0d6fd9 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContext.java @@ -27,11 +27,11 @@ import org.springframework.lang.Nullable; * @author Marcin Grzejszczak * @since 3.0.0 */ -class BraveTraceContext implements TraceContext { +public class BraveTraceContext implements TraceContext { final brave.propagation.TraceContext traceContext; - BraveTraceContext(brave.propagation.TraceContext traceContext) { + public BraveTraceContext(brave.propagation.TraceContext traceContext) { this.traceContext = traceContext; } @@ -61,14 +61,14 @@ class BraveTraceContext implements TraceContext { return this.traceContext != null ? this.traceContext.toString() : "null"; } - static brave.propagation.TraceContext toBrave(TraceContext traceContext) { + public static brave.propagation.TraceContext toBrave(TraceContext traceContext) { if (traceContext == null) { return null; } return ((BraveTraceContext) traceContext).traceContext; } - static TraceContext fromBrave(brave.propagation.TraceContext traceContext) { + public static TraceContext fromBrave(brave.propagation.TraceContext traceContext) { return new BraveTraceContext(traceContext); } From 58445f5a4997fff2429e125a01bb19d9b3f0bc01 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 22 Feb 2021 08:43:14 +0100 Subject: [PATCH 02/78] Making the breaking change not breaking anymore --- .../springframework/cloud/sleuth/exporter/FinishedSpan.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java index 73d4d121a..0df4ef633 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/FinishedSpan.java @@ -80,7 +80,9 @@ public interface FinishedSpan { * @return span's local ip */ @Nullable - String getLocalIp(); + default String getLocalIp() { + return null; + } /** * @return span's remote port From a888e2c6b8b583e7a289ce94ebb2c3816e88e634 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 23 Feb 2021 12:00:02 +0100 Subject: [PATCH 03/78] Fixed a typo (Rabbit -> ActiveMQ) fixes #1857 --- docs/src/main/asciidoc/howto.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/howto.adoc b/docs/src/main/asciidoc/howto.adoc index 97ecdff11..ae3b9c206 100644 --- a/docs/src/main/asciidoc/howto.adoc +++ b/docs/src/main/asciidoc/howto.adoc @@ -213,7 +213,7 @@ dependencies { ---- ==== -If you want Sleuth over RabbitMQ, add the `spring-cloud-starter-sleuth`, `spring-cloud-sleuth-zipkin` and `activemq-client` dependencies. +If you want Sleuth over ActiveMQ, add the `spring-cloud-starter-sleuth`, `spring-cloud-sleuth-zipkin` and `activemq-client` dependencies. ==== [source,xml,indent=0,subs="verbatim,attributes",role="primary"] @@ -458,4 +458,4 @@ include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoco Spring Cloud Sleuth API contains all necessary interfaces to be implemented by a tracer. The project comes with OpenZipkin Brave implementation. -You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` module. \ No newline at end of file +You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` module. From a937765c9fee219032f0d567b6a7953ffb4067ca Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 25 Feb 2021 12:43:00 +0100 Subject: [PATCH 04/78] New reactor queue wrapping (#1858) fixes gh-1843 --- benchmarks/pom.xml | 157 +++++-------- .../app/mvc/SleuthBenchmarkingSpringApp.java | 108 ++++----- .../controller/AsyncSimulationController.java | 50 ++++ .../SleuthBenchmarkingStreamApplication.java | 209 +++++++++++++++++ .../SleuthBenchmarkingSpringWebFluxApp.java | 85 ++++--- benchmarks/src/main/resources/application.yml | 4 +- .../cloud/sleuth/benchmarks/jmh/Pair.java | 51 +++++ .../benchmarks/jmh}/ProcessLauncherState.java | 12 +- .../jmh/RunSleuthJmhBenchmarksFromIde.java | 36 --- .../sleuth/benchmarks/jmh/SampleTests.java | 163 +++++++++++++ .../benchmarks/jmh/TracerImplementation.java} | 17 +- .../jmh/mvc/AnnotationBenchmarksTests.java} | 25 +- .../mvc/AsyncWithSleuthBenchmarksTests.java | 81 +++++++ .../AsyncWithoutSleuthBenchmarksTests.java} | 57 ++--- .../jmh/mvc/HttpFilterBenchmarksTests.java} | 49 ++-- .../jmh/mvc/RestTemplateBenchmarkTests.java} | 49 ++-- .../jmh/mvc/StartupBenchmarkTests.java} | 27 ++- .../jmh/stream/MicroBenchmarkStreamTests.java | 196 ++++++++++++++++ .../jmh/webflux/MicroBenchmarkHttpTests.java | 146 ++++++++++++ .../SpringWebFluxBenchmarksTests.java} | 53 +++-- ...orSleuthSpringWebFluxBenchmarksTests.java} | 23 +- ...utSleuthSpringWebFluxBenchmarksTests.java} | 23 +- .../main/asciidoc/spring-cloud-sleuth.adoc | 17 +- pom.xml | 2 +- .../instrument/reactor/ReactorSleuth.java | 23 ++ .../reactor/SleuthReactorProperties.java | 18 ++ .../TraceReactorAutoConfiguration.java | 215 ++++++++++++++++-- ...ndlerFunctionAdapterBeanPostProcessor.java | 118 ++++++++++ .../sleuth/instrument/web/TraceWebFilter.java | 40 +++- .../web/TraceWebFluxAutoConfiguration.java | 6 + .../SleuthSpanCreatorAspectFluxTests.java | 1 + .../SleuthSpanCreatorAspectTests.java | 1 + ...utoConfigurationAccessorConfiguration.java | 3 +- ...onfiguredSkipPatternsIntegrationTests.java | 1 + .../reactor/Issue866Configuration.java | 2 +- ...ePassingSpanSubscriberSpringBootTests.java | 6 + .../ScopePassingSpanSubscriberTests.java | 3 +- ...utoConfigurationAccessorConfiguration.java | 16 +- .../reactor/sample/FlatMapTests.java | 39 +++- .../src/test/resources/application.yml | 2 +- 40 files changed, 1670 insertions(+), 464 deletions(-) create mode 100644 benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/controller/AsyncSimulationController.java create mode 100644 benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java create mode 100644 benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks => test/java/org/springframework/cloud/sleuth/benchmarks/jmh}/ProcessLauncherState.java (93%) delete mode 100644 benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/RunSleuthJmhBenchmarksFromIde.java create mode 100644 benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxOnLastBenchmark.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java} (56%) rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java} (78%) create mode 100644 benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java} (53%) rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java} (82%) rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java} (66%) rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/StartupBenchmark.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java} (70%) create mode 100644 benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java create mode 100644 benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java} (77%) rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutSleuthSpringWebFluxBenchmarks.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java} (57%) rename benchmarks/src/{main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutReactorSleuthSpringWebFluxBenchmarks.java => test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java} (59%) create mode 100644 spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 45295d16b..4dbbf5e39 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -25,16 +25,23 @@ 2.2.8.BUILD-SNAPSHOT benchmarks + + org.springframework.boot + spring-boot-starter-parent + 2.3.9.RELEASE + + + ${project.basedir}/.. - 1.22 3.2.1 true 1.8 1.8 - 2.3.8.RELEASE - 5.12.7 - 3.14.6 + 4.9.0 + 0.2.0.RELEASE + 1.21 + Horsham.SR11 @@ -47,10 +54,9 @@ import - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} + org.springframework.cloud + spring-cloud-stream-dependencies + ${spring-cloud-stream.version} pom import @@ -91,20 +97,35 @@ org.assertj assertj-core - 3.14.0 compile - org.hamcrest - hamcrest-core - 1.3 + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + org.springframework.cloud + spring-cloud-stream + test-jar + compile + test-binder + + + org.springframework.boot + spring-boot-starter-test compile - - org.openjdk.jmh - jmh-core - ${jmh.version} + com.github.mp911de.microbenchmark-runner + microbenchmark-runner-junit5 + ${microbenchmark-runner.version} + test + + + com.github.mp911de.microbenchmark-runner + microbenchmark-runner-extras + ${microbenchmark-runner.version} + test @@ -122,12 +143,16 @@ io.zipkin.brave brave-instrumentation-httpclient - ${brave.version} org.apache.httpcomponents httpclient + + org.awaitility + awaitility + test + @@ -140,28 +165,19 @@ ${maven.compiler.target} - - - maven-deploy-plugin - - true - - - - maven-install-plugin - - true - - + + jitpack.io + https://jitpack.io + spring-snapshots Spring Snapshots - https://repo.spring.io/libs-snapshot-local + https://repo.spring.io/snapshot true @@ -184,7 +200,7 @@ spring-milestones Spring Milestones - https://repo.spring.io/libs-milestone-local + https://repo.spring.io/milestone false @@ -202,7 +218,7 @@ spring-snapshots Spring Snapshots - https://repo.spring.io/libs-snapshot-local + https://repo.spring.io/snapshot true @@ -213,7 +229,7 @@ spring-milestones Spring Milestones - https://repo.spring.io/libs-milestone-local + https://repo.spring.io/milestone false @@ -221,7 +237,7 @@ spring-releases Spring Releases - https://repo.spring.io/libs-release-local + https://repo.spring.io/release false @@ -229,75 +245,6 @@ - - jmh - - false - - - - - maven-shade-plugin - ${maven-shade-plugin.version} - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - - true - - true - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - package - - shade - - - benchmarks - - - META-INF/spring.handlers - - - META-INF/spring.factories - - - META-INF/spring.schemas - - - - org.openjdk.jmh.Main - - - false - - - - - - - - jmeter @@ -380,7 +327,7 @@ com.lazerycode.jmeter jmeter-maven-plugin - 1.10.1 + 3.1.1 false false diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java index a47396692..99efe676c 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/SleuthBenchmarkingSpringApp.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -16,10 +16,6 @@ package org.springframework.cloud.sleuth.benchmarks.app.mvc; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.regex.Pattern; @@ -27,7 +23,6 @@ import javax.annotation.PreDestroy; import brave.Span; import brave.Tracer; -import brave.sampler.Sampler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -41,28 +36,26 @@ import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.cloud.sleuth.annotation.ContinueSpan; import org.springframework.cloud.sleuth.annotation.NewSpan; import org.springframework.cloud.sleuth.annotation.SpanTag; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; -import org.springframework.scheduling.annotation.Async; +import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.util.SocketUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; /** * @author Marcin Grzejszczak */ @SpringBootApplication -@RestController @EnableAsync -public class SleuthBenchmarkingSpringApp - implements ApplicationListener { +public class SleuthBenchmarkingSpringApp implements ApplicationListener { private static final Log log = LogFactory.getLog(SleuthBenchmarkingSpringApp.class); - public final ExecutorService pool = Executors.newWorkStealingPool(); - + /** + * Port of the app. + */ public int port; @Autowired(required = false) @@ -71,28 +64,16 @@ public class SleuthBenchmarkingSpringApp @Autowired AClass aClass; + @Autowired + AsyncSimulationController controller; + public static void main(String... args) { SpringApplication.run(SleuthBenchmarkingSpringApp.class, args); } - @RequestMapping("/foo") - public String foo() { - return "foo"; - } - - @RequestMapping("/bar") - public Callable bar() { - return () -> "bar"; - } - - @RequestMapping("/async") - public String asyncHttp() throws ExecutionException, InterruptedException { - return this.async().get(); - } - - @Async - public Future async() { - return this.pool.submit(() -> "async"); + @PreDestroy + public void clean() { + this.controller.clean(); } public String manualSpan() { @@ -108,48 +89,43 @@ public class SleuthBenchmarkingSpringApp this.port = event.getSource().getPort(); } - @Bean - public ServletWebServerFactory servletContainer( - @Value("${server.port:0}") int serverPort) { - log.info("Starting container at port [" + serverPort + "]"); - return new TomcatServletWebServerFactory( - serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); + public Future async() { + return this.controller.async(); } - @PreDestroy - public void clean() { - this.pool.shutdownNow(); - } + @Configuration + static class Config { + @Autowired(required = false) + Tracer tracer; - @Bean - Sampler alwaysSampler() { - return Sampler.ALWAYS_SAMPLE; - } + @Bean + AnotherClass anotherClass() { + return new AnotherClass(this.tracer); + } - @Bean - AnotherClass anotherClass() { - return new AnotherClass(this.tracer); - } + @Bean + AClass aClass() { + return new AClass(this.tracer, anotherClass()); + } - @Bean - AClass aClass() { - return new AClass(this.tracer, anotherClass()); - } + @Bean + SkipPatternProvider patternProvider() { + return new SkipPatternProvider() { + @Override + public Pattern skipPattern() { + return Pattern.compile(""); + } + }; + } - @Bean - SkipPatternProvider patternProvider() { - return new SkipPatternProvider() { - @Override - public Pattern skipPattern() { - return Pattern.compile(""); - } - }; - } - public ExecutorService getPool() { - return this.pool; - } + @Bean + public ServletWebServerFactory servletContainer(@Value("${server.port:0}") int serverPort) { + log.info("Starting container at port [" + serverPort + "]"); + return new TomcatServletWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); + } + } } class AClass { diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/controller/AsyncSimulationController.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/controller/AsyncSimulationController.java new file mode 100644 index 000000000..94b17fdd8 --- /dev/null +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/mvc/controller/AsyncSimulationController.java @@ -0,0 +1,50 @@ +package org.springframework.cloud.sleuth.benchmarks.app.mvc.controller; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import javax.annotation.PreDestroy; + +import org.springframework.scheduling.annotation.Async; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Marcin Grzejszczak + */ +@RestController +public class AsyncSimulationController { + private final ExecutorService pool = Executors.newWorkStealingPool(); + + @RequestMapping("/foo") + public String foo() { + return "foo"; + } + + @RequestMapping("/bar") + public Callable bar() { + return () -> "bar"; + } + + @RequestMapping("/async") + public String asyncHttp() throws ExecutionException, InterruptedException { + return this.async().get(); + } + + @Async + public Future async() { + return this.pool.submit(() -> "async"); + } + + @PreDestroy + public void clean() { + this.pool.shutdownNow(); + } + + public ExecutorService getPool() { + return this.pool; + } +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java new file mode 100644 index 000000000..a793ec2bd --- /dev/null +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java @@ -0,0 +1,209 @@ +/* + * Copyright 2013-2020 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 + * + * https://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.stream; + +import java.io.IOException; +import java.time.Duration; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; +import reactor.core.scheduler.Schedulers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.stream.binder.test.InputDestination; +import org.springframework.cloud.stream.binder.test.OutputDestination; +import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootApplication +@Import(TestChannelBinderConfiguration.class) +public class SleuthBenchmarkingStreamApplication { + + private static final Logger log = LoggerFactory.getLogger(SleuthBenchmarkingStreamApplication.class); + + public static void main(String[] args) throws InterruptedException, IOException { + // System.setProperty("spring.sleuth.enabled", "false"); + // System.setProperty("spring.sleuth.reactor.instrumentation-type", + // "DECORATE_ON_EACH"); + // System.setProperty("spring.sleuth.reactor.instrumentation-type", + // "DECORATE_ON_LAST"); + // System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL"); + System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL"); + System.setProperty("spring.sleuth.function.type", "simple"); + ConfigurableApplicationContext context = SpringApplication.run(SleuthBenchmarkingStreamApplication.class, args); + for (int i = 0; i < 1; i++) { + InputDestination input = context.getBean(InputDestination.class); + input.send(MessageBuilder.withPayload("hello".getBytes()) + .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); + log.info("Retrieving the message for tests"); + OutputDestination output = context.getBean(OutputDestination.class); + Message message = output.receive(200L); + log.info("Got the message from output"); + assertThat(message).isNotNull(); + log.info("Message is not null"); + assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); + log.info("Payload is HELLO"); + String b3 = message.getHeaders().get("b3", String.class); + log.info("Checking the b3 header [" + b3 + "]"); + assertThat(b3).startsWith("4883117762eb9420"); + } + } + + @Bean + ExecutorService sleuthExecutorService() { + return Executors.newCachedThreadPool(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple") + public Function simple() { + log.info("simple_function"); + return new SimpleFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple") + public Function, Flux> reactiveSimple() { + log.info("simple_reactive_function"); + return new SimpleReactiveFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "simple_function_with_around") + public Function, Message> simpleFunctionWithAround() { + log.info("simple_function_with_around"); + return new SimpleMessageFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.nonreactive.function.enabled", havingValue = "true") + public Function nonReactiveFunction(ExecutorService executorService) { + log.info("no sleuth non reactive function"); + return new SleuthNonReactiveFunction(executorService); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "DECORATE_ON_EACH", + matchIfMissing = true) + public Function, Flux> onEachFunction() { + log.info("on each function"); + return new SleuthFunction(); + } + + @Bean(name = "myFlux") + @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "DECORATE_ON_LAST") + public Function, Flux> onLastFunction() { + log.info("on last function"); + return new SleuthFunction(); + } + +} + +class SimpleFunction implements Function { + + private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); + + @Override + public String apply(String input) { + // tracing works cause headers from the input message get propagated to the output + // message + log.info("Hello from simple [{}]", input); + return input.toUpperCase(); + } + +} + +class SimpleReactiveFunction implements Function, Flux> { + + private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class); + + @Override + public Flux apply(Flux input) { + return input.doOnNext(s -> log.info("Hello from simple [{}]", s)).map(String::toUpperCase); + } + +} + +class SimpleMessageFunction implements Function, Message> { + + private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class); + + @Override + public Message apply(Message input) { + log.info("Hello from message simple [{}]", input.getPayload()); + return MessageBuilder.withPayload(input.getPayload().toUpperCase()).build(); + } + +} + +class SleuthNonReactiveFunction implements Function { + + private static final Logger log = LoggerFactory.getLogger(SleuthNonReactiveFunction.class); + + private final ExecutorService executorService; + + SleuthNonReactiveFunction(ExecutorService executorService) { + this.executorService = executorService; + } + + @Override + public String apply(String input) { + log.info("Got a message"); + try { + return this.executorService.submit(() -> { + log.info("Logging [{}] from a new thread", input); + return input.toUpperCase(); + }).get(20, TimeUnit.MILLISECONDS); + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } + +} + +class SleuthFunction implements Function, Flux> { + + private static final Logger log = LoggerFactory.getLogger(SleuthFunction.class); + + static final Scheduler SCHEDULER = Schedulers.newParallel("sleuthFunction"); + + @Override + public Flux apply(Flux input) { + return input.doOnEach(signal -> log.info("Got a message")) + .flatMap(s -> Mono.delay(Duration.ofMillis(1), SCHEDULER).map(aLong -> { + log.info("Logging [{}] from flat map", s); + return s.toUpperCase(); + })); + } + +} 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 index 631919c6b..121b9ceb1 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -16,13 +16,17 @@ package org.springframework.cloud.sleuth.benchmarks.app.webflux; +import java.time.Duration; import java.util.regex.Pattern; +import java.util.stream.Collectors; -import brave.sampler.Sampler; -import brave.handler.SpanHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import brave.propagation.TraceContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; +import reactor.core.scheduler.Schedulers; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.WebApplicationType; @@ -33,7 +37,9 @@ import org.springframework.boot.web.reactive.context.ReactiveWebServerInitialize import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; +import org.springframework.util.Assert; import org.springframework.util.SocketUtils; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -42,17 +48,20 @@ import org.springframework.web.bind.annotation.RestController; */ @SpringBootApplication @RestController -public class SleuthBenchmarkingSpringWebFluxApp - implements ApplicationListener { +public class SleuthBenchmarkingSpringWebFluxApp implements ApplicationListener { - private static final Log log = LogFactory - .getLog(SleuthBenchmarkingSpringWebFluxApp.class); + static final Scheduler FOO_SCHEDULER = Schedulers.newParallel("foo"); + private static final Logger log = LoggerFactory.getLogger(SleuthBenchmarkingSpringWebFluxApp.class); + + /** + * Port to set. + */ public int port; public static void main(String... args) { - new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) - .web(WebApplicationType.REACTIVE).application().run(args); + new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class).web(WebApplicationType.REACTIVE) + .application().run(args); } @RequestMapping("/foo") @@ -60,29 +69,15 @@ public class SleuthBenchmarkingSpringWebFluxApp 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) { + NettyReactiveWebServerFactory nettyReactiveWebServerFactory(@Value("${server.port:0}") int serverPort) { log.info("Starting container at port [" + serverPort + "]"); - return new NettyReactiveWebServerFactory( - serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); - } - - @Bean - public SpanHandler spanHandler() { - return new SpanHandler() { - // intentionally anonymous to prevent logging fallback on NOOP - }; + return new NettyReactiveWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort); } @Override @@ -90,4 +85,40 @@ public class SleuthBenchmarkingSpringWebFluxApp this.port = event.getWebServer().getPort(); } + @GetMapping("/simple") + public Mono simple() { + return Mono.just("hello").map(String::toUpperCase).doOnNext(s -> log.info("Hello from simple [{}]", s)); + } + + + @GetMapping("/complexNoSleuth") + public Mono complexNoSleuth() { + return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) + .doOnEach(signal -> log.info("Got a request")) + .flatMap(s -> Mono.delay(Duration.ofMillis(1), FOO_SCHEDULER).map(aLong -> { + log.info("Logging [{}] from flat map", s); + return ""; + })); + } + + @GetMapping("/complex") + public Mono complex() { + return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList()) + .doOnEach(signal -> log.info("Got a request")) + .flatMap(s -> Mono.delay(Duration.ofMillis(1), FOO_SCHEDULER).map(aLong -> { + log.info("Logging [{}] from flat map", s); + return ""; + })).doOnEach(signal -> { + log.info("Doing assertions"); + TraceContext traceContext = signal.getContext().get(TraceContext.class); + Assert.notNull(traceContext, "Context must be set by Sleuth instrumentation"); + if (traceContext.traceIdString().startsWith("0000000000000000")) { + Assert.state(traceContext.traceIdString().equals("00000000000000004883117762eb9420"), "TraceId must be propagated"); + } else { + Assert.state(traceContext.traceIdString().equals("4883117762eb9420"), "TraceId must be propagated"); + } + log.info("Assertions passed"); + }); + } + } diff --git a/benchmarks/src/main/resources/application.yml b/benchmarks/src/main/resources/application.yml index 246f23e1c..8ffac9305 100644 --- a/benchmarks/src/main/resources/application.yml +++ b/benchmarks/src/main/resources/application.yml @@ -1,3 +1,5 @@ logging.level: org.springframework: ERROR - org.springframework.cloud.sleuth.benchmarks: INFO + org.springframework.sleuth: ERROR + org.springframework.sleuth.benchmarks: INFO + brave: ERROR diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java new file mode 100644 index 000000000..bad8a8d5a --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java @@ -0,0 +1,51 @@ +/* + * Copyright 2016-2019 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 + * + * https://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; + +public class Pair { + final String key; + final String value; + + public Pair(String key, String value) { + this.key = key; + this.value = value; + } + + public String asProp() { + return this.key + "=" + this.value; + } + + public static Pair of(String key, String value) { + return new Pair(key, value); + } + + public static Pair noHook() { + return new Pair("spring.sleuth.reactor.decorate-hooks", "false"); + } + + public static Pair noSleuth() { + return new Pair("spring.sleuth.enabled", "false"); + } + + public static Pair onEach() { + return new Pair("spring.sleuth.reactor.decorate-on-each", "true"); + } + + public static Pair onLast() { + return new Pair("spring.sleuth.reactor.decorate-on-each", "false"); + } +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/ProcessLauncherState.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java similarity index 93% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/ProcessLauncherState.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java index 9478d6955..7a57bfc13 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/ProcessLauncherState.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh; import java.io.BufferedReader; import java.io.File; @@ -57,15 +57,13 @@ public class ProcessLauncherState { this.args.add(count++, "-Djava.security.egd=file:/dev/./urandom"); this.args.add(count++, "-XX:TieredStopAtLevel=1"); // zoom if (System.getProperty("bench.args") != null) { - this.args.addAll(count++, - Arrays.asList(System.getProperty("bench.args").split(" "))); + this.args.addAll(count++, Arrays.asList(System.getProperty("bench.args").split(" "))); } this.length = args.length; this.home = new File(dir); } - protected static String output(InputStream inputStream, String marker) - throws IOException { + protected static String output(InputStream inputStream, String marker) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader br = null; br = new BufferedReader(new InputStreamReader(inputStream)); @@ -100,8 +98,7 @@ public class ProcessLauncherState { public void after() throws Exception { if (started != null && started.isAlive()) { - System.err.println( - "Stopped " + mainClass + ": " + started.destroyForcibly().waitFor()); + System.err.println("Stopped " + mainClass + ": " + started.destroyForcibly().waitFor()); } } @@ -120,6 +117,7 @@ public class ProcessLauncherState { } public void run() throws Exception { + System.out.println("Running process"); List args = new ArrayList<>(this.args); args.add(args.size() - this.length, this.mainClass); if (extraArgs != null) { diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/RunSleuthJmhBenchmarksFromIde.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/RunSleuthJmhBenchmarksFromIde.java deleted file mode 100644 index 1c6e7d03e..000000000 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/RunSleuthJmhBenchmarksFromIde.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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; - -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; - -public class RunSleuthJmhBenchmarksFromIde { - - // Convenience main entry-point for testing from IDE - public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(RunSleuthJmhBenchmarksFromIde.class.getPackage().getName() - + ".benchmarks.*") - .build(); - - new Runner(opt).run(); - } - -} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java new file mode 100644 index 000000000..3cadc3077 --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java @@ -0,0 +1,163 @@ +/* + * Copyright 2013-2020 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 + * + * https://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; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import brave.Tracing; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.TearDown; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.benchmarks.app.stream.SleuthBenchmarkingStreamApplication; +import org.springframework.cloud.stream.binder.test.InputDestination; +import org.springframework.cloud.stream.binder.test.OutputDestination; +import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.util.StringUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +@Disabled +public class SampleTests { + + @Test + public void testStream() throws Exception { + for (BenchmarkContext.Instrumentation value : BenchmarkContext.Instrumentation.values()) { + run(value); + } + // run(BenchmarkContext.Instrumentation.sleuthReactiveSimpleManual); + } + + private void run(BenchmarkContext.Instrumentation value) throws Exception { + BenchmarkContext context = new BenchmarkContext(); + System.out.println("\n\n\n\n WILL WORK WITH [" + value + "]\n\n\n\n"); + context.instrumentation = value; + context.setup(); + + try { + context.run(value); + } + finally { + context.clean(); + } + System.out.println("\n\n FINISHED WITH [" + value + "]\n\n\n\n"); + } + + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext applicationContext; + + volatile InputDestination input; + + volatile OutputDestination output; + + @Param + private Instrumentation instrumentation; + + @Setup + public void setup() { + this.applicationContext = initContext(); + this.input = this.applicationContext.getBean(InputDestination.class); + this.output = this.applicationContext.getBean(OutputDestination.class); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingStreamApplication.class) + .web(WebApplicationType.REACTIVE).application(); + return application.run(runArgs()); + } + + protected String[] runArgs() { + List strings = new ArrayList<>(); + strings.addAll(Arrays.asList("--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContextForStream" + instrumentation.name())); + strings.addAll(instrumentation.entires.stream().map(s -> "--" + s).collect(Collectors.toList())); + return strings.toArray(new String[0]); + } + + void run(Instrumentation value) { + System.out.println("Sending the message to input"); + input.send(MessageBuilder.withPayload("hello".getBytes()) + .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); + System.out.println("Retrieving the message for tests"); + Message message = output.receive(200L); + System.out.println("Got the message from output"); + assertThat(message).isNotNull(); + System.out.println("Message is not null"); + assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); + System.out.println("Payload is HELLO"); + if (!value.toString().toLowerCase().contains("nosleuth")) { + String b3 = message.getHeaders().get("b3", String.class); + System.out.println("Checking the b3 header [" + b3 + "]"); + assertThat(b3).startsWith("4883117762eb9420"); + } + } + + @TearDown + public void clean() throws Exception { + Tracing current = Tracing.current(); + if (current != null) { + current.close(); + } + try { + this.applicationContext.close(); + } + catch (Exception ig) { + + } + } + + public enum Instrumentation { + + noSleuthSimple("spring.sleuth.enabled=false,spring.sleuth.function.type=simple"); + + private Set entires = new HashSet<>(); + + Instrumentation(String key, String value) { + this.entires.add(key + "=" + value); + } + + Instrumentation(String commaSeparated) { + this.entires.addAll(StringUtils.commaDelimitedListToSet(commaSeparated)); + } + + } + + } + + @Configuration(proxyBeanMethods = false) + @Import(TestChannelBinderConfiguration.class) + static class TestConfiguration { + + } + +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxOnLastBenchmark.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java similarity index 56% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxOnLastBenchmark.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java index b050885a6..75fa5373b 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxOnLastBenchmark.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2016-2019 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. @@ -14,16 +14,15 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh; -public class SpringWebFluxOnLastBenchmark extends SpringWebFluxBenchmarks { +public enum TracerImplementation { + + brave; @Override - protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", - "--spring.application.name=defaultTraceContextWithOnLastOperator", - "--spring.sleuth.enabled=true", - "--spring.sleuth.reactor.on-each-operator=false" }; + public String toString() { + return this.name(); } -} +} \ No newline at end of file diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java similarity index 78% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java index c1bfb8c0f..8a4e5eeda 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AnnotationBenchmarks.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,16 +14,18 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.mvc; import java.util.concurrent.TimeUnit; +import jmh.mbr.junit5.Microbenchmark; 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.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; @@ -33,17 +35,19 @@ import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; import org.springframework.context.ConfigurableApplicationContext; import static org.assertj.core.api.BDDAssertions.then; -@Measurement(iterations = 5) -@Warmup(iterations = 10) -@Fork(3) +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MICROSECONDS) @Threads(Threads.MAX) -public class AnnotationBenchmarks { +@Microbenchmark +public class AnnotationBenchmarksTests { @Benchmark public void manuallyCreatedSpans(BenchmarkContext context) throws Exception { @@ -62,11 +66,14 @@ public class AnnotationBenchmarks { volatile SleuthBenchmarkingSpringApp sleuth; + @Param + private TracerImplementation tracerImplementation; + @Setup public void setup() { - this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class) - .run("--spring.jmx.enabled=false", - "--spring.application.name=withSleuth"); + this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", + + "--spring.application.name=withSleuth_" + this.tracerImplementation.name()); this.sleuth = this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class); } diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java new file mode 100644 index 000000000..d82fd607c --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithSleuthBenchmarksTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2013-2020 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 + * + * https://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.mvc; + +import java.util.concurrent.TimeUnit; + +import jmh.mbr.junit5.Microbenchmark; +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.Param; +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.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; + +import static org.assertj.core.api.BDDAssertions.then; + +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class AsyncWithSleuthBenchmarksTests { + @Benchmark + public void asyncMethodWithSleuth(BenchmarkContext context) throws Exception { + then(context.app.async().get()).isEqualTo("async"); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + volatile ConfigurableApplicationContext context; + volatile SleuthBenchmarkingSpringApp app; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.context = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( + "--spring.jmx.enabled=false", + "--spring.application.name=withSleuth_" + this.tracerImplementation.name() + ); + this.app = this.context.getBean(SleuthBenchmarkingSpringApp.class); + } + + @TearDown + public void clean() { + this.app.clean(); + this.context.close(); + } + + } + +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java similarity index 53% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java index 61fe76cc7..93ea2e7ce 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/AsyncBenchmarks.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.mvc; import java.util.concurrent.TimeUnit; +import jmh.mbr.junit5.Microbenchmark; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; @@ -37,57 +38,39 @@ import org.springframework.context.ConfigurableApplicationContext; import static org.assertj.core.api.BDDAssertions.then; -@Measurement(iterations = 5) -@Warmup(iterations = 10) -@Fork(3) +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MICROSECONDS) @Threads(Threads.MAX) -public class AsyncBenchmarks { - +@Microbenchmark +public class AsyncWithoutSleuthBenchmarksTests { @Benchmark public void asyncMethodWithoutSleuth(BenchmarkContext context) throws Exception { - then(context.untracedAsyncMethodHavingBean.async().get()).isEqualTo("async"); - } - - @Benchmark - public void asyncMethodWithSleuth(BenchmarkContext context) throws Exception { - then(context.tracedAsyncMethodHavingBean.async().get()).isEqualTo("async"); + then(context.app.async().get()).isEqualTo("async"); } @State(Scope.Benchmark) public static class BenchmarkContext { - - volatile ConfigurableApplicationContext withSleuth; - - volatile ConfigurableApplicationContext withoutSleuth; - - volatile SleuthBenchmarkingSpringApp tracedAsyncMethodHavingBean; - - volatile SleuthBenchmarkingSpringApp untracedAsyncMethodHavingBean; + volatile ConfigurableApplicationContext context; + volatile SleuthBenchmarkingSpringApp app; @Setup public void setup() { - this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class) - .run("--spring.jmx.enabled=false", - "--spring.application.name=withSleuth"); - this.withoutSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class) - .run("--spring.jmx.enabled=false", - "--spring.application.name=withoutSleuth", - "--spring.sleuth.enabled=false", - "--spring.sleuth.async.enabled=false"); - this.tracedAsyncMethodHavingBean = this.withSleuth - .getBean(SleuthBenchmarkingSpringApp.class); - this.untracedAsyncMethodHavingBean = this.withoutSleuth - .getBean(SleuthBenchmarkingSpringApp.class); + this.context = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( + "--spring.jmx.enabled=false", + "--spring.application.name=withoutSleuth", + "--spring.sleuth.enabled=false", + "--spring.sleuth.async.enabled=false" + ); + this.app = this.context.getBean(SleuthBenchmarkingSpringApp.class); } @TearDown public void clean() { - this.tracedAsyncMethodHavingBean.clean(); - this.untracedAsyncMethodHavingBean.clean(); - this.withSleuth.close(); - this.withoutSleuth.close(); + this.app.clean(); + this.context.close(); } } diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java similarity index 82% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java index 1ad2ab604..4ea058739 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/HttpFilterBenchmarks.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.mvc; import java.io.IOException; import java.util.concurrent.Callable; @@ -28,12 +28,14 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import brave.servlet.TracingFilter; +import jmh.mbr.junit5.Microbenchmark; 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.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; @@ -43,6 +45,8 @@ import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.http.MediaType; import org.springframework.mock.web.MockFilterChain; @@ -62,17 +66,17 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@Warmup(iterations = 10) +@Warmup(iterations = 5) @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MICROSECONDS) @Threads(Threads.MAX) -public class HttpFilterBenchmarks { +@Microbenchmark +public class HttpFilterBenchmarksTests { @Benchmark @Measurement(iterations = 5, time = 1) - @Fork(3) - public void filterWithoutSleuth(BenchmarkContext context) - throws IOException, ServletException { + @Fork(2) + public void filterWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); MockHttpServletResponse response = new MockHttpServletResponse(); response.setContentType(MediaType.APPLICATION_JSON_VALUE); @@ -82,9 +86,8 @@ public class HttpFilterBenchmarks { @Benchmark @Measurement(iterations = 5, time = 1) - @Fork(3) - public void filterWithSleuth(BenchmarkContext context) - throws ServletException, IOException { + @Fork(2) + public void filterWithSleuth(BenchmarkContext context) throws ServletException, IOException { MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); MockHttpServletResponse response = new MockHttpServletResponse(); response.setContentType(MediaType.APPLICATION_JSON_VALUE); @@ -107,12 +110,10 @@ public class HttpFilterBenchmarks { } private MockHttpServletRequestBuilder builder() { - return get("/").accept(MediaType.APPLICATION_JSON).header("User-Agent", - "MockMvc"); + return get("/").accept(MediaType.APPLICATION_JSON).header("User-Agent", "MockMvc"); } - private void performRequest(MockMvc mockMvc, String url, String expectedResult) - throws Exception { + private void performRequest(MockMvc mockMvc, String url, String expectedResult) throws Exception { MvcResult mvcResult = mockMvc.perform(get("/" + url)).andExpect(status().isOk()) .andExpect(request().asyncStarted()).andReturn(); @@ -133,18 +134,18 @@ public class HttpFilterBenchmarks { volatile MockMvc mockMvcForUntracedController; + @Param + private TracerImplementation tracerImplementation; + @Setup public void setup() { - this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class) - .run("--spring.jmx.enabled=false", - "--spring.application.name=withSleuth"); + this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", + + "--spring.application.name=withSleuth_" + this.tracerImplementation.name()); this.tracingFilter = this.withSleuth.getBean(TracingFilter.class); this.mockMvcForTracedController = MockMvcBuilders - .standaloneSetup( - this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class)) - .build(); - this.mockMvcForUntracedController = MockMvcBuilders - .standaloneSetup(new VanillaController()).build(); + .standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)).build(); + this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build(); } @TearDown @@ -162,8 +163,8 @@ public class HttpFilterBenchmarks { } @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { chain.doFilter(request, response); } diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java similarity index 66% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java index 8823ff1e6..c18673216 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/RestTemplateBenchmark.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.mvc; import java.io.IOException; import java.util.Collections; @@ -23,12 +23,14 @@ import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import brave.spring.web.TracingClientHttpRequestInterceptor; +import jmh.mbr.junit5.Microbenchmark; 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.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; @@ -38,6 +40,8 @@ import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.web.client.MockMvcClientHttpRequestFactory; import org.springframework.test.web.servlet.MockMvc; @@ -49,24 +53,22 @@ import static org.assertj.core.api.BDDAssertions.then; /** * We're checking how much overhead does the instrumentation of the RestTemplate take */ -@Measurement(iterations = 5) -@Warmup(iterations = 10) -@Fork(3) +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MICROSECONDS) @Threads(Threads.MAX) -public class RestTemplateBenchmark { +@Microbenchmark +public class RestTemplateBenchmarkTests { @Benchmark - public void syncEndpointWithoutSleuth(BenchmarkContext context) - throws IOException, ServletException { - then(context.untracedTemplate.getForObject("/foo", String.class)) - .isEqualTo("foo"); + public void syncEndpointWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { + then(context.untracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo"); } @Benchmark - public void syncEndpointWithSleuth(BenchmarkContext context) - throws ServletException, IOException { + public void syncEndpointWithSleuth(BenchmarkContext context) throws ServletException, IOException { then(context.tracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo"); } @@ -81,20 +83,21 @@ public class RestTemplateBenchmark { volatile RestTemplate untracedTemplate; + @Param + private TracerImplementation tracerImplementation; + @Setup public void setup() { - new SpringApplication(SleuthBenchmarkingSpringApp.class).run( - "--spring.jmx.enabled=false", "--spring.application.name=withSleuth"); - this.mockMvc = MockMvcBuilders - .standaloneSetup( - this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class)) + this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run( + "--spring.jmx.enabled=false", + "--spring.application.name=withSleuth_" + this.tracerImplementation.name() + ); + this.mockMvc = MockMvcBuilders.standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)) .build(); - this.tracedTemplate = new RestTemplate( - new MockMvcClientHttpRequestFactory(this.mockMvc)); - this.tracedTemplate.setInterceptors(Collections.singletonList( - this.withSleuth.getBean(TracingClientHttpRequestInterceptor.class))); - this.untracedTemplate = new RestTemplate( - new MockMvcClientHttpRequestFactory(this.mockMvc)); + this.tracedTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc)); + this.tracedTemplate.setInterceptors( + Collections.singletonList(this.withSleuth.getBean(TracingClientHttpRequestInterceptor.class))); + this.untracedTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc)); } @TearDown diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/StartupBenchmark.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java similarity index 70% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/StartupBenchmark.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java index 0510186ea..63a6adc65 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/StartupBenchmark.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java @@ -14,24 +14,32 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.mvc; +import jmh.mbr.junit5.Microbenchmark; +import org.junit.jupiter.api.Disabled; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.annotations.Warmup; +import org.springframework.cloud.sleuth.benchmarks.jmh.ProcessLauncherState; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; + @Measurement(iterations = 5) @Warmup(iterations = 1) @Fork(value = 2, warmups = 0) @BenchmarkMode(Mode.AverageTime) -public class StartupBenchmark { +@Microbenchmark +@Disabled("Process doesn't stop") +public class StartupBenchmarkTests { @Benchmark public void withAnnotations(ApplicationState state) throws Exception { @@ -46,31 +54,30 @@ public class StartupBenchmark { @Benchmark public void withoutAsync(ApplicationState state) throws Exception { - state.setExtraArgs("--spring.sleuth.async.enabled=false", - "--spring.sleuth.annotation.enabled=false"); + state.setExtraArgs("--spring.sleuth.async.enabled=false", "--spring.sleuth.annotation.enabled=false"); state.run(); } @Benchmark public void withoutScheduled(ApplicationState state) throws Exception { - state.setExtraArgs("--spring.sleuth.scheduled.enabled=false", - "--spring.sleuth.async.enabled=false", + state.setExtraArgs("--spring.sleuth.scheduled.enabled=false", "--spring.sleuth.async.enabled=false", "--spring.sleuth.annotation.enabled=false"); state.run(); } @Benchmark public void withoutWeb(ApplicationState state) throws Exception { - state.setExtraArgs("--spring.sleuth.web.enabled=false", - "--spring.sleuth.scheduled.enabled=false", - "--spring.sleuth.async.enabled=false", - "--spring.sleuth.annotation.enabled=false"); + state.setExtraArgs("--spring.sleuth.web.enabled=false", "--spring.sleuth.scheduled.enabled=false", + "--spring.sleuth.async.enabled=false", "--spring.sleuth.annotation.enabled=false"); state.run(); } @State(Scope.Benchmark) public static class ApplicationState extends ProcessLauncherState { + @Param + private TracerImplementation tracerImplementation; + public ApplicationState() { super("target", "--server.port=0"); } diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java new file mode 100644 index 000000000..d58dee940 --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java @@ -0,0 +1,196 @@ +/* + * Copyright 2013-2020 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 + * + * https://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.stream; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import brave.Tracing; +import jmh.mbr.junit5.Microbenchmark; +import org.junit.platform.commons.annotation.Testable; +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.Param; +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.Warmup; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.benchmarks.app.stream.SleuthBenchmarkingStreamApplication; +import org.springframework.cloud.sleuth.benchmarks.jmh.Pair; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.cloud.stream.binder.test.InputDestination; +import org.springframework.cloud.stream.binder.test.OutputDestination; +import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Microbenchmark +public class MicroBenchmarkStreamTests { + + @Benchmark + @Testable + public void testStream(BenchmarkContext context) throws Exception { + context.run(); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext applicationContext; + + volatile InputDestination input; + + volatile OutputDestination output; + + @Param + private Instrumentation instrumentation; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.applicationContext = initContext(); + this.input = this.applicationContext.getBean(InputDestination.class); + this.output = this.applicationContext.getBean(OutputDestination.class); + } + + private void sendInputMessage() { + // System.out.println("Sending the message to input"); + input.send(MessageBuilder.withPayload("hello".getBytes()) + .setHeader("b3", "4883117762eb9420-4883117762eb9420-1").build()); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingStreamApplication.class) + .web(WebApplicationType.NONE).application(); + return application.run(runArgs()); + } + + protected String[] runArgs() { + List strings = new ArrayList<>(); + strings.addAll(Arrays.asList("--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContextForStream" + instrumentation.name() + "_" + + tracerImplementation.name())); + strings.addAll(Arrays.asList(instrumentation.asParams())); + return strings.toArray(new String[0]); + } + + void run() { + sendInputMessage(); + assertThatOutputMessageGotReceived(); + } + + private void assertThatOutputMessageGotReceived() { + // System.out.println("Retrieving the message for tests"); + Message message = output.receive(200L); + // System.out.println("Got the message from output"); + assertThat(message).isNotNull(); + // System.out.println("Message is not null"); + assertThat(message.getPayload()).isEqualTo("HELLO".getBytes()); + // System.out.println("Payload is HELLO"); + if (!instrumentation.toString().toLowerCase().contains("nosleuth")) { + String b3 = message.getHeaders().get("b3", String.class); + // System.out.println("Checking the b3 header [" + b3 + "]"); + assertThat(b3).isNotEmpty(); + if (b3.startsWith("0000000000000000")) { + assertThat(b3).startsWith("00000000000000004883117762eb9420"); + } else { + assertThat(b3).startsWith("4883117762eb9420"); + } + } + } + + @TearDown + public void clean() throws Exception { + Tracing current = Tracing.current(); + if (current != null) { + current.close(); + } + try { + this.applicationContext.close(); + } + catch (Exception ig) { + + } + } + + public enum Instrumentation { + + // @formatter:off + noSleuthSimple(Pair.noSleuth(), function("simple")), + sleuthSimpleOnHooks(function("simple")), + sleuthSimpleOnEach(function("simple"), Pair.noHook(), Pair.onEach()), + sleuthSimpleOnLast(function("simple"), Pair.noHook(), Pair.onLast()), + sleuthSimpleWithAroundOnHooks(function("simple_function_with_around")), + sleuthSimpleWithAroundOnEach(function("simple_function_with_around"), Pair.noHook(), Pair.onEach()), + sleuthSimpleWithAroundOnLast(function("simple_function_with_around"), Pair.noHook(), Pair.onLast()), + noSleuthReactiveSimple(function("reactive_simple"), Pair.noSleuth()), + sleuthReactiveSimpleOnHooks(function("DECORATE_ON_EACH")), + sleuthReactiveSimpleOnEach(function("DECORATE_ON_EACH"), Pair.noHook(), Pair.onEach(), integrationEnabled()); + // @formatter:on + + private List pairs; + + Instrumentation(Pair... pairs) { + this.pairs = Arrays.asList(pairs); + } + + String[] asParams() { + return this.pairs.stream().map(p -> "--" + p.asProp()).collect(Collectors.toList()).toArray(new String[0]); + } + + static Pair function(String type) { + return Pair.of("spring.sleuth.function.type", type); + } + + static Pair integrationEnabled() { + return Pair.of("spring.sleuth.integration.enabled", "true"); + } + } + + } + + @Configuration(proxyBeanMethods = false) + @Import(TestChannelBinderConfiguration.class) + static class TestConfiguration { + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java new file mode 100644 index 000000000..2b622e136 --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java @@ -0,0 +1,146 @@ +/* + * Copyright 2013-2020 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 + * + * https://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.webflux; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import brave.Tracing; +import jmh.mbr.junit5.Microbenchmark; +import org.junit.platform.commons.annotation.Testable; +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.Param; +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.Warmup; + +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.cloud.sleuth.benchmarks.jmh.Pair; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.web.reactive.server.WebTestClient; + +@Measurement(iterations = 10, time = 1) +@Warmup(iterations = 10, time = 1) +@Fork(4) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Microbenchmark +public class MicroBenchmarkHttpTests { + + @Benchmark + @Testable + public void test(BenchmarkContext context) throws Exception { + context.run(); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext applicationContext; + + volatile WebTestClient webTestClient; + + @Param + private Instrumentation instrumentation; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.applicationContext = initContext(); + this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext).build(); + } + + protected ConfigurableApplicationContext initContext() { + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) + .web(WebApplicationType.REACTIVE).application(); + return application.run(runArgs()); + } + + protected String[] runArgs() { + String[] defaultArgs = new String[] { "--spring.jmx.enabled=false", + "--spring.application.name=defaultTraceContext" + instrumentation.name() + "_" + + tracerImplementation.name() }; + List list = new ArrayList<>(Arrays.asList(defaultArgs)); + list.addAll(Arrays.asList(instrumentation.asParams())); + return list.toArray(new String[0]); + } + + void run() { + this.webTestClient.get().uri(instrumentation.url).header("X-B3-TraceId", "4883117762eb9420") + .header("X-B3-SpanId", "4883117762eb9420").exchange().expectStatus().isOk(); + } + + @TearDown + public void clean() throws Exception { + Tracing current = Tracing.current(); + if (current != null) { + current.close(); + } + try { + this.applicationContext.close(); + } + catch (Exception ig) { + + } + } + + public enum Instrumentation { + + // @formatter:off + noSleuthSimple("/simple", Pair.noSleuth()), + sleuthSimpleOnHooks("/simple"), + sleuthSimpleOnEach("/simple", Pair.noHook(), Pair.onEach()), + sleuthSimpleOnLast("/simple", Pair.noHook(), Pair.onLast()), + noSleuthComplex("/complexNoSleuth", Pair.noSleuth()), + onHooksComplex("/complex"), + onEachComplex("/complex", Pair.noHook(), Pair.onEach()), + onLastComplex("/complex", Pair.noHook(), Pair.onLast()); + // @formatter:on + + private String url; + + private List pairs; + + Instrumentation(String url, Pair... pairs) { + this.url = url; + this.pairs = Arrays.asList(pairs); + } + + String[] asParams() { + return this.pairs.stream().map(p -> "--" + p.asProp()).collect(Collectors.toList()).toArray(new String[0]); + } + } + + } + +} diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java similarity index 77% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java index ca0cfd1cd..c11f45a15 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.webflux; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -26,6 +26,7 @@ import brave.httpclient.TracingHttpClientBuilder; import brave.propagation.CurrentTraceContext; import brave.propagation.TraceContext; import brave.sampler.Sampler; +import jmh.mbr.junit5.Microbenchmark; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; @@ -51,32 +52,40 @@ 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.cloud.sleuth.benchmarks.jmh.TracerImplementation; import org.springframework.context.ConfigurableApplicationContext; -@Measurement(iterations = 5, time = 1) +@Measurement(iterations = 10, time = 1) @Warmup(iterations = 10, time = 1) -@Fork(3) +@Fork(4) @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MICROSECONDS) @Threads(2) @State(Scope.Benchmark) -public class SpringWebFluxBenchmarks { +@Microbenchmark +public abstract class SpringWebFluxBenchmarksTests { + static final SpanHandler FAKE_SPAN_HANDLER = new SpanHandler() { // intentionally anonymous to prevent logging fallback on NOOP }; - protected static TraceContext defaultTraceContext = TraceContext.newBuilder() - .traceIdHigh(333L).traceId(444L).spanId(3).sampled(true).build(); + protected static TraceContext defaultTraceContext = TraceContext.newBuilder().traceIdHigh(333L).traceId(444L) + .spanId(3).sampled(true).build(); + protected ConfigurableApplicationContext applicationContext; + protected SleuthBenchmarkingSpringWebFluxApp springWebFluxApp; + CloseableHttpClient client; + CloseableHttpClient tracedClient; + CloseableHttpClient unsampledClient; + private String baseUrl; public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(".*" + SpringWebFluxBenchmarks.class.getSimpleName() + ".*") + Options opt = new OptionsBuilder().include(".*" + SpringWebFluxBenchmarksTests.class.getSimpleName() + ".*") .build(); new Runner(opt).run(); @@ -87,8 +96,7 @@ public class SpringWebFluxBenchmarks { } protected CloseableHttpClient newClient(HttpTracing httpTracing) { - return TracingHttpClientBuilder.create(httpTracing).disableAutomaticRetries() - .build(); + return TracingHttpClientBuilder.create(httpTracing).disableAutomaticRetries().build(); } protected CloseableHttpClient newClient() { @@ -107,21 +115,18 @@ public class SpringWebFluxBenchmarks { public void setup() { ConfigurableApplicationContext context = initContext(); this.applicationContext = context; - this.springWebFluxApp = this.applicationContext - .getBean(SleuthBenchmarkingSpringWebFluxApp.class); + this.springWebFluxApp = this.applicationContext.getBean(SleuthBenchmarkingSpringWebFluxApp.class); baseUrl = "http://127.0.0.1:" + springWebFluxApp.port + "/foo"; client = newClient(); - tracedClient = newClient(HttpTracing - .create(Tracing.newBuilder().addSpanHandler(FAKE_SPAN_HANDLER).build())); - unsampledClient = newClient(HttpTracing.create(Tracing.newBuilder() - .sampler(Sampler.NEVER_SAMPLE).addSpanHandler(FAKE_SPAN_HANDLER).build())); + tracedClient = newClient(HttpTracing.create(Tracing.newBuilder().addSpanHandler(FAKE_SPAN_HANDLER).build())); + unsampledClient = newClient(HttpTracing + .create(Tracing.newBuilder().sampler(Sampler.NEVER_SAMPLE).addSpanHandler(FAKE_SPAN_HANDLER).build())); postSetUp(); } protected ConfigurableApplicationContext initContext() { - SpringApplication application = new SpringApplicationBuilder( - SleuthBenchmarkingSpringWebFluxApp.class).web(WebApplicationType.REACTIVE) - .application(); + SpringApplication application = new SpringApplicationBuilder(SleuthBenchmarkingSpringWebFluxApp.class) + .web(WebApplicationType.REACTIVE).application(); customSpringApplication(application); return application.run(runArgs()); } @@ -134,9 +139,8 @@ public class SpringWebFluxBenchmarks { } protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", - "--spring.application.name=defaultTraceContext", - "--spring.sleuth.enabled=true" }; + return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", + TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true" }; } @TearDown @@ -171,8 +175,7 @@ public class SpringWebFluxBenchmarks { @Benchmark public void tracedClient_get_resumeTrace() throws Exception { - try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext() - .newScope(defaultTraceContext)) { + try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext().newScope(defaultTraceContext)) { get(tracedClient); } } diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutSleuthSpringWebFluxBenchmarks.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java similarity index 57% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutSleuthSpringWebFluxBenchmarks.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java index 6780eba2c..3629040a1 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutSleuthSpringWebFluxBenchmarks.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,31 +14,36 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.webflux; +import jmh.mbr.junit5.Microbenchmark; 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.cloud.sleuth.benchmarks.jmh.TracerImplementation; + /** * @author alvin */ -public class WithOutSleuthSpringWebFluxBenchmarks extends SpringWebFluxBenchmarks { +@Microbenchmark +public class WithOutReactorSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests { public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder().include( - ".*" + WithOutSleuthSpringWebFluxBenchmarks.class.getSimpleName() + ".*") - .build(); + Options opt = new OptionsBuilder() + .include(".*" + WithOutReactorSleuthSpringWebFluxBenchmarksTests.class.getSimpleName() + ".*").build(); new Runner(opt).run(); } @Override protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", - "--spring.application.name=defaultTraceContext", - "--spring.sleuth.enabled=false" }; + return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", + TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true", + "--spring.sleuth.reactor.enabled=false" + + }; } @Override diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutReactorSleuthSpringWebFluxBenchmarks.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java similarity index 59% rename from benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutReactorSleuthSpringWebFluxBenchmarks.java rename to benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java index 111d86c15..8185d0c20 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/WithOutReactorSleuthSpringWebFluxBenchmarks.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,34 +14,33 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.benchmarks.jmh.benchmarks; +package org.springframework.cloud.sleuth.benchmarks.jmh.webflux; +import jmh.mbr.junit5.Microbenchmark; 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.cloud.sleuth.benchmarks.jmh.TracerImplementation; + /** * @author alvin */ -public class WithOutReactorSleuthSpringWebFluxBenchmarks extends SpringWebFluxBenchmarks { +@Microbenchmark +public class WithOutSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests { public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder().include( - ".*" + WithOutReactorSleuthSpringWebFluxBenchmarks.class.getSimpleName() - + ".*") - .build(); + Options opt = new OptionsBuilder() + .include(".*" + WithOutSleuthSpringWebFluxBenchmarksTests.class.getSimpleName() + ".*").build(); new Runner(opt).run(); } @Override protected String[] runArgs() { - return new String[] { "--spring.jmx.enabled=false", - "--spring.application.name=defaultTraceContext", - "--spring.sleuth.enabled=true", "--spring.sleuth.reactor.enabled=false" - - }; + return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", + TracerImplementation.brave.toString(), "--spring.sleuth.enabled=false" }; } @Override diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc index ad529b01a..f207bf515 100644 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc @@ -1526,19 +1526,14 @@ To turn off this feature, set the `spring.sleuth.quartz.enabled` property to `fa === Project Reactor +==== From Spring Cloud Sleuth 2.2.8 (inclusive) + +With the new Reactor https://github.com/reactor/reactor-core/pull/2566[queue wrapping mechanism] (Reactor 3.3.14) we're instrumenting the way threads are switched by Reactor. You should observe significant improvement in performance. In order to disable this feature you have to set the `spring.sleuth.reactor.decorate-hooks` option to `false`. You'll fall back to the previous instrumentation mode mechanism. + +==== To Spring Cloud Sleuth 2.2.8 (exclusive) + For projects depending on Project Reactor such as Spring Cloud Gateway, we suggest turning the `spring.sleuth.reactor.decorate-on-each` option to `false`. That way an increased performance gain should be observed in comparison to the standard instrumentation mechanism. What this option does is it will wrap decorate `onLast` operator instead of `onEach` which will result in creation of far fewer objects. The downside of this is that when Project Reactor will change threads, the trace propagation will continue without issues, however anything relying on the `ThreadLocal` such as e.g. MDC entries can be buggy. == Configuration properties To see the list of all Sleuth related configuration properties please check link:appendix.html[the Appendix page]. - -== Running examples - -You can see the running examples deployed in the https://run.pivotal.io/[Pivotal Web Services]. -Check them out at the following links: - -* https://docssleuth-zipkin-server.cfapps.io/[Zipkin for apps presented in the samples to the top]. First make -a request to https://docssleuth-service1.cfapps.io/start[Service 1] and then check out the trace in Zipkin. -* https://docsbrewing-zipkin-server.cfapps.io/[Zipkin for Brewery on PWS], its https://github.com/spring-cloud-samples/brewery[Github Code]. -Ensure that you've picked the lookback period of 7 days. If there are no traces, go to https://docsbrewing-presenting.cfapps.io/[Presenting application] -and order some beers. Then check Zipkin for traces. diff --git a/pom.xml b/pom.xml index 62f0b08af..4d018f908 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.springframework.cloud spring-cloud-build - 2.3.2.RELEASE + 2.3.3.BUILD-SNAPSHOT diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java index 345bfbb8a..690685c4b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java @@ -129,6 +129,29 @@ public abstract class ReactorSleuth { }); } + public static Function scopePassingOnScheduleHook( + ConfigurableApplicationContext springContext) { + LazyBean lazyCurrentTraceContext = LazyBean + .create(springContext, CurrentTraceContext.class); + return delegate -> { + if (springContext.isActive()) { + final CurrentTraceContext currentTraceContext = lazyCurrentTraceContext + .get(); + if (currentTraceContext == null) { + return delegate; + } + final TraceContext traceContext = currentTraceContext.get(); + return () -> { + try (CurrentTraceContext.Scope scope = currentTraceContext + .maybeScope(traceContext)) { + delegate.run(); + } + }; + } + return delegate; + }; + } + private static Context context(CoreSubscriber sub) { try { return sub.currentContext(); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java index fa1d433d1..4a7315164 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java @@ -33,11 +33,21 @@ public class SleuthReactorProperties { */ private boolean enabled = true; + /** + * When true uses the new decorate hooks feature from Project Reactor. Should allow + * the feature set of {@link SleuthReactorProperties#decorateOnEach} with the least + * impact on the performance. + */ + private boolean decorateHooks = 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. + * + * If {@link SleuthReactorProperties#decorateHooks} is used, this decoration mode will + * NOT be used. */ private boolean decorateOnEach = true; @@ -49,6 +59,14 @@ public class SleuthReactorProperties { this.enabled = enabled; } + public boolean isDecorateHooks() { + return this.decorateHooks; + } + + public void setDecorateHooks(boolean decorateHooks) { + this.decorateHooks = decorateHooks; + } + public boolean isDecorateOnEach() { return this.decorateOnEach; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java index 87e0eb510..1a6ee4252 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java @@ -16,9 +16,18 @@ package org.springframework.cloud.sleuth.instrument.reactor; +import java.io.Closeable; +import java.io.IOException; +import java.util.AbstractQueue; +import java.util.Iterator; +import java.util.Queue; +import java.util.function.Function; + import javax.annotation.PreDestroy; import brave.Tracing; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Hooks; @@ -37,15 +46,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.context.scope.refresh.RefreshScope; import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; -import org.springframework.cloud.sleuth.instrument.async.TraceableScheduledExecutorService; import org.springframework.cloud.sleuth.instrument.web.TraceWebFluxAutoConfiguration; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.util.ReflectionUtils; import static org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth.scopePassingSpanOperator; +import static org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY; import static org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY; /** @@ -77,6 +87,8 @@ public class TraceReactorAutoConfiguration { private static final Log log = LogFactory.getLog(TraceReactorConfiguration.class); + static final boolean IS_QUEUE_WRAPPER_ON_THE_CLASSPATH = isQueueWrapperOnTheClasspath(); + @Autowired ConfigurableApplicationContext springContext; @@ -87,6 +99,13 @@ public class TraceReactorAutoConfiguration { } SleuthReactorProperties reactorProperties = this.springContext .getBean(SleuthReactorProperties.class); + if (TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH + && reactorProperties.isDecorateHooks()) { + if (log.isTraceEnabled()) { + log.trace("Resetting queue wrapper instrumentation"); + } + Hooks.removeQueueWrapper(SLEUTH_TRACE_REACTOR_KEY); + } if (reactorProperties.isDecorateOnEach()) { if (log.isTraceEnabled()) { log.trace("Resetting onEach operator instrumentation"); @@ -99,8 +118,11 @@ public class TraceReactorAutoConfiguration { } Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); } - Schedulers - .removeExecutorServiceDecorator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + } + + private static boolean isQueueWrapperOnTheClasspath() { + return ReflectionUtils.findMethod(Hooks.class, "addQueueWrapper", + String.class, Function.class) != null; } @Bean @@ -152,12 +174,23 @@ class HooksRefresher implements ApplicationListener } Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); - if (this.reactorProperties.isDecorateOnEach()) { + Hooks.removeQueueWrapper(SLEUTH_TRACE_REACTOR_KEY); + if (this.reactorProperties.isDecorateHooks() + && TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH) { + if (log.isTraceEnabled()) { + log.trace("Adding queue wrapper instrumentation"); + } + HookRegisteringBeanDefinitionRegistryPostProcessor.addQueueWrapper(context); + } + else if (this.reactorProperties.isDecorateOnEach()) { if (log.isTraceEnabled()) { log.trace("Decorating onEach operator instrumentation"); } Hooks.onEachOperator(SLEUTH_TRACE_REACTOR_KEY, scopePassingSpanOperator(this.context)); + Schedulers.onScheduleHook( + TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY, + ReactorSleuth.scopePassingOnScheduleHook(this.context)); } else { if (log.isTraceEnabled()) { @@ -171,7 +204,7 @@ class HooksRefresher implements ApplicationListener } class HookRegisteringBeanDefinitionRegistryPostProcessor - implements BeanDefinitionRegistryPostProcessor { + implements BeanDefinitionRegistryPostProcessor, Closeable { private static final Log log = LogFactory .getLog(HookRegisteringBeanDefinitionRegistryPostProcessor.class); @@ -194,27 +227,165 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor static void setupHooks(ConfigurableApplicationContext springContext) { ConfigurableEnvironment environment = springContext.getEnvironment(); - boolean decorateOnEach = environment.getProperty( - "spring.sleuth.reactor.decorate-on-each", Boolean.class, true); - if (decorateOnEach) { - if (log.isTraceEnabled()) { - log.trace("Decorating onEach operator instrumentation"); - } - Hooks.onEachOperator(SLEUTH_TRACE_REACTOR_KEY, - scopePassingSpanOperator(springContext)); + Boolean decorateHooks = environment + .getProperty("spring.sleuth.reactor.decorate-hooks", Boolean.class); + if (wrapperNotOnClasspathButPropertyHasValue(decorateHooks)) { + log.warn( + "You have explicitly set the decorate hooks option but you're using an old version of Reactor. Please upgrade to the latest Boot version (at least 2.3.9.RELEASE). Will fall back to the previous reactor instrumentation mode"); } else { - if (log.isTraceEnabled()) { - log.trace("Decorating onLast operator instrumentation"); - } - Hooks.onLastOperator(SLEUTH_TRACE_REACTOR_KEY, - scopePassingSpanOperator(springContext)); + decorateHooks = decorateHooks != null ? decorateHooks : Boolean.TRUE; } - Schedulers.setExecutorServiceDecorator( + if (wrapperOnClasspathHooksPropertyTurnedOn(decorateHooks)) { + if (log.isTraceEnabled()) { + log.trace("Adding queue wrapper instrumentation"); + } + addQueueWrapper(springContext); + } + else { + boolean decorateOnEach = environment.getProperty( + "spring.sleuth.reactor.decorate-on-each", Boolean.class, true); + if (decorateOnEach) { + if (log.isTraceEnabled()) { + log.trace("Decorating onEach operator instrumentation"); + } + Hooks.onEachOperator(SLEUTH_TRACE_REACTOR_KEY, + scopePassingSpanOperator(springContext)); + } + else { + if (log.isTraceEnabled()) { + log.trace("Decorating onLast operator instrumentation"); + } + Hooks.onLastOperator(SLEUTH_TRACE_REACTOR_KEY, + scopePassingSpanOperator(springContext)); + } + } + decorateScheduler(springContext); + } + + private static boolean wrapperOnClasspathHooksPropertyTurnedOn(Boolean decorateHooks) { + return Boolean.TRUE.equals(decorateHooks) + && TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH; + } + + private static boolean wrapperNotOnClasspathButPropertyHasValue(Boolean decorateHooks) { + return !TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH + && decorateHooks != null; + } + + static void addQueueWrapper(ConfigurableApplicationContext springContext) { + Hooks.addQueueWrapper(SLEUTH_TRACE_REACTOR_KEY, + queue -> traceQueue(springContext, queue)); + } + + @Override + public void close() throws IOException { + if (log.isTraceEnabled()) { + log.trace("Cleaning up hooks"); + } + Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); + Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); + Hooks.removeQueueWrapper(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + Schedulers.resetOnScheduleHook(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + Schedulers.resetOnScheduleHook( + TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + } + + private static void decorateScheduler(ConfigurableApplicationContext springContext) { + Schedulers.onScheduleHook( TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY, - (scheduler, - scheduledExecutorService) -> new TraceableScheduledExecutorService( - springContext, scheduledExecutorService)); + ReactorSleuth.scopePassingOnScheduleHook(springContext)); + } + + private static Queue traceQueue(ConfigurableApplicationContext springContext, + Queue queue) { + if (!springContext.isActive()) { + return queue; + } + CurrentTraceContext currentTraceContext = springContext + .getBean(CurrentTraceContext.class); + @SuppressWarnings("unchecked") + Queue envelopeQueue = queue; + return new AbstractQueue() { + + @Override + public int size() { + return envelopeQueue.size(); + } + + @Override + public boolean offer(Object o) { + TraceContext traceContext = currentTraceContext.get(); + return envelopeQueue.offer(new Envelope(o, traceContext)); + } + + @Override + public Object poll() { + Object object = envelopeQueue.poll(); + if (object == null) { + return null; + } + else if (object instanceof Envelope) { + Envelope envelope = (Envelope) object; + restoreTheContext(envelope); + return envelope.body; + } + return object; + } + + private void restoreTheContext(Envelope envelope) { + if (envelope.traceContext != null) { + currentTraceContext.maybeScope(envelope.traceContext); + } + } + + @Override + public Object peek() { + Object peek = queue.peek(); + if (peek instanceof Envelope) { + Envelope envelope = (Envelope) peek; + restoreTheContext(envelope); + return (envelope).body; + } + return peek; + } + + @Override + @SuppressWarnings("unchecked") + public Iterator iterator() { + Iterator iterator = queue.iterator(); + return new Iterator() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Object next() { + Object next = iterator.next(); + if (next instanceof Envelope) { + Envelope envelope = (Envelope) next; + restoreTheContext(envelope); + return (envelope).body; + } + return next; + } + }; + } + }; + } + + static class Envelope { + + final Object body; + + final TraceContext traceContext; + + Envelope(Object body, TraceContext traceContext) { + this.body = body; + this.traceContext = traceContext; + } + } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java new file mode 100644 index 000000000..597548afe --- /dev/null +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java @@ -0,0 +1,118 @@ +/* + * Copyright 2013-2019 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 + * + * https://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.instrument.web; + +import java.util.concurrent.atomic.AtomicReference; + +import brave.Span; +import brave.propagation.CurrentTraceContext; +import reactor.core.publisher.Mono; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.web.reactive.HandlerAdapter; +import org.springframework.web.reactive.HandlerResult; +import org.springframework.web.reactive.function.server.HandlerFunction; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.support.HandlerFunctionAdapter; +import org.springframework.web.server.ServerWebExchange; + +class TraceHandlerFunctionAdapterBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + TraceHandlerFunctionAdapterBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof HandlerFunctionAdapter) { + return new TraceHandlerAdapter((HandlerAdapter) bean, this.beanFactory); + } + return bean; + } + + private static final class TraceHandlerAdapter implements HandlerAdapter { + + private final BeanFactory beanFactory; + + private final HandlerAdapter delegate; + + private TraceHandlerAdapter(HandlerAdapter delegate, BeanFactory beanFactory) { + this.delegate = delegate; + this.beanFactory = beanFactory; + } + + @Override + public boolean supports(Object handler) { + return this.delegate.supports(handler); + } + + @Override + public Mono handle(ServerWebExchange exchange, Object handler) { + HandlerFunction handlerFunction = (HandlerFunction) handler; + TraceHandlerFunction traceHandlerFunction = new TraceHandlerFunction( + handlerFunction, this.beanFactory); + return this.delegate.handle(exchange, traceHandlerFunction); + } + + } + + private static final class TraceHandlerFunction implements HandlerFunction { + + private final HandlerFunction delegate; + + private final BeanFactory beanFactory; + + private CurrentTraceContext currentTraceContext; + + private TraceHandlerFunction(HandlerFunction delegate, + BeanFactory beanFactory) { + this.delegate = delegate; + this.beanFactory = beanFactory; + } + + @Override + public Mono handle(ServerRequest serverRequest) { + AtomicReference scope = new AtomicReference<>(); + return Mono.just(scope).doFirst(() -> serverRequest + .attribute(TraceWebFilter.TRACE_REQUEST_ATTR) + .ifPresent(span -> scope.set( + currentTraceContext().maybeScope(((Span) span).context())))) + .flatMap(r -> this.delegate.handle(serverRequest)) + .doFinally(signalType -> { + CurrentTraceContext.Scope spanInScope = scope.get(); + if (spanInScope != null) { + spanInScope.close(); + } + }); + } + + private CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.beanFactory + .getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + + } + +} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java index df0795bba..cdcee9f52 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java @@ -25,6 +25,7 @@ import brave.http.HttpServerHandler; import brave.http.HttpServerRequest; import brave.http.HttpServerResponse; import brave.http.HttpTracing; +import brave.propagation.CurrentTraceContext; import brave.propagation.TraceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -79,11 +80,13 @@ public final class TraceWebFilter implements WebFilter, Ordered { private final BeanFactory beanFactory; - Tracer tracer; + private Tracer tracer; - HttpServerHandler handler; + private HttpServerHandler handler; - SleuthWebProperties webProperties; + private SleuthWebProperties webProperties; + + private CurrentTraceContext currentTraceContext; TraceWebFilter(BeanFactory beanFactory) { this.beanFactory = beanFactory; @@ -94,7 +97,7 @@ public final class TraceWebFilter implements WebFilter, Ordered { } @SuppressWarnings("unchecked") - HttpServerHandler handler() { + private HttpServerHandler handler() { if (this.handler == null) { this.handler = HttpServerHandler .create(this.beanFactory.getBean(HttpTracing.class)); @@ -102,32 +105,40 @@ public final class TraceWebFilter implements WebFilter, Ordered { return this.handler; } - Tracer tracer() { + private Tracer tracer() { if (this.tracer == null) { this.tracer = this.beanFactory.getBean(HttpTracing.class).tracing().tracer(); } return this.tracer; } - SleuthWebProperties sleuthWebProperties() { + private SleuthWebProperties sleuthWebProperties() { if (this.webProperties == null) { this.webProperties = this.beanFactory.getBean(SleuthWebProperties.class); } return this.webProperties; } + private CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.beanFactory + .getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + @Override public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { String uri = exchange.getRequest().getPath().pathWithinApplication().value(); - if (log.isDebugEnabled()) { - log.debug("Received a request to uri [" + uri + "]"); - } Mono source = chain.filter(exchange); boolean tracePresent = tracer().currentSpan() != null; if (tracePresent) { // clear any previous trace tracer().withSpanInScope(null); // TODO: dangerous and also allocates stuff } + if (log.isDebugEnabled()) { + log.debug("Received a request to uri [" + uri + "]"); + } return new MonoWebFilterTrace(source, exchange, tracePresent, this); } @@ -150,11 +161,14 @@ public final class TraceWebFilter implements WebFilter, Ordered { final boolean initialTracePresent; + final CurrentTraceContext currentTraceContext; + MonoWebFilterTrace(Mono source, ServerWebExchange exchange, boolean initialTracePresent, TraceWebFilter parent) { super(source); this.tracer = parent.tracer(); this.handler = parent.handler(); + this.currentTraceContext = parent.currentTraceContext(); this.exchange = exchange; this.attrSpan = exchange.getAttribute(TRACE_REQUEST_ATTR); this.initialTracePresent = initialTracePresent; @@ -163,8 +177,12 @@ public final class TraceWebFilter implements WebFilter, Ordered { @Override public void subscribe(CoreSubscriber subscriber) { Context context = contextWithoutInitialSpan(subscriber.currentContext()); - this.source.subscribe(new WebFilterTraceSubscriber(subscriber, context, - findOrCreateSpan(context), this)); + Span span = findOrCreateSpan(context); + try (CurrentTraceContext.Scope scope = this.currentTraceContext + .maybeScope(span.context())) { + this.source.subscribe( + new WebFilterTraceSubscriber(subscriber, context, span, this)); + } } private Context contextWithoutInitialSpan(Context context) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java index 98681504a..371a136ae 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java @@ -48,4 +48,10 @@ public class TraceWebFluxAutoConfiguration { return new TraceWebFilter(beanFactory); } + @Bean + public TraceHandlerFunctionAdapterBeanPostProcessor traceHandlerFunctionAdapterBeanPostProcessor( + BeanFactory beanFactory) { + return new TraceHandlerFunctionAdapterBeanPostProcessor(beanFactory); + } + } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java index 664007e9a..93d61b35f 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java @@ -92,6 +92,7 @@ public class SleuthSpanCreatorAspectFluxTests { public void setup() { this.spans.clear(); this.testBean.reset(); + tracer.withSpanInScope(null); } @Test diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java index 1eaed8285..46884b39d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java @@ -56,6 +56,7 @@ public class SleuthSpanCreatorAspectTests { @Before public void setup() { this.spans.clear(); + tracer.withSpanInScope(null); } @Test diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java index 763574221..ea7808e47 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java @@ -44,7 +44,8 @@ public final class TraceReactorAutoConfigurationAccessorConfiguration { } Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); - Schedulers.removeExecutorServiceDecorator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + Hooks.removeQueueWrapper(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + Schedulers.resetOnScheduleHook(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); } public static void setup(ConfigurableApplicationContext context) { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java index a10b9efd5..35583e4f6 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java @@ -62,6 +62,7 @@ public class IgnoreAutoConfiguredSkipPatternsIntegrationTests { @After public void clearSpans() { this.spans.clear(); + tracer.withSpanInScope(null); } @Test diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/Issue866Configuration.java b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/Issue866Configuration.java index 0dfd4730f..6ebe82aae 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/Issue866Configuration.java +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/Issue866Configuration.java @@ -40,7 +40,7 @@ public class Issue866Configuration { public static TestHook hook; @Bean - HookRegisteringBeanDefinitionRegistryPostProcessor overridingProcessorForTests( + static HookRegisteringBeanDefinitionRegistryPostProcessor overridingProcessorForTests( ConfigurableApplicationContext context) { log.info( "Registering a HookRegisteringBeanDefinitionRegistryPostProcessor for context [" diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java index ef0a6bbd8..2da6b2892 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberSpringBootTests.java @@ -25,6 +25,7 @@ import brave.propagation.TraceContext; import brave.sampler.Sampler; import org.awaitility.Awaitility; import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; import org.junit.runner.RunWith; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -58,6 +59,11 @@ public class ScopePassingSpanSubscriberSpringBootTests { TraceContext context2 = TraceContext.newBuilder().traceId(1).spanId(2).sampled(true) .build(); + @BeforeAll + static void setup() { + TraceReactorAutoConfigurationAccessorConfiguration.close(); + } + @Test public void should_pass_tracing_info_when_using_reactor() { final AtomicReference spanInOperation = new AtomicReference<>(); diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java index 013a15105..2004532c2 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/ScopePassingSpanSubscriberTests.java @@ -148,7 +148,8 @@ public class ScopePassingSpanSubscriberTests { // prevent should_not_scope_scalar_subscribe from being interfered with. Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); - Schedulers.removeExecutorServiceDecorator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + Hooks.removeQueueWrapper(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + Schedulers.resetOnScheduleHook(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); } @After diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java index 763574221..abf618814 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java @@ -16,16 +16,13 @@ package org.springframework.cloud.sleuth.instrument.reactor; +import java.io.IOException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Hooks; -import reactor.core.scheduler.Schedulers; import org.springframework.context.ConfigurableApplicationContext; -import static org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY; -import static org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY; - /** * @author Marcin Grzejszczak */ @@ -42,9 +39,12 @@ public final class TraceReactorAutoConfigurationAccessorConfiguration { if (log.isTraceEnabled()) { log.trace("Cleaning up hooks"); } - Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY); - Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY); - Schedulers.removeExecutorServiceDecorator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY); + try { + new HookRegisteringBeanDefinitionRegistryPostProcessor(null).close(); + } + catch (IOException e) { + throw new IllegalStateException(e); + } } public static void setup(ConfigurableApplicationContext context) { diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java index 1c70558bf..c5bd95949 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java @@ -30,6 +30,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; @@ -74,14 +75,35 @@ public class FlatMapTests { Issue866Configuration.hook = null; } + @BeforeEach + void before() { + TraceReactorAutoConfigurationAccessorConfiguration.close(); + } + @Test - public void should_work_with_flat_maps() { + public void should_work_with_flat_maps_on_hooks_instrumentation() { // given ConfigurableApplicationContext context = new SpringApplicationBuilder( FlatMapTests.TestConfiguration.class, Issue866Configuration.class) .web(WebApplicationType.REACTIVE) .properties("server.port=0", "spring.jmx.enabled=false", - "spring.application.name=TraceWebFluxTests", + "spring.application.name=TraceWebFluxOnHooksTests", + "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + assertReactorTracing(context); + } + + @Test + public void should_work_with_flat_maps_on_each_operator_instrumentation() { + // given + ConfigurableApplicationContext context = new SpringApplicationBuilder( + FlatMapTests.TestConfiguration.class, Issue866Configuration.class) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.jmx.enabled=false", + "spring.sleuth.reactor.decorate-hooks=false", + "spring.sleuth.reactor.decorate-on-each=true", + "spring.application.name=TraceWebFluxOnEachTests", "security.basic.enabled=false", "management.security.enabled=false") .run(); @@ -95,20 +117,23 @@ public class FlatMapTests { FlatMapTests.TestConfiguration.class, Issue866Configuration.class) .web(WebApplicationType.REACTIVE) .properties("server.port=0", "spring.jmx.enabled=false", + "spring.sleuth.reactor.decorate-hooks=false", "spring.sleuth.reactor.decorate-on-each=false", - "spring.application.name=TraceWebFlux2Tests", + "spring.application.name=TraceWebFluxOnLastTests", "security.basic.enabled=false", "management.security.enabled=false") .run(); assertReactorTracing(context); try { - System.setProperty("spring.sleuth.reactor.decorate-on-each", "true"); + System.setProperty("spring.sleuth.reactor.decorate-hooks", "false"); + System.setProperty("spring.sleuth.reactor.decorate-on-each", "false"); // trigger context refreshed context.getBean(ContextRefresher.class).refresh(); assertReactorTracing(context); } finally { + System.clearProperty("spring.sleuth.reactor.decorate-hooks"); System.clearProperty("spring.sleuth.reactor.decorate-on-each"); } } @@ -196,11 +221,11 @@ public class FlatMapTests { RouterFunction handlers(Tracer tracer, RequestSender requestSender) { return route(GET("/noFlatMap"), request -> { - LOGGER.info("noFlatMap"); + LOGGER.info("noFlatMap [" + request + "]"); Flux one = requestSender.getAll().map(String::length); return ServerResponse.ok().body(one, Integer.class); }).andRoute(GET("/withFlatMap"), request -> { - LOGGER.info("withFlatMap"); + LOGGER.info("withFlatMap [" + request + "]"); Flux one = requestSender.getAll().map(String::length); Flux response = one .flatMap(size -> requestSender.getAll().doOnEach( @@ -211,7 +236,7 @@ public class FlatMapTests { }); return ServerResponse.ok().body(response, Integer.class); }).andRoute(GET("/foo"), request -> { - LOGGER.info("foo"); + LOGGER.info("foo [" + request + "]"); this.spanInFoo = tracer.currentSpan(); return ServerResponse.ok().body(Flux.just(1), Integer.class); }); diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml index f1e4a6a92..775f0d904 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/resources/application.yml @@ -1,3 +1,3 @@ -logging.level.org.springframework.cloud: DEBUG +logging.level.org.springframework.cloud: TRACE logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE \ No newline at end of file From de33b9173947cd2169582fd8befbbb0b2ce46529 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 25 Feb 2021 12:43:46 +0100 Subject: [PATCH 05/78] Upgraded copyrights --- .../org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java | 2 +- .../cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java | 2 +- .../cloud/sleuth/benchmarks/jmh/TracerImplementation.java | 2 +- .../cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java | 2 +- .../java/org/springframework/cloud/sleuth/DefaultSpanNamer.java | 2 +- .../java/org/springframework/cloud/sleuth/LocalServiceName.java | 2 +- .../java/org/springframework/cloud/sleuth/SpanAdjuster.java | 2 +- .../main/java/org/springframework/cloud/sleuth/SpanName.java | 2 +- .../main/java/org/springframework/cloud/sleuth/SpanNamer.java | 2 +- .../annotation/AbstractSleuthMethodInvocationProcessor.java | 2 +- .../springframework/cloud/sleuth/annotation/ContinueSpan.java | 2 +- .../cloud/sleuth/annotation/DefaultSpanCreator.java | 2 +- .../org/springframework/cloud/sleuth/annotation/NewSpan.java | 2 +- .../springframework/cloud/sleuth/annotation/NewSpanParser.java | 2 +- .../cloud/sleuth/annotation/NoOpTagValueResolver.java | 2 +- .../annotation/NonReactorSleuthMethodInvocationProcessor.java | 2 +- .../annotation/ReactorSleuthMethodInvocationProcessor.java | 2 +- .../cloud/sleuth/annotation/SleuthAdvisorConfig.java | 2 +- .../cloud/sleuth/annotation/SleuthAnnotatedParameter.java | 2 +- .../sleuth/annotation/SleuthAnnotationAutoConfiguration.java | 2 +- .../cloud/sleuth/annotation/SleuthAnnotationProperties.java | 2 +- .../cloud/sleuth/annotation/SleuthAnnotationUtils.java | 2 +- .../sleuth/annotation/SleuthMethodInvocationProcessor.java | 2 +- .../org/springframework/cloud/sleuth/annotation/SpanTag.java | 2 +- .../cloud/sleuth/annotation/SpanTagAnnotationHandler.java | 2 +- .../cloud/sleuth/annotation/SpelTagValueExpressionResolver.java | 2 +- .../cloud/sleuth/annotation/TagValueExpressionResolver.java | 2 +- .../cloud/sleuth/annotation/TagValueResolver.java | 2 +- .../cloud/sleuth/autoconfig/SleuthBaggageProperties.java | 2 +- .../cloud/sleuth/autoconfig/SleuthProperties.java | 2 +- .../cloud/sleuth/autoconfig/TraceAutoConfiguration.java | 2 +- .../cloud/sleuth/autoconfig/TraceBaggageConfiguration.java | 2 +- .../cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java | 2 +- .../cloud/sleuth/instrument/async/AsyncAutoConfiguration.java | 2 +- .../sleuth/instrument/async/AsyncCustomAutoConfiguration.java | 2 +- .../sleuth/instrument/async/AsyncDefaultAutoConfiguration.java | 2 +- .../sleuth/instrument/async/ExecutorBeanPostProcessor.java | 2 +- .../cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java | 2 +- .../sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java | 2 +- .../cloud/sleuth/instrument/async/LazyTraceExecutor.java | 2 +- .../instrument/async/LazyTraceThreadPoolTaskExecutor.java | 2 +- .../instrument/async/LazyTraceThreadPoolTaskScheduler.java | 2 +- .../cloud/sleuth/instrument/async/SleuthAsyncProperties.java | 2 +- .../cloud/sleuth/instrument/async/TraceAsyncAspect.java | 2 +- .../instrument/async/TraceAsyncListenableTaskExecutor.java | 2 +- .../cloud/sleuth/instrument/async/TraceCallable.java | 2 +- .../cloud/sleuth/instrument/async/TraceRunnable.java | 2 +- .../cloud/sleuth/instrument/async/TraceableExecutorService.java | 2 +- .../instrument/async/TraceableScheduledExecutorService.java | 2 +- .../circuitbreaker/SleuthCircuitBreakerAutoConfiguration.java | 2 +- .../circuitbreaker/SleuthCircuitBreakerProperties.java | 2 +- .../cloud/sleuth/instrument/circuitbreaker/TraceFunction.java | 2 +- .../cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java | 2 +- .../instrument/grpc/GrpcManagedChannelBuilderCustomizer.java | 2 +- .../instrument/grpc/SpringAwareManagedChannelBuilder.java | 2 +- .../sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java | 2 +- .../instrument/grpc/TracingManagedChannelBuilderCustomizer.java | 2 +- .../instrument/hystrix/SleuthHystrixAutoConfiguration.java | 2 +- .../instrument/hystrix/SleuthHystrixConcurrencyStrategy.java | 2 +- .../hystrix/SleuthHystrixConcurrencyStrategyProperties.java | 2 +- .../cloud/sleuth/instrument/hystrix/TraceCommand.java | 2 +- .../cloud/sleuth/instrument/messaging/ConsumerSampler.java | 2 +- .../instrument/messaging/DefaultMessageSpanCustomizer.java | 2 +- .../sleuth/instrument/messaging/MessageHeaderPropagation.java | 2 +- .../sleuth/instrument/messaging/MessageSpanCustomizer.java | 2 +- .../cloud/sleuth/instrument/messaging/OnMessagingEnabled.java | 2 +- .../cloud/sleuth/instrument/messaging/ProducerSampler.java | 2 +- .../instrument/messaging/SleuthKafkaStreamsConfiguration.java | 2 +- .../sleuth/instrument/messaging/SleuthMessagingProperties.java | 2 +- .../cloud/sleuth/instrument/messaging/TraceMessageHeaders.java | 2 +- .../instrument/messaging/TraceMessagingAutoConfiguration.java | 2 +- .../messaging/TraceSpringIntegrationAutoConfiguration.java | 2 +- .../messaging/TraceSpringMessagingAutoConfiguration.java | 2 +- .../messaging/TracingConnectionFactoryBeanPostProcessor.java | 2 +- .../messaging/TracingMethodMessageHandlerAdapter.java | 2 +- .../messaging/websocket/TraceWebSocketAutoConfiguration.java | 2 +- .../instrument/opentracing/OpentracingAutoConfiguration.java | 2 +- .../instrument/opentracing/SleuthOpentracingProperties.java | 2 +- .../sleuth/instrument/quartz/TraceQuartzAutoConfiguration.java | 2 +- .../cloud/sleuth/instrument/quartz/TracingJobListener.java | 2 +- .../cloud/sleuth/instrument/reactor/ReactorSleuth.java | 2 +- .../sleuth/instrument/reactor/ScopePassingSpanSubscriber.java | 2 +- .../sleuth/instrument/reactor/SleuthReactorProperties.java | 2 +- .../cloud/sleuth/instrument/reactor/SpanSubscriber.java | 2 +- .../cloud/sleuth/instrument/reactor/SpanSubscription.java | 2 +- .../instrument/reactor/TraceReactorAutoConfiguration.java | 2 +- .../sleuth/instrument/redis/TraceRedisAutoConfiguration.java | 2 +- .../cloud/sleuth/instrument/redis/TraceRedisProperties.java | 2 +- .../cloud/sleuth/instrument/rpc/RpcClientSampler.java | 2 +- .../cloud/sleuth/instrument/rpc/RpcServerSampler.java | 2 +- .../cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java | 2 +- .../cloud/sleuth/instrument/rxjava/RxJavaAutoConfiguration.java | 2 +- .../sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java | 2 +- .../instrument/rxjava/SleuthRxJavaSchedulersProperties.java | 2 +- .../instrument/scheduling/SleuthSchedulingProperties.java | 2 +- .../sleuth/instrument/scheduling/TraceSchedulingAspect.java | 2 +- .../instrument/scheduling/TraceSchedulingAutoConfiguration.java | 2 +- .../cloud/sleuth/instrument/web/ClientSampler.java | 2 +- .../cloud/sleuth/instrument/web/ExceptionLoggingFilter.java | 2 +- .../cloud/sleuth/instrument/web/HttpClientRequestParser.java | 2 +- .../cloud/sleuth/instrument/web/HttpClientResponseParser.java | 2 +- .../cloud/sleuth/instrument/web/HttpClientSampler.java | 2 +- .../cloud/sleuth/instrument/web/HttpServerRequestParser.java | 2 +- .../cloud/sleuth/instrument/web/HttpServerResponseParser.java | 2 +- .../cloud/sleuth/instrument/web/HttpServerSampler.java | 2 +- .../cloud/sleuth/instrument/web/ServerSampler.java | 2 +- .../cloud/sleuth/instrument/web/ServletUtils.java | 2 +- .../cloud/sleuth/instrument/web/SingleSkipPattern.java | 2 +- .../cloud/sleuth/instrument/web/SkipPatternProvider.java | 2 +- .../cloud/sleuth/instrument/web/SkipPatternSampler.java | 2 +- .../cloud/sleuth/instrument/web/SleuthHttpClientParser.java | 2 +- .../cloud/sleuth/instrument/web/SleuthHttpLegacyProperties.java | 2 +- .../cloud/sleuth/instrument/web/SleuthHttpProperties.java | 2 +- .../cloud/sleuth/instrument/web/SleuthHttpServerParser.java | 2 +- .../cloud/sleuth/instrument/web/SleuthWebProperties.java | 2 +- .../web/TraceHandlerFunctionAdapterBeanPostProcessor.java | 2 +- .../cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java | 2 +- .../springframework/cloud/sleuth/instrument/web/TraceKeys.java | 2 +- .../cloud/sleuth/instrument/web/TraceWebAspect.java | 2 +- .../cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java | 2 +- .../cloud/sleuth/instrument/web/TraceWebFilter.java | 2 +- .../sleuth/instrument/web/TraceWebFluxAutoConfiguration.java | 2 +- .../cloud/sleuth/instrument/web/TraceWebMvcConfigurer.java | 2 +- .../sleuth/instrument/web/TraceWebServletAutoConfiguration.java | 2 +- .../instrument/web/client/HttpClientBeanPostProcessor.java | 2 +- .../sleuth/instrument/web/client/SleuthWebClientEnabled.java | 2 +- .../instrument/web/client/TraceRequestHttpHeadersFilter.java | 2 +- .../web/client/TraceWebAsyncClientAutoConfiguration.java | 2 +- .../instrument/web/client/TraceWebClientAutoConfiguration.java | 2 +- .../instrument/web/client/TraceWebClientBeanPostProcessor.java | 2 +- .../web/client/feign/FeignContextBeanPostProcessor.java | 2 +- .../cloud/sleuth/instrument/web/client/feign/LazyClient.java | 2 +- .../instrument/web/client/feign/LazyTracingFeignClient.java | 2 +- .../cloud/sleuth/instrument/web/client/feign/NeverRetry.java | 2 +- .../web/client/feign/OkHttpFeignClientBeanPostProcessor.java | 2 +- .../sleuth/instrument/web/client/feign/SleuthFeignBuilder.java | 2 +- .../instrument/web/client/feign/SleuthFeignProperties.java | 2 +- .../instrument/web/client/feign/SleuthHystrixFeignBuilder.java | 2 +- .../sleuth/instrument/web/client/feign/TraceFeignAspect.java | 2 +- .../web/client/feign/TraceFeignBlockingLoadBalancerClient.java | 2 +- .../web/client/feign/TraceFeignClientAutoConfiguration.java | 2 +- .../sleuth/instrument/web/client/feign/TraceFeignContext.java | 2 +- .../web/client/feign/TraceLoadBalancerFeignClient.java | 2 +- .../cloud/sleuth/instrument/zuul/TracePostZuulFilter.java | 2 +- .../sleuth/instrument/zuul/TraceZuulAutoConfiguration.java | 2 +- .../zuul/TraceZuulHandlerMappingBeanPostProcessor.java | 2 +- .../org/springframework/cloud/sleuth/internal/ContextUtil.java | 2 +- .../org/springframework/cloud/sleuth/internal/LazyBean.java | 2 +- .../cloud/sleuth/internal/SleuthContextListener.java | 2 +- .../cloud/sleuth/log/SleuthLogAutoConfiguration.java | 2 +- .../springframework/cloud/sleuth/log/SleuthSlf4jProperties.java | 2 +- .../cloud/sleuth/log/Slf4jCurrentTraceContext.java | 2 +- .../springframework/cloud/sleuth/log/Slf4jScopeDecorator.java | 2 +- .../propagation/SleuthTagPropagationAutoConfiguration.java | 2 +- .../sleuth/propagation/SleuthTagPropagationProperties.java | 2 +- .../sleuth/propagation/TagPropagationFinishedSpanHandler.java | 2 +- .../cloud/sleuth/sampler/ProbabilityBasedSampler.java | 2 +- .../cloud/sleuth/sampler/RateLimitingSampler.java | 2 +- .../cloud/sleuth/sampler/SamplerAutoConfiguration.java | 2 +- .../springframework/cloud/sleuth/sampler/SamplerCondition.java | 2 +- .../springframework/cloud/sleuth/sampler/SamplerProperties.java | 2 +- .../cloud/sleuth/util/ArrayListSpanReporter.java | 2 +- .../org/springframework/cloud/sleuth/util/SpanNameUtil.java | 2 +- .../jms/config/TracingJmsListenerEndpointRegistry.java | 2 +- .../java/org/springframework/cloud/sleuth/DisableSecurity.java | 2 +- .../springframework/cloud/sleuth/DisableWebFluxSecurity.java | 2 +- .../cloud/sleuth/PermitAllServletConfiguration.java | 2 +- .../cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java | 2 +- .../cloud/sleuth/SleuthTestAutoConfiguration.java | 2 +- .../org/springframework/cloud/sleuth/SpanAdjusterTests.java | 2 +- .../java/org/springframework/cloud/sleuth/SpanHandlerTests.java | 2 +- .../cloud/sleuth/annotation/NoOpTagValueResolverTests.java | 2 +- .../sleuth/annotation/NullSpanTagAnnotationHandlerTests.java | 2 +- .../annotation/SleuthNewSpanParserAnnotationDisableTests.java | 2 +- .../annotation/SleuthNewSpanParserAnnotationNoSleuthTests.java | 2 +- .../sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java | 2 +- .../sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java | 2 +- .../sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java | 2 +- .../cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java | 2 +- .../annotation/SleuthSpanCreatorCircularDependencyTests.java | 2 +- .../cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java | 2 +- .../sleuth/annotation/SpelTagValueExpressionResolverTests.java | 2 +- .../autoconfig/TraceAutoConfigurationCustomizersTests.java | 2 +- .../TraceAutoConfigurationPropagationCustomizationTests.java | 2 +- .../cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java | 2 +- .../TraceAutoConfigurationWithDisabledSleuthTests.java | 2 +- .../cloud/sleuth/autoconfig/TraceBaggageConfigurationTests.java | 2 +- .../cloud/sleuth/documentation/SpringCloudSleuthDocTests.java | 2 +- .../cloud/sleuth/instrument/DefaultTestAutoConfiguration.java | 2 +- .../instrument/async/AsyncCustomAutoConfigurationTest.java | 2 +- .../cloud/sleuth/instrument/async/AsyncDisabledTests.java | 2 +- .../sleuth/instrument/async/ExecutorBeanPostProcessorTests.java | 2 +- .../sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java | 2 +- .../async/LazyTraceScheduledThreadPoolExecutorTests.java | 2 +- .../instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java | 2 +- .../cloud/sleuth/instrument/async/TraceAsyncAspectTest.java | 2 +- .../instrument/async/TraceAsyncListenableTaskExecutorTest.java | 2 +- .../cloud/sleuth/instrument/async/TraceCallableTests.java | 2 +- .../cloud/sleuth/instrument/async/TraceRunnableTests.java | 2 +- .../sleuth/instrument/async/TraceableExecutorServiceTests.java | 2 +- .../instrument/async/TraceableScheduledExecutorServiceTest.java | 2 +- .../circuitbreaker/CircuitBreakerIntegrationTests.java | 2 +- .../sleuth/instrument/circuitbreaker/CircuitBreakerTests.java | 2 +- .../hystrix/SleuthHystrixConcurrencyStrategyTest.java | 2 +- .../cloud/sleuth/instrument/hystrix/TraceCommandTests.java | 2 +- .../messaging/ITTracingMethodMessageHandlerAdapterTests.java | 2 +- .../instrument/messaging/MessageHeaderPropagationTest.java | 2 +- .../messaging/MessageHeaderPropagation_NativeTest.java | 2 +- .../sleuth/instrument/messaging/PropagationSetterTest.java | 2 +- .../SleuthKafkaStreamsConfigurationIntegrationTests.java | 2 +- .../instrument/messaging/SqsQueueMessageHandlerTests.java | 2 +- .../TraceMessagingAutoConfigurationIntegrationTests.java | 2 +- .../instrument/messaging/TracingChannelInterceptorTest.java | 2 +- .../cloud/sleuth/instrument/multiple/DemoApplication.java | 2 +- .../instrument/multiple/MultipleHopsIntegrationTests.java | 2 +- .../cloud/sleuth/instrument/opentracing/OpenTracingTest.java | 2 +- .../instrument/quartz/TraceQuartzAutoConfigurationTest.java | 2 +- .../cloud/sleuth/instrument/quartz/TracingJobListenerTest.java | 2 +- .../TraceReactorAutoConfigurationAccessorConfiguration.java | 2 +- .../rpc/TraceRpcAutoConfigurationIntegrationTests.java | 2 +- .../sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java | 2 +- .../scheduling/TraceSchedulingAutoConfigurationTest.java | 2 +- .../cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java | 2 +- .../instrument/web/EndpointWithCyclicDependenciesTests.java | 2 +- .../web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java | 2 +- ...kipEndPointsIntegrationTestsWithContextPathWithBasePath.java | 2 +- ...EndPointsIntegrationTestsWithContextPathWithoutBasePath.java | 2 +- ...EndPointsIntegrationTestsWithoutContextPathWithBasePath.java | 2 +- ...PointsIntegrationTestsWithoutContextPathWithoutBasePath.java | 2 +- .../sleuth/instrument/web/SkipPatternProviderConfigTest.java | 2 +- .../cloud/sleuth/instrument/web/SkipPatternSamplerTests.java | 2 +- .../sleuth/instrument/web/SleuthHttpClientParserTests.java | 2 +- .../sleuth/instrument/web/SleuthHttpServerParserTests.java | 2 +- .../sleuth/instrument/web/TraceHttpAutoConfigurationTests.java | 2 +- .../cloud/sleuth/instrument/web/TraceNoWebEnvironmentTests.java | 2 +- .../instrument/web/TraceRestTemplateInterceptorTests.java | 2 +- .../sleuth/instrument/web/TraceWebClientDisabledTests.java | 2 +- .../cloud/sleuth/instrument/web/client/GH846Tests.java | 2 +- .../instrument/web/client/HttpClientBeanPostProcessorTest.java | 2 +- .../client/LazyTracingClientHttpRequestInterceptorTests.java | 2 +- .../instrument/web/client/MultipleAsyncRestTemplateTests.java | 2 +- .../web/client/ReactorNettyHttpClientSpringBootTests.java | 2 +- .../TraceExchangeFilterFunctionHttpClientResponseTests.java | 2 +- .../web/client/TraceRequestHttpHeadersFilterTests.java | 2 +- .../web/client/TraceResponseHttpHeadersFilterTests.java | 2 +- .../client/TraceRestTemplateInterceptorIntegrationTests.java | 2 +- .../web/client/TraceWebClientAutoConfigurationTests.java | 2 +- .../web/client/TraceWebClientBeanPostProcessorTest.java | 2 +- .../discoveryexception/WebClientDiscoveryExceptionTests.java | 2 +- .../web/client/exception/WebClientExceptionTests.java | 2 +- .../sleuth/instrument/web/client/feign/FeignRetriesTests.java | 2 +- .../instrument/web/client/feign/TraceFeignAspectTests.java | 2 +- .../instrument/web/client/feign/TracingFeignClientTests.java | 2 +- .../web/client/feign/TracingFeignObjectWrapperTests.java | 2 +- .../instrument/web/client/integration/WebClientTests.java | 2 +- .../cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java | 2 +- .../springframework/cloud/sleuth/internal/LazyBeanTests.java | 2 +- .../cloud/sleuth/internal/SleuthContextListenerAccessor.java | 2 +- .../springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java | 2 +- .../propagation/SleuthTagPropagationAutoConfigurationTests.java | 2 +- .../propagation/TagPropagationFinishedSpanHandlerTest.java | 2 +- .../cloud/sleuth/sampler/ProbabilityBasedSamplerTests.java | 2 +- .../cloud/sleuth/sampler/SamplerAutoConfigurationTests.java | 2 +- .../springframework/cloud/sleuth/util/SpanNameUtilTests.java | 2 +- .../java/org/springframework/cloud/sleuth/util/SpanUtil.java | 2 +- .../src/main/java/sample/SampleController.java | 2 +- .../src/main/java/sample/SampleFeignApplication.java | 2 +- .../src/test/java/sample/SampleFeignApplicationTests.java | 2 +- .../src/main/java/sample/SampleBackground.java | 2 +- .../src/main/java/sample/SampleMessagingApplication.java | 2 +- .../src/main/java/sample/SampleRequestResponse.java | 2 +- .../src/main/java/sample/SampleService.java | 2 +- .../src/main/java/sample/SampleSink.java | 2 +- .../src/main/java/sample/SampleTransformer.java | 2 +- .../test/java/integration/IntegrationTestZipkinSpanHandler.java | 2 +- .../src/test/java/integration/MessagingApplicationTests.java | 2 +- .../src/test/java/sample/SampleMessagingApplicationTests.java | 2 +- .../src/main/java/sample/SampleController.java | 2 +- .../src/main/java/sample/SampleRibbonApplication.java | 2 +- .../src/test/java/sample/SampleRibbonApplicationTests.java | 2 +- .../src/main/java/tools/AbstractIntegrationTest.java | 2 +- .../src/main/java/tools/AssertingRestTemplate.java | 2 +- .../src/main/java/tools/RequestSendingRunnable.java | 2 +- .../src/main/java/tools/SpanUtil.java | 2 +- .../src/main/java/sample/GreetingController.java | 2 +- .../src/main/java/sample/SampleWebsocketApplication.java | 2 +- .../src/test/java/sample/SampleWebsocketApplicationTests.java | 2 +- .../src/main/java/sample/SampleBackground.java | 2 +- .../src/main/java/sample/SampleController.java | 2 +- .../src/main/java/sample/SampleZipkinApplication.java | 2 +- .../src/test/java/integration/ZipkinTests.java | 2 +- .../src/test/java/sample/SampleSleuthApplicationTests.java | 2 +- .../src/main/java/sample/SampleBackground.java | 2 +- .../src/main/java/sample/SampleController.java | 2 +- .../src/main/java/sample/SampleSleuthApplication.java | 2 +- .../src/test/java/sample/SampleSleuthApplicationTests.java | 2 +- .../cloud/sleuth/zipkin2/DefaultEndpointLocator.java | 2 +- .../sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java | 2 +- .../springframework/cloud/sleuth/zipkin2/EndpointLocator.java | 2 +- .../cloud/sleuth/zipkin2/ZipkinAutoConfiguration.java | 2 +- .../zipkin2/ZipkinBackwardsCompatibilityAutoConfiguration.java | 2 +- .../cloud/sleuth/zipkin2/ZipkinLoadBalancer.java | 2 +- .../springframework/cloud/sleuth/zipkin2/ZipkinProperties.java | 2 +- .../cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java | 2 +- .../zipkin2/sender/LoadBalancerClientZipkinLoadBalancer.java | 2 +- .../cloud/sleuth/zipkin2/sender/RestTemplateSender.java | 2 +- .../zipkin2/sender/ZipkinActiveMqSenderConfiguration.java | 2 +- .../sleuth/zipkin2/sender/ZipkinKafkaSenderConfiguration.java | 2 +- .../sleuth/zipkin2/sender/ZipkinRabbitSenderConfiguration.java | 2 +- .../zipkin2/sender/ZipkinRestTemplateSenderConfiguration.java | 2 +- .../cloud/sleuth/zipkin2/sender/ZipkinSenderCondition.java | 2 +- .../zipkin2/sender/ZipkinSenderConfigurationImportSelector.java | 2 +- .../cloud/sleuth/zipkin2/sender/ZipkinSenderProperties.java | 2 +- .../sleuth/zipkin2/DefaultEndpointLocatorConfigurationTest.java | 2 +- .../cloud/sleuth/zipkin2/ZipkinAutoConfigurationTests.java | 2 +- .../ZipkinBackwardsCompatibilityAutoConfigurationTests.java | 2 +- .../cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java | 2 +- .../cloud/sleuth/zipkin2/ZipkinWithDisabledSleuthTests.java | 2 +- .../cloud/sleuth/zipkin2/sender/RestTemplateSenderTest.java | 2 +- .../sender/ZipkinRestTemplateSenderConfigurationTest.java | 2 +- tests/pom.xml | 2 +- tests/spring-cloud-sleuth-instrumentation-async-tests/pom.xml | 2 +- .../sleuth/instrument/async/DefaultTestAutoConfiguration.java | 2 +- .../sleuth/instrument/async/TraceAsyncIntegrationTests.java | 2 +- .../sleuth/instrument/async/issues/issue1212/GH1212Tests.java | 2 +- .../sleuth/instrument/async/issues/issue410/Issue410Tests.java | 2 +- .../sleuth/instrument/async/issues/issue546/Issue546Tests.java | 2 +- tests/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml | 2 +- .../issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java | 2 +- .../ManuallyCreatedDelegateLoadBalancerFeignClientTests.java | 2 +- .../sleuth/instrument/feign/issues/issue307/Issue307Tests.java | 2 +- .../sleuth/instrument/feign/issues/issue350/Issue350Tests.java | 2 +- .../sleuth/instrument/feign/issues/issue362/Issue362Tests.java | 2 +- .../sleuth/instrument/feign/issues/issue393/Issue393Tests.java | 2 +- .../sleuth/instrument/feign/issues/issue502/Issue502Tests.java | 2 +- tests/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml | 2 +- .../sleuth/instrument/grpc/GrpcTracingIntegrationTests.java | 2 +- .../cloud/sleuth/instrument/grpc/stubs/HelloReply.java | 2 +- .../cloud/sleuth/instrument/grpc/stubs/HelloReplyOrBuilder.java | 2 +- .../cloud/sleuth/instrument/grpc/stubs/HelloRequest.java | 2 +- .../sleuth/instrument/grpc/stubs/HelloRequestOrBuilder.java | 2 +- .../cloud/sleuth/instrument/grpc/stubs/HelloServiceGrpc.java | 2 +- .../sleuth/instrument/grpc/stubs/HelloServiceOuterClass.java | 2 +- tests/spring-cloud-sleuth-instrumentation-hystrix-tests/pom.xml | 2 +- .../sleuth/instrument/hystrix/DefaultTestAutoConfiguration.java | 2 +- .../instrument/hystrix/HystrixAnnotationsIntegrationTests.java | 2 +- tests/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml | 2 +- .../instrument/redis/TraceRedisAutoConfigurationTests.java | 2 +- .../spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml | 2 +- .../instrument/messaging/ITTracingChannelInterceptorTests.java | 2 +- .../instrument/messaging/JmsTracingConfigurationTest.java | 2 +- .../messaging/SleuthKafkaStreamsConfigurationTest.java | 2 +- .../TraceContextPropagationChannelInterceptorTests.java | 2 +- .../messaging/TraceMessagingAutoConfiguration1664Tests.java | 2 +- .../messaging/TraceMessagingAutoConfigurationTests.java | 2 +- .../messaging/TraceStreamChannelInterceptorTests.java | 2 +- .../messaging/issues/issue_943/CustomExecutorConfig.java | 2 +- .../messaging/issues/issue_943/HelloSpringIntegration.java | 2 +- .../instrument/messaging/issues/issue_943/HelloWorldImpl.java | 2 +- .../messaging/issues/issue_943/HelloWorldRestController.java | 2 +- .../instrument/messaging/issues/issue_943/Issue943Tests.java | 2 +- .../instrument/messaging/issues/issue_943/MessagingGateway.java | 2 +- .../websocket/TraceWebSocketAutoConfigurationTests.java | 2 +- .../springframework/cloud/sleuth/instrument/util/SpanUtil.java | 2 +- tests/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml | 2 +- .../cloud/sleuth/instrument/web/AbstractMvcIntegrationTest.java | 2 +- .../cloud/sleuth/instrument/web/TraceAsyncIntegrationTests.java | 2 +- .../instrument/web/TraceCustomFilterResponseInjectorTests.java | 2 +- .../sleuth/instrument/web/TraceFilterIntegrationTests.java | 2 +- .../web/TraceFilterWebIntegrationMultipleFiltersTests.java | 2 +- .../sleuth/instrument/web/TraceFilterWebIntegrationTests.java | 2 +- .../cloud/sleuth/instrument/web/TraceWebDisabledTests.java | 2 +- .../instrument/web/TraceWebServletAutoConfigurationTests.java | 2 +- .../web/client/RestTemplateTraceAspectIntegrationTests.java | 2 +- .../web/client/TraceWebAsyncClientAutoConfigurationTests.java | 2 +- .../instrument/web/client/exceptionresolver/Issue585Tests.java | 2 +- .../cloud/sleuth/instrument/web/view/Issue469.java | 2 +- .../cloud/sleuth/instrument/web/view/Issue469Tests.java | 2 +- .../java/org/springframework/cloud/sleuth/util/SpanUtil.java | 2 +- tests/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml | 2 +- .../cloud/sleuth/instrument/reactor/Issue866Configuration.java | 2 +- .../reactor/ScopePassingSpanSubscriberSpringBootTests.java | 2 +- .../instrument/reactor/ScopePassingSpanSubscriberTests.java | 2 +- .../TraceReactorAutoConfigurationAccessorConfiguration.java | 2 +- .../cloud/sleuth/instrument/reactor/sample/FlatMapTests.java | 2 +- .../cloud/sleuth/instrument/reactor/sample/RequestSender.java | 2 +- .../instrument/web/client/ITSpringConfiguredReactorClient.java | 2 +- .../instrument/web/client/ReactorNettyHttpClientBraveTests.java | 2 +- .../cloud/sleuth/instrument/web/client/WebClientBraveTests.java | 2 +- tests/spring-cloud-sleuth-instrumentation-rpc-tests/pom.xml | 2 +- .../rpc/TraceRpcAutoConfigurationIntegrationTests.java | 2 +- tests/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml | 2 +- .../instrument/rxjava/SleuthRxJavaSchedulersHookTests.java | 2 +- .../cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java | 2 +- .../pom.xml | 2 +- .../sleuth/instrument/scheduling/TracingOnScheduledTests.java | 2 +- tests/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml | 2 +- .../cloud/sleuth/instrument/web/GH1102Tests.java | 2 +- .../cloud/sleuth/instrument/web/TraceWebFluxTests.java | 2 +- .../java/org/springframework/cloud/sleuth/util/SpanUtil.java | 2 +- tests/spring-cloud-sleuth-instrumentation-zuul-tests/pom.xml | 2 +- .../cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java | 2 +- .../sleuth/instrument/zuul/issues/issue634/Issue634Tests.java | 2 +- 403 files changed, 403 insertions(+), 403 deletions(-) diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java index bad8a8d5a..8167ede4a 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java index 7a57bfc13..26899d5d4 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/ProcessLauncherState.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java index 75fa5373b..348c8ff61 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/TracerImplementation.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java index 63a6adc65..b57c195cd 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/StartupBenchmarkTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/DefaultSpanNamer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/DefaultSpanNamer.java index b61edd523..2601827df 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/DefaultSpanNamer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/DefaultSpanNamer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/LocalServiceName.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/LocalServiceName.java index 26c16148e..9c4e6724f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/LocalServiceName.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/LocalServiceName.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanAdjuster.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanAdjuster.java index 5ff8914a9..6d04605a5 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanAdjuster.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanAdjuster.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanName.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanName.java index 67ea81708..44b17e55d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanName.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanName.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java index 01f438c8d..f0cee8e44 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/AbstractSleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/AbstractSleuthMethodInvocationProcessor.java index d2bac1447..19e254d89 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/AbstractSleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/AbstractSleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java index 903d0dfa9..f9f625fc0 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/DefaultSpanCreator.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/DefaultSpanCreator.java index e3388aeee..d757bec3b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/DefaultSpanCreator.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/DefaultSpanCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java index 18acb6cc0..28d9114aa 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java index 97a51c761..1f7b98538 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java index bb9354446..5eb29e09e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NonReactorSleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NonReactorSleuthMethodInvocationProcessor.java index 6a137f58a..bfdb6f4b7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NonReactorSleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/NonReactorSleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ReactorSleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ReactorSleuthMethodInvocationProcessor.java index ebff3d4f0..4f2f8523d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ReactorSleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/ReactorSleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java index bde8b6dca..d39ce6ce6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotatedParameter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotatedParameter.java index 61e45e3e3..6cd7ffabe 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotatedParameter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotatedParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java index 61503133b..a5b8926cd 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationProperties.java index 7c4313ac2..8697c7972 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationUtils.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationUtils.java index e13dffc0b..32a351f4c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationUtils.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java index ca3fb190e..d84080ea7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java index d17858de7..a7739e4af 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandler.java index c7b48b36e..23b27107d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolver.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolver.java index 6c79155d8..cf7929ad3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolver.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java index 0a97f3c55..662eeeeff 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java index 18913f07a..8fde99e03 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java index 81a44c4da..f3323eaf0 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthProperties.java index 1b7543744..e9a5f2ebb 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java index ef4393918..f48248c00 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.java index 5755391bc..9d1a0dc1b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java index 6d053d621..48fbbbe7e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncAutoConfiguration.java index fc26848b7..661881e6f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfiguration.java index 70aec549a..a1288f210 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java index cfee8fd8e..ba7b92d7b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java index 51dbb9b42..c37638623 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java index 2e39af032..883f3c7c8 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java index 5d5c97049..106f8b5ca 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java index 18178e109..af26f95ff 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java index 9a086d879..2f2ef7800 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java index d03c0482f..9f3804892 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthAsyncProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthAsyncProperties.java index cfbeeb8a6..c399e42fc 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthAsyncProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthAsyncProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java index e173d6762..d0218fd47 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java index ff43a26a3..91ea9a664 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java index 054d643cb..b239fd7d4 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceCallable.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java index 33c943eff..c02751cc6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java index a2bce14cd..63bb82455 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorService.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java index 71b83d0db..e079ba2f3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorService.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerAutoConfiguration.java index 334cc01ec..1a864960e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java index ef279a7da..63ae43195 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java index cc102fea0..4627df17c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java index 79cccd07c..b97d1198d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java index 476b38d1a..f21a38e87 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcManagedChannelBuilderCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java index 749b3a444..6fb78c2a2 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java index 1d0d7aea3..e0d7a09ee 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TracingManagedChannelBuilderCustomizer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TracingManagedChannelBuilderCustomizer.java index 7a95f6522..09898ba37 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TracingManagedChannelBuilderCustomizer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TracingManagedChannelBuilderCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixAutoConfiguration.java index a55aac310..5670afe88 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java index 401719560..c4e69b635 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyProperties.java index f9b58b63c..973f6fe72 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java index 1b6e884c8..bb91d9618 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ConsumerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ConsumerSampler.java index bebabc715..ff7d4dea0 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ConsumerSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ConsumerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java index 3706153a7..1af98f4ad 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/DefaultMessageSpanCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation.java index 4d0fffa9c..541d55b8b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java index 881e592ed..315910f6d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageSpanCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/OnMessagingEnabled.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/OnMessagingEnabled.java index 66f9a4e1d..c1eab588c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/OnMessagingEnabled.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/OnMessagingEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ProducerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ProducerSampler.java index c289f1acf..047fae204 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ProducerSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/ProducerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfiguration.java index a0b1654d4..0b8f2fe2e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthMessagingProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthMessagingProperties.java index 2c212a704..0d6c3d889 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthMessagingProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthMessagingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHeaders.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHeaders.java index 0b15e4f3d..864f4f507 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHeaders.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHeaders.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java index 04d6a5596..0d562ce97 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java index 1db858eb9..32c76fa1c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringMessagingAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringMessagingAutoConfiguration.java index 122111cf6..c5fd28417 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringMessagingAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringMessagingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java index 4209809f2..bff3b0da2 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingConnectionFactoryBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingMethodMessageHandlerAdapter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingMethodMessageHandlerAdapter.java index ebdee8e65..6d8e78739 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingMethodMessageHandlerAdapter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingMethodMessageHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/websocket/TraceWebSocketAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/websocket/TraceWebSocketAutoConfiguration.java index 592361788..7303773b4 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/websocket/TraceWebSocketAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/websocket/TraceWebSocketAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/OpentracingAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/OpentracingAutoConfiguration.java index 6441b835c..2ac5e0f34 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/OpentracingAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/OpentracingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/SleuthOpentracingProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/SleuthOpentracingProperties.java index 6f6fb25f8..5aa31d13f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/SleuthOpentracingProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/opentracing/SleuthOpentracingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfiguration.java index 630041ac8..19598c8a9 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java index dfc028adf..bb33dbe07 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java index 690685c4b..2367f3b87 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. 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 a1b587052..05f4a4190 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 @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java index 4a7315164..c402afda3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SleuthReactorProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriber.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriber.java index b5d0014d9..fafd2184d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriber.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscriber.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java index 8295ebb8b..0d32cb5e7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/SpanSubscription.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java index 1a6ee4252..9fba5d5d2 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisAutoConfiguration.java index a254e88b6..d219a7ce8 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisProperties.java index 10f2cc8dc..81b6363d0 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/redis/TraceRedisProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcClientSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcClientSampler.java index 689eef752..a85e01397 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcClientSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcClientSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcServerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcServerSampler.java index 195116410..8734ae5e9 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcServerSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcServerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java index ab0c623bc..fbdf8bc3c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/RxJavaAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/RxJavaAutoConfiguration.java index 1dce36d67..39e77bc94 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/RxJavaAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/RxJavaAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java index d4bfd3840..12bdf5abf 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHook.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersProperties.java index 6cef41d96..b48700edb 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/SleuthSchedulingProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/SleuthSchedulingProperties.java index 55c17254d..15dee8715 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/SleuthSchedulingProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/SleuthSchedulingProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java index a9bf2956a..ac5dde737 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java index 94a6f1a26..5eb9bc024 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java index 21bb50cd5..194f3753c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ExceptionLoggingFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ExceptionLoggingFilter.java index a18a476df..6a574bcee 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ExceptionLoggingFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ExceptionLoggingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java index f79639f58..301184da6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientRequestParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java index a5ecc499c..e151377f9 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientResponseParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java index fbf748196..724969006 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java index 7ae20954f..f90396ab7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerRequestParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java index 1e19082cd..2d8b62d9a 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerResponseParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java index a725de02d..9b04bf841 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java index fccf26a3b..120fd0866 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServletUtils.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServletUtils.java index fe419178d..a4bab96d4 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServletUtils.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServletUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SingleSkipPattern.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SingleSkipPattern.java index c367c6b05..c8b913f98 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SingleSkipPattern.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SingleSkipPattern.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java index 9cf5a84b1..478849381 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSampler.java index 6e678b28b..c9ec5c0b5 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java index 7b894c34e..0ea5928a3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpLegacyProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpLegacyProperties.java index 7c87def61..5776efdf6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpLegacyProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpLegacyProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpProperties.java index a52ef9def..201ccf016 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParser.java index 6f9f5b276..68cd7b4a5 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParser.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java index c9d777dc9..e5c8830fd 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java index 597548afe..dccefd523 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerFunctionAdapterBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java index f780254e3..f52fd5b58 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceKeys.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceKeys.java index e4477b986..542d3b0e5 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceKeys.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceKeys.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java index c07c3285a..b7f5344ef 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java index 32fa512f6..e394a05b0 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java index cdcee9f52..afd67b885 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java index 371a136ae..7b727e8f3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebMvcConfigurer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebMvcConfigurer.java index dff8d7b0e..20cc9b185 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebMvcConfigurer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebMvcConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java index b919a5398..b38bc5196 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java index 83bbcf3dc..6d105749c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/SleuthWebClientEnabled.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/SleuthWebClientEnabled.java index 40c52b0fe..43f60f8b6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/SleuthWebClientEnabled.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/SleuthWebClientEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java index 5bb4c487d..1ffda1779 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java index 8d16fc7b7..24c1ac186 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java index c7971222c..5f8e03fcf 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java index ce95437d0..e69b48afe 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java index efe5137e4..f64dc8d5f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java index e90a938b7..31323cc3b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java index 3c19164a7..fd66b9a6f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyTracingFeignClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/NeverRetry.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/NeverRetry.java index cdc3fb913..74fa1e3a4 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/NeverRetry.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/NeverRetry.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java index be66b14ea..7b5b8427d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java index 8c8658296..48bb85a1e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignProperties.java index e0c13905e..631e85fd3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java index bfee5ff25..4513bf6c5 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java index 42cfb191d..c240af84d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java index 1a7637636..538eede94 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBlockingLoadBalancerClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java index 38e34e24e..de96bf213 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java index f30569562..d46aac456 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceLoadBalancerFeignClient.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceLoadBalancerFeignClient.java index 6e4091357..25d92a566 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceLoadBalancerFeignClient.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceLoadBalancerFeignClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java index 0bd4e30e2..e52d20ed2 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java index 98dafacbc..0649f0a08 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulHandlerMappingBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulHandlerMappingBeanPostProcessor.java index 90c02b9e1..254fc4038 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulHandlerMappingBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulHandlerMappingBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java index 944dd2d26..288c94d89 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/ContextUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java index 8a55e0b31..4493c17e8 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/LazyBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java index 2c689d31f..8db51333d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java index 9f91b4248..2b3a8e203 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java index 62a5a7824..29abbf4dc 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jCurrentTraceContext.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jCurrentTraceContext.java index 67c3a5cb7..5120ad945 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jCurrentTraceContext.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jCurrentTraceContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java index b8fe354a8..f64195d35 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java index 342c9e4b1..b0b9635dd 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationProperties.java index 24e586788..6bb64fa13 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java index 80b7ebeb7..f24708174 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSampler.java index 5603327e6..b2db8eb6e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/RateLimitingSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/RateLimitingSampler.java index 03b0b61f4..bf8c8dc00 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/RateLimitingSampler.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/RateLimitingSampler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfiguration.java index 473fbdd5e..434b02945 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerCondition.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerCondition.java index 5c50c3113..0833bdb23 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerCondition.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerProperties.java index 9dd6f8ebb..15f072403 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/sampler/SamplerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanReporter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanReporter.java index 14eccc356..2e606b023 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanReporter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanReporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/SpanNameUtil.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/SpanNameUtil.java index 42cc78148..b5b933664 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/SpanNameUtil.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/SpanNameUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java index c0088eaf0..61debd44c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/jms/config/TracingJmsListenerEndpointRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java index 39debd665..77de3d315 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java index 88f8b8848..da65f6cf4 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DisableWebFluxSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java index c5a34c782..99f458c88 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllServletConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java index 009f166a0..0925934e0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/PermitAllWebFluxSecurityConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java index b03423b67..234d814cc 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SleuthTestAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanAdjusterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanAdjusterTests.java index 9cce9ca84..2db17efd0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanAdjusterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanAdjusterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java index 51ecaeece..06386f94b 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java index dabc1a2ea..34a3c6a1d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NullSpanTagAnnotationHandlerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NullSpanTagAnnotationHandlerTests.java index 7245cdf41..57e3482b9 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NullSpanTagAnnotationHandlerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/NullSpanTagAnnotationHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationDisableTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationDisableTests.java index 907fdc79a..efc2730cb 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationDisableTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationDisableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationNoSleuthTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationNoSleuthTests.java index c084e5fb9..3ce31547e 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationNoSleuthTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthNewSpanParserAnnotationNoSleuthTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java index 93d61b35f..43b3c720e 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java index a1212cda0..55b039f45 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java index d14f3bb10..4481032f7 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java index 46884b39d..923142b08 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java index 13a0aef01..eb3900e76 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java index 626052dac..a936366e5 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java index d982d66f8..264ed6870 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SpelTagValueExpressionResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java index 252b23b5c..e3ca3e628 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java index a0e8ae7eb..3f53041c7 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java index 943104edd..d02fe470e 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationWithDisabledSleuthTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationWithDisabledSleuthTests.java index 3ea7068c7..1f185affc 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationWithDisabledSleuthTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationWithDisabledSleuthTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfigurationTests.java index 0821fbd14..3036b5efd 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceBaggageConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java index 3c3550123..dbf297b17 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/DefaultTestAutoConfiguration.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/DefaultTestAutoConfiguration.java index dff0a365d..7e9158fb5 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/DefaultTestAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/DefaultTestAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfigurationTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfigurationTest.java index 821523e92..df57070d1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfigurationTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncCustomAutoConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java index 60e354228..96467c556 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/AsyncDisabledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java index 8f856aa71..d4f019bfd 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java index 167a74acd..029391daf 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceAsyncCustomizerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java index a5cf2e9ef..aeb8c7b41 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java index e1de3430e..e844302b8 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java index 555895a63..ea562439c 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java index 18a2738df..2bfa9cef1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncListenableTaskExecutorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java index c68990358..9b6970603 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java index 510ddccd4..df86ee81d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java index 482e783c7..9c8a30843 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java index 409b923de..8bba9a115 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableScheduledExecutorServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java index 197e9b206..7740d88df 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java index abaf34f4f..de8e119fa 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyTest.java index 86f26bc57..b8e585ed8 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategyTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java index 0558841b9..308a9ad12 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingMethodMessageHandlerAdapterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingMethodMessageHandlerAdapterTests.java index 42b7e54d3..24ce4ee6d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingMethodMessageHandlerAdapterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingMethodMessageHandlerAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagationTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagationTest.java index 1d06a66ae..ff53949f4 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagationTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation_NativeTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation_NativeTest.java index 280c7b235..3e351bd38 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation_NativeTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagation_NativeTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/PropagationSetterTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/PropagationSetterTest.java index 0327af34a..de12061c4 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/PropagationSetterTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/PropagationSetterTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfigurationIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfigurationIntegrationTests.java index 5aba918e5..33226c2c4 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SleuthKafkaStreamsConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SqsQueueMessageHandlerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SqsQueueMessageHandlerTests.java index beff3653d..786687598 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SqsQueueMessageHandlerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/SqsQueueMessageHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java index c4c5e57ae..39ad1aef7 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index 54a3b4e8e..a4b4090b2 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java index dc565d5fe..e55048946 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java index 81ffb4f9e..365332bc1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/OpenTracingTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/OpenTracingTest.java index c311aa6c6..558cf5b69 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/OpenTracingTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/OpenTracingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfigurationTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfigurationTest.java index 4eedeea91..c1533e79f 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfigurationTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TraceQuartzAutoConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java index 3e9db23f6..946f9241d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java index ea7808e47..0781d2996 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/TraceReactorAutoConfigurationAccessorConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java index 5b05a2776..1a88c5c83 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java index ba71b65ae..365f122db 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java index f187ad4e6..2d5595d77 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java index 51ce2c4cf..7190b2343 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/EndpointWithCyclicDependenciesTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/EndpointWithCyclicDependenciesTests.java index a998461e6..b31c78446 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/EndpointWithCyclicDependenciesTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/EndpointWithCyclicDependenciesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java index 35583e4f6..b7bc1af10 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java index ea608574f..fd24ab1e9 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java index 883662e29..a3bc9fac0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java index 30db64cc6..c54db0b80 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java index 0c45cf0c4..086c27dfb 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java index 0e5ef3242..ee9f4b600 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSamplerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSamplerTests.java index 9661dc77c..03d3a7377 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSamplerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternSamplerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParserTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParserTests.java index fd952d184..53df78069 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParserTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpClientParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParserTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParserTests.java index 4f14f61bf..ca24ff9d1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParserTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpServerParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfigurationTests.java index 3c7b83f2b..41bc4fb49 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceNoWebEnvironmentTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceNoWebEnvironmentTests.java index 8369aa0b5..8f6c18ee8 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceNoWebEnvironmentTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceNoWebEnvironmentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java index 8d036af6b..43d1319ee 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebClientDisabledTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebClientDisabledTests.java index f9443f3f8..372c25093 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebClientDisabledTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebClientDisabledTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Tests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Tests.java index 94d8e8cca..4effd9d8a 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Tests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Tests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java index b7c7de7fb..e556a3b3f 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTracingClientHttpRequestInterceptorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTracingClientHttpRequestInterceptorTests.java index 4d4f56c56..5e39aa2e3 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTracingClientHttpRequestInterceptorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/LazyTracingClientHttpRequestInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java index 5eacf3b89..06a241a34 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java index f2f65af9b..b6148da99 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java index e615af73d..da6c01297 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunctionHttpClientResponseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java index 0233047fa..5fb6d43c0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java index 3f76c48af..a53409ba9 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java index 4d1c0594c..3da371cc5 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java index a8f81a8ed..6e6946732 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java index d99b7f6c2..b36a3a188 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java index e824c00e0..90ebc5acd 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java index ca7b4433c..acdf857b9 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java index 8ec2ebd45..5ea902256 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java index 9e1ff9e8b..6a0713e6a 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignAspectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java index 40d677203..1797f34dd 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java index 1705b77c1..5ea4e55da 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignObjectWrapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java index 52efcf6ca..9f7e468b5 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java index 34d75adcd..ce773dd1d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java index b985c848c..141bd12e1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/LazyBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java index f2ea51e55..6e825beca 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java index aa5c45f50..36b2c4034 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java index 3e4960146..cb376b649 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandlerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandlerTest.java index 626fdaeb9..5d170f4d5 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandlerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSamplerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSamplerTests.java index 46409ab52..2ca1ab852 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSamplerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/ProbabilityBasedSamplerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java index 12644e3c0..05cacbb46 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanNameUtilTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanNameUtilTests.java index 9b6c8b572..3762de8bc 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanNameUtilTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanNameUtilTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java index fad18d7a3..06213bbc1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java index fcd1a1d6c..38c0e905e 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java index 7b04adf26..6a7488296 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java index 03f981b46..76aba4ec5 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/test/java/sample/SampleFeignApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java index 1c013a17b..cb0a4d555 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleBackground.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java index 1d2387ba9..0bc0c1f03 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleMessagingApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java index 4800e9c5a..f7cad4401 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleRequestResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java index a4aafb245..3c076e995 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleService.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java index 32cac94ac..e1d4c9545 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleSink.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java index 457882514..b24f0928b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/java/sample/SampleTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java index a77301e60..cec201b80 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java index 1eaebaee0..1a89e76f9 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java index 9e5efb9fa..d535b443e 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/sample/SampleMessagingApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleController.java index b5258e452..4145d225b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleRibbonApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleRibbonApplication.java index 7a441c1ba..f4edef064 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleRibbonApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/java/sample/SampleRibbonApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/test/java/sample/SampleRibbonApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/test/java/sample/SampleRibbonApplicationTests.java index 8c70065ba..19a8e44ce 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/test/java/sample/SampleRibbonApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/test/java/sample/SampleRibbonApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java index 381b4121b..e3bdb4f7e 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AbstractIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java index 1e4bc4949..262e6cfea 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/AssertingRestTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java index eae741a9c..efb11233b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/RequestSendingRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java index 589c3cc7b..bb22afb88 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/src/main/java/tools/SpanUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java index b399b2f57..846177aef 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/GreetingController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java index 37f92fe0f..f6b7d2d76 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/main/java/sample/SampleWebsocketApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java index d6f582736..60bddfbb9 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/src/test/java/sample/SampleWebsocketApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java index 1c013a17b..cb0a4d555 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleBackground.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java index 81c0b9be5..31f8d1fe4 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java index 7aa16a024..6c53f564b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java index 6153c7447..eb3cec2f3 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java index 4d28c0570..54f11061b 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/sample/SampleSleuthApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java index 4881d5a15..fed6ff1ba 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleBackground.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java index 9f9b98272..3f999e564 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleController.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java index abf5991a4..999bb1176 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/java/sample/SampleSleuthApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java index d230dee88..abf932590 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/test/java/sample/SampleSleuthApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java index 67e92c78c..fb5d9acab 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java index f26d5f4fd..da5835fd0 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/DefaultZipkinRestTemplateCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java index 91c47633f..98be515d7 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/EndpointLocator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfiguration.java index 61a3fcfea..7922975cb 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfiguration.java index d4f6f6095..42674272b 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java index ef098dcd9..70d28f03e 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinLoadBalancer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java index 555da14ab..de1faccbe 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java index ae8cba211..389ee56f5 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/ZipkinRestTemplateCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/LoadBalancerClientZipkinLoadBalancer.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/LoadBalancerClientZipkinLoadBalancer.java index 49ee6aa29..d03aae581 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/LoadBalancerClientZipkinLoadBalancer.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/LoadBalancerClientZipkinLoadBalancer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSender.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSender.java index 982dcb0d9..73f7fd1ea 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSender.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSender.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinActiveMqSenderConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinActiveMqSenderConfiguration.java index 4f4426a17..98c07197a 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinActiveMqSenderConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinActiveMqSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinKafkaSenderConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinKafkaSenderConfiguration.java index 4cb4576d1..ff8c308ff 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinKafkaSenderConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinKafkaSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRabbitSenderConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRabbitSenderConfiguration.java index f30c627c5..3aaefcfc9 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRabbitSenderConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRabbitSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfiguration.java index c00f5a9ec..13bf4afc9 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderCondition.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderCondition.java index 5d7751975..b7a0760c5 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderCondition.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderConfigurationImportSelector.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderConfigurationImportSelector.java index 41857c00f..32cf5217a 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderConfigurationImportSelector.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderConfigurationImportSelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderProperties.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderProperties.java index fea8c5db3..96ae4bd6d 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderProperties.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinSenderProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocatorConfigurationTest.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocatorConfigurationTest.java index be59fc3b1..4102d3d40 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocatorConfigurationTest.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/DefaultEndpointLocatorConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfigurationTests.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfigurationTests.java index 3a68148a2..5c9220223 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfigurationTests.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfigurationTests.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfigurationTests.java index 33928e457..199fefc29 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfigurationTests.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinBackwardsCompatibilityAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java index edbe4558a..400886b94 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinDiscoveryClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinWithDisabledSleuthTests.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinWithDisabledSleuthTests.java index 981ca40bc..87aa9cffb 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinWithDisabledSleuthTests.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinWithDisabledSleuthTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSenderTest.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSenderTest.java index 63fb32211..7a0ae3cbe 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSenderTest.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/RestTemplateSenderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfigurationTest.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfigurationTest.java index 95c07cc6c..a4badf643 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfigurationTest.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/sender/ZipkinRestTemplateSenderConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2021 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. diff --git a/tests/pom.xml b/tests/pom.xml index 0c835dfb2..068bdbf03 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -1,6 +1,6 @@ diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java index eb2cf20fc..0f9d424b8 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java @@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer; @@ -41,6 +42,7 @@ import org.springframework.context.annotation.Configuration; * @since 3.0.0 */ @Configuration(proxyBeanMethods = false) +@ConditionalOnMissingClass("com.mongodb.reactivestreams.client.MongoClient") @ConditionalOnBean(Tracing.class) @AutoConfigureAfter(BraveAutoConfiguration.class) @AutoConfigureBefore(MongoAutoConfiguration.class) diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java new file mode 100644 index 000000000..120b69f49 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.brave.instrument.mongodb; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Chintan Radia + */ +class BraveMongoDbAutoConfigurationAsyncDriverTest { + + @Test + void should_not_auto_configure_brave_mongo_db() { + new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(BraveAutoConfiguration.class, BraveMongoDbAutoConfiguration.class)) + .run(context -> assertThat(context).doesNotHaveBean(BraveMongoDbAutoConfiguration.class)); + } + + @Test + void should_auto_configure_brave_mongo_db() { + new ApplicationContextRunner() + .withClassLoader(new FilteredClassLoader("com.mongodb.reactivestreams.client.MongoClient")) + .withConfiguration( + AutoConfigurations.of(BraveAutoConfiguration.class, BraveMongoDbAutoConfiguration.class)) + .run(context -> assertThat(context).hasSingleBean(BraveMongoDbAutoConfiguration.class)); + } + +} + From 8b4ef12c6e360f311e88740ec9e7e02388293bc1 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Tue, 9 Mar 2021 05:30:28 +0000 Subject: [PATCH 20/78] Bumping versions --- .../mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java index 120b69f49..7d9139d0a 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfigurationAsyncDriverTest.java @@ -48,4 +48,3 @@ class BraveMongoDbAutoConfigurationAsyncDriverTest { } } - From c8a3b1b6691085de6970ccb552a08945d755df21 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 8 Mar 2021 16:42:55 +0100 Subject: [PATCH 21/78] Updated the reactor instrumentation docs --- docs/src/main/asciidoc/integrations.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/main/asciidoc/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc index 6d7233d1b..b56360cb0 100644 --- a/docs/src/main/asciidoc/integrations.adoc +++ b/docs/src/main/asciidoc/integrations.adoc @@ -391,11 +391,11 @@ This feature is available for all tracer implementations. We have the following modes of instrumenting reactor based applications that can be set via `spring.sleuth.reactor.instrumentation-type` property: -* `ON_HOOKS` - With the new Reactor https://github.com/reactor/reactor-core/pull/2566[queue wrapping mechanism] (Reactor 3.4.3) we're instrumenting the way threads are switched by Reactor. This should lead to feature parity with `ON_EACH` with low performance impact. -* `ON_EACH` - wraps every Reactor operator in a trace representation. +* `DECORATE_QUEUES` - With the new Reactor https://github.com/reactor/reactor-core/pull/2566[queue wrapping mechanism] (Reactor 3.4.3) we're instrumenting the way threads are switched by Reactor. This should lead to feature parity with `ON_EACH` with low performance impact. +* `DECORATE_ON_EACH` - wraps every Reactor operator in a trace representation. Passes the tracing context in most cases. This mode might lead to drastic performance degradation. -* `ON_LAST` - wraps last Reactor operator in a trace representation. +* `DECORATE_ON_LAST` - wraps last Reactor operator in a trace representation. Passes the tracing context in some cases thus accessing MDC context might not work. This mode might lead to medium performance degradation. * `MANUAL` - wraps every Reactor in the least invasive way without passing of tracing context. From a9f8efed73a98cf7258fb1c6dcbd6f31bca83821 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 9 Mar 2021 08:42:47 +0100 Subject: [PATCH 22/78] Added missing project versions --- .../pom.xml | 1 + .../pom.xml | 30 ------------------- .../pom.xml | 1 + .../spring-cloud-sleuth-sample-zipkin/pom.xml | 1 + 4 files changed, 3 insertions(+), 30 deletions(-) diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml index 0a5c13aa4..470aea321 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml @@ -114,6 +114,7 @@ org.springframework.cloud spring-cloud-sleuth-sample-test-core + ${project.version} test diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml index 0fee3fcd6..83dcff828 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml @@ -38,36 +38,6 @@ true - - - - - - maven-deploy-plugin - - true - - - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - 1.19 - - true - - org.codehaus.mojo.signature - java17 - 1.0 - - - - - - org.springframework.boot diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml index e6c243c69..2a4fe52fb 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml @@ -105,6 +105,7 @@ org.springframework.cloud spring-cloud-sleuth-sample-test-core + ${project.version} test diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml index 900bcc2d8..876c93ce1 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml @@ -101,6 +101,7 @@ org.springframework.cloud spring-cloud-sleuth-sample-test-core + ${project.version} test From 3d8012fc56c0d80a1df3daa8c8d3b6be6cc5e50d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 9 Mar 2021 08:50:21 +0100 Subject: [PATCH 23/78] Parameterized the path key (OTel uses http.route) --- .../client/integration/sampled/WebClientTests.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java index 68b15e85e..bebe8d0fd 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java @@ -146,18 +146,21 @@ public abstract class WebClientTests { then(this.spans).isNotEmpty(); Optional noTraceSpan = this.spans.reportedSpans().stream() .filter(span -> span.getName().contains("GET") && !span.getTags().isEmpty() - && span.getTags().containsKey("http.path")) + && span.getTags().containsKey(pathKey())) .findFirst(); then(noTraceSpan.isPresent()).isTrue(); - then(noTraceSpan.get().getTags()).containsEntry("http.path", "/notrace").containsEntry("http.method", - "GET"); + then(noTraceSpan.get().getTags()).containsEntry(pathKey(), "/notrace").containsEntry("http.method", "GET"); // TODO: matches cause there is an issue with Feign not providing the full URL // at the interceptor level - then(noTraceSpan.get().getTags().get("http.path")).matches(".*/notrace"); + then(noTraceSpan.get().getTags().get(pathKey())).matches(".*/notrace"); }); thenThereIsNoCurrentSpan(); } + protected String pathKey() { + return "http.path"; + } + private void thenThereIsNoCurrentSpan() { log.info("Current span [" + this.tracer.currentSpan() + "]"); then(this.tracer.currentSpan()).isNull(); From 630229c632b0673a29fa2c6daef7acbc0d33cacf Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 9 Mar 2021 08:52:32 +0100 Subject: [PATCH 24/78] Fixed the wrong SCM settings --- spring-cloud-sleuth-dependencies/pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index 78bd736ed..c5ecf9cbb 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -30,6 +30,17 @@ pom spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies + + + https://github.com/spring-cloud/spring-cloud-sleuth + scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git + + + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git + + HEAD + + 5.13.2 0.37.4 From d090ce325545f4109080680785c2d5e23571594a Mon Sep 17 00:00:00 2001 From: blake-bauman Date: Mon, 15 Mar 2021 11:52:23 -0700 Subject: [PATCH 25/78] Issue 1860 - WebFluxSleuthOperators should use ContextView (#1881) * Adds variant of WebFluxSleuthOperators methods which use ContextView * Have existing methods using Context invoke the new methods Fixes gh-1860 --- .../web/WebFluxSleuthOperators.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java index 023917eea..b18f58a86 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/WebFluxSleuthOperators.java @@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Signal; import reactor.core.publisher.SignalType; import reactor.util.context.Context; +import reactor.util.context.ContextView; import org.springframework.cloud.sleuth.CurrentTraceContext; import org.springframework.cloud.sleuth.Span; @@ -94,6 +95,15 @@ public final class WebFluxSleuthOperators { * @param runnable - lambda to execute within the tracing context */ public static void withSpanInScope(Context context, Runnable runnable) { + withSpanInScope((ContextView) context, runnable); + } + + /** + * Wraps a runnable with a span. + * @param context - Reactor context that contains the {@link TraceContext} + * @param runnable - lambda to execute within the tracing context + */ + public static void withSpanInScope(ContextView context, Runnable runnable) { CurrentTraceContext currentTraceContext = context.get(CurrentTraceContext.class); TraceContext traceContext = traceContextOrNew(context); try (CurrentTraceContext.Scope scope = currentTraceContext.maybeScope(traceContext)) { @@ -109,12 +119,23 @@ public final class WebFluxSleuthOperators { * @return value from the callable */ public static T withSpanInScope(Context context, Callable callable) { + return withSpanInScope((ContextView) context, callable); + } + + /** + * Wraps a callable with a span. + * @param context - Reactor context that contains the {@link TraceContext} + * @param callable - lambda to execute within the tracing context + * @param callable's return type + * @return value from the callable + */ + public static T withSpanInScope(ContextView context, Callable callable) { CurrentTraceContext currentTraceContext = context.get(CurrentTraceContext.class); TraceContext traceContext = traceContextOrNew(context); return withContext(callable, currentTraceContext, traceContext); } - private static TraceContext traceContextOrNew(Context context) { + private static TraceContext traceContextOrNew(ContextView context) { Tracer tracer = context.get(Tracer.class); if (!context.hasKey(TraceContext.class)) { if (log.isDebugEnabled()) { From 3000680a3ec23c08d03f77067eafac072e70213d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 11:58:31 +0100 Subject: [PATCH 26/78] Don't wrap operators when context not active fixes gh-1856 --- .../cloud/sleuth/instrument/reactor/ReactorSleuth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java index ee3534e9c..82dd63265 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java @@ -122,7 +122,7 @@ public abstract class ReactorSleuth { ConfigurableApplicationContext springContext, LazyBean lazyCurrentTraceContext, LazyBean lazyTracer) { return (p, sub) -> { - if (!springContext.isActive()) { + if (!springContext.isActive() || !springContext.isRunning()) { if (log.isTraceEnabled()) { String message = "Spring Context [" + springContext + "] is not yet refreshed. This is unexpected. Reactor Context is [" + context(sub) From 7fa4538dfc3936cdf369c0b4d8669753ab97efa3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 11:58:46 +0100 Subject: [PATCH 27/78] Polish --- .../instrument/messaging/BraveMessagingAutoConfiguration.java | 4 ++-- .../autoconfig/instrument/web/TraceWebFluxConfiguration.java | 3 ++- .../instrument/redis/BraveRedisAutoConfigurationTests.java | 2 +- .../messaging/BraveMessagingAutoConfigurationTests.java | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java index 5b2156231..191d1350c 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfiguration.java @@ -132,7 +132,7 @@ public class BraveMessagingAutoConfiguration { } @Bean - KafkaFactoryBeanPostProcessor kafkaFactoryBeanPostProcessor(BeanFactory beanFactory) { + static KafkaFactoryBeanPostProcessor kafkaFactoryBeanPostProcessor(BeanFactory beanFactory) { return new KafkaFactoryBeanPostProcessor(beanFactory); } @@ -171,7 +171,7 @@ public class BraveMessagingAutoConfiguration { // Setup the tracing endpoint registry. @Bean - TracingJmsBeanPostProcessor tracingJmsBeanPostProcessor(BeanFactory beanFactory) { + static TracingJmsBeanPostProcessor tracingJmsBeanPostProcessor(BeanFactory beanFactory) { return new TracingJmsBeanPostProcessor(beanFactory); } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java index a9abdafc9..c38d8275c 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebFluxConfiguration.java @@ -47,7 +47,8 @@ class TraceWebFluxConfiguration { } @Bean - TraceHandlerFunctionAdapterBeanPostProcessor traceHandlerFunctionAdapterBeanPostProcessor(BeanFactory beanFactory) { + static TraceHandlerFunctionAdapterBeanPostProcessor traceHandlerFunctionAdapterBeanPostProcessor( + BeanFactory beanFactory) { return new TraceHandlerFunctionAdapterBeanPostProcessor(beanFactory); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java index 258cc9d2e..306ba7a2a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/redis/BraveRedisAutoConfigurationTests.java @@ -62,7 +62,7 @@ public class BraveRedisAutoConfigurationTests { } @Bean - TestTraceLettuceClientResourcesBeanPostProcessor testTraceLettuceClientResourcesBeanPostProcessor( + static TestTraceLettuceClientResourcesBeanPostProcessor testTraceLettuceClientResourcesBeanPostProcessor( BeanFactory beanFactory) { return new TestTraceLettuceClientResourcesBeanPostProcessor(beanFactory); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java index b0c6d3f4d..fe6945d64 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java @@ -163,7 +163,7 @@ public class BraveMessagingAutoConfigurationTests { } @Bean - SleuthRabbitBeanPostProcessor sleuthRabbitBeanPostProcessor(BeanFactory beanFactory) { + static SleuthRabbitBeanPostProcessor sleuthRabbitBeanPostProcessor(BeanFactory beanFactory) { return new TestSleuthRabbitBeanPostProcessor(beanFactory); } @@ -173,7 +173,7 @@ public class BraveMessagingAutoConfigurationTests { } @Bean - TestSleuthJmsBeanPostProcessor sleuthJmsBeanPostProcessor(BeanFactory beanFactory) { + static TestSleuthJmsBeanPostProcessor sleuthJmsBeanPostProcessor(BeanFactory beanFactory) { return new TestSleuthJmsBeanPostProcessor(beanFactory); } From e8c0c5eaba766b7a3b3e87fa19a9e422e41792b5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 11:59:05 +0100 Subject: [PATCH 28/78] SkipPatternConfiguration will reuse management.server.base-path property (#1883) fixes gh-1880 --- .../web/SkipPatternConfiguration.java | 10 ++++++++-- .../web/SkipPatternProviderConfigTest.java | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java index 8bf42509f..f910c767c 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java @@ -24,6 +24,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.springframework.beans.factory.BeanCurrentlyInCreationException; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; @@ -211,9 +212,14 @@ class SkipPatternConfiguration { @ConditionalOnProperty(name = "management.server.servlet.context-path", havingValue = "/", matchIfMissing = true) SingleSkipPattern skipPatternForActuatorEndpointsDifferentPort(Environment environment, - final ServerProperties serverProperties, final WebEndpointProperties webEndpointProperties, + final WebEndpointProperties webEndpointProperties, + ObjectProvider managementServerProperties, final EndpointsSupplier endpointsSupplier) { - return () -> getEndpointsPatterns(environment, null, webEndpointProperties, endpointsSupplier); + return () -> { + ManagementServerProperties props = managementServerProperties.getIfAvailable(); + return getEndpointsPatterns(environment, props != null ? props.getBasePath() : null, + webEndpointProperties, endpointsSupplier); + }; } } diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java index cba8e3ac3..c09b160fc 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java @@ -212,6 +212,20 @@ public class SkipPatternProviderConfigTest { }); } + @Test + public void should_return_endpoints_with_base_path_when_management_port_is_different() { + contextRunner + .withConfiguration( + UserConfigurations.of(ServerPropertiesConfig.class, ManagementServerPropertiesConfig.class)) + .withPropertyValues("management.server.base-path=/foo", "management.endpoints.web.base-path=/actuator", + "management.server.port=0") + .run(context -> { + BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( + "/foo/actuator(/|/(health|health/.*|info|info/.*))?", + SleuthWebProperties.DEFAULT_SKIP_PATTERN); + }); + } + @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root_different_port_with_placeholder() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) @@ -313,6 +327,12 @@ public class SkipPatternProviderConfigTest { } + @Configuration(proxyBeanMethods = false) + @EnableConfigurationProperties(ManagementServerProperties.class) + static class ManagementServerPropertiesConfig { + + } + @Configuration(proxyBeanMethods = false) static class EmptyEndpoints { From 2348cf17cc9e2b0d4663b72c1d2f42e39fdc93f9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 12:57:10 +0100 Subject: [PATCH 29/78] Disable double tracing filter regsitration without this change we're registering the TracingFilter twice. Once, since it's a bean and second time via the FilterRegistrationBean. with this change we're not registering the TracingFilter as a bean. It's been final so nobody could actually extend it so we're not breaking the compatibility. fixes gh-1839 --- .../instrument/web/TraceWebServletConfiguration.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java index a9416f344..1c0e73d5f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/TraceWebServletConfiguration.java @@ -28,7 +28,6 @@ import javax.servlet.ServletResponse; import org.springframework.beans.factory.BeanFactory; 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.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -79,12 +78,6 @@ class TraceWebServletConfiguration { return filterRegistrationBean; } - @Bean - @ConditionalOnMissingBean - TracingFilter tracingFilter(CurrentTraceContext currentTraceContext, HttpServerHandler httpServerHandler) { - return TracingFilter.create(currentTraceContext, httpServerHandler); - } - /** * Nested config that configures Web MVC if it's present (without adding a runtime * dependency to it). @@ -128,7 +121,8 @@ final class LazyTracingFilter implements Filter { private Filter tracingFilter() { if (this.tracingFilter == null) { - this.tracingFilter = this.beanFactory.getBean(TracingFilter.class); + this.tracingFilter = TracingFilter.create(this.beanFactory.getBean(CurrentTraceContext.class), + this.beanFactory.getBean(HttpServerHandler.class)); } return this.tracingFilter; } From 93b59a6d75f34a06f47e1bbc6f1045eb84487a79 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 14:42:44 +0100 Subject: [PATCH 30/78] Don't allow double Gateway instrumentation (#1882) * Don't allow double Gateway instrumentation with this change we're doing both HeaderFilter based Gateway instrumentation and the Netty Client one. with this change we're conditionally enabling the HeaderFilter instrumentation only when there is no Netty Client one present on the classpath. fixes gh-1840 --- .../TraceWebClientAutoConfiguration.java | 2 + .../client/GatewayAutoConfigurationTests.java | 50 +++++++++++++++++++ .../client/HttpClientBeanPostProcessor.java | 19 ++++++- .../client/TraceRequestHttpHeadersFilter.java | 15 ++++-- .../TraceRequestHttpHeadersFilterTests.java | 24 +++++++++ 5 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GatewayAutoConfigurationTests.java diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java index 46bc2f589..3e7d85c46 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/TraceWebClientAutoConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoRestTemplateCustomizer; import org.springframework.boot.web.client.RestTemplateCustomizer; @@ -104,6 +105,7 @@ class TraceWebClientAutoConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(HttpHeadersFilter.class) + @ConditionalOnMissingClass("reactor.netty.http.client.HttpClient") static class HttpHeadersFilterConfig { @Bean diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GatewayAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GatewayAutoConfigurationTests.java new file mode 100644 index 000000000..94711c59f --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/GatewayAutoConfigurationTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.web.client; + +import org.junit.jupiter.api.Test; +import reactor.netty.http.client.HttpClient; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; +import org.springframework.cloud.sleuth.autoconfig.TraceNoOpAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.web.client.TraceRequestHttpHeadersFilter; +import org.springframework.cloud.sleuth.instrument.web.client.TraceResponseHttpHeadersFilter; + +import static org.assertj.core.api.Assertions.assertThat; + +class GatewayAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.sleuth.noop.enabled=true").withConfiguration( + AutoConfigurations.of(TraceNoOpAutoConfiguration.class, TraceWebClientAutoConfiguration.class)); + + @Test + void should_not_create_gateway_trace_filters_when_reactor_netty_client_on_classpath() { + this.contextRunner.run(context -> assertThat(context).doesNotHaveBean(HttpHeadersFilter.class)); + } + + @Test + void should_create_gateway_trace_filters_when_reactor_netty_client_not_on_classpath() { + this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class)) + .run(context -> assertThat(context).hasSingleBean(TraceResponseHttpHeadersFilter.class) + .hasSingleBean(TraceRequestHttpHeadersFilter.class)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java index 118d081bc..0e3de4206 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java @@ -25,6 +25,8 @@ import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.Supplier; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; import reactor.netty.Connection; import reactor.netty.http.client.HttpClient; @@ -86,6 +88,8 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { static class TracingMapConnect implements Function, Mono> { + private static final Log log = LogFactory.getLog(TracingMapConnect.class); + static final Exception CANCELLED_ERROR = new CancellationException("CANCELLED") { @Override public Throwable fillInStackTrace() { @@ -116,6 +120,9 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { // like onComplete() completed the span (clearing the reference). Span span = pendingSpan.getAndSet(null); if (span != null) { + if (log.isDebugEnabled()) { + log.debug("Marking span [" + span + "] with cancelled error"); + } span.error(CANCELLED_ERROR); span.end(); } @@ -126,6 +133,8 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { private static class TracingDoOnRequest implements BiConsumer { + private static final Log log = LogFactory.getLog(TracingDoOnRequest.class); + final ConfigurableApplicationContext context; HttpClientHandler handler; @@ -153,15 +162,16 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { // update this code! Span span = pendingSpan.getAndSet(null); if (span != null) { - assert false : "span exists when it shouldn't!"; span.abandon(); // abandon instead of break } // Start a new client span with the appropriate parent TraceContext parent = req.currentContextView().getOrDefault(TraceContext.class, null); HttpClientRequestWrapper request = new HttpClientRequestWrapper(req, connection); - span = handler().handleSend(request, parent); + if (log.isDebugEnabled()) { + log.debug("Handled send of the netty client span [" + span + "] with parent [" + parent + "]"); + } pendingSpan.set(span); } @@ -211,6 +221,8 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { private static abstract class AbstractTracingDoOnHandler { + private static final Log log = LogFactory.getLog(AbstractTracingDoOnHandler.class); + final ConfigurableApplicationContext context; HttpClientHandler handler; @@ -236,6 +248,9 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { if (span == null) { return; // Unexpected. In the handle method, without a span to finish! } + if (log.isDebugEnabled()) { + log.debug("Handle receive of the netty client span [" + span + "]"); + } HttpClientResponseWrapper response = new HttpClientResponseWrapper(resp, error); handler().handleReceive(response, span); } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java index 4ba470676..5be41ac2c 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java @@ -44,6 +44,8 @@ public class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { static final String TRACE_REQUEST_ATTR = TraceContext.class.getName(); + static final String TRACE_REQUEST_ATTR_FROM_TRACE_WEB_FILTER = Span.class.getName(); + public TraceRequestHttpHeadersFilter(Tracer tracer, HttpClientHandler handler, Propagator propagator) { super(tracer, handler, propagator); } @@ -84,12 +86,20 @@ public class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { private Span currentSpan(ServerWebExchange exchange) { Object attribute = exchange.getAttribute(TRACE_REQUEST_ATTR); + Object span = exchange.getAttribute(TRACE_REQUEST_ATTR_FROM_TRACE_WEB_FILTER); if (attribute instanceof Span) { if (log.isDebugEnabled()) { log.debug("Found trace request attribute in the server web exchange [" + attribute + "]"); } return (Span) attribute; } + else if (span instanceof Span) { + if (log.isDebugEnabled()) { + log.debug("Found trace request attribute in the server web exchange set by TraceWebFilter [" + span + + "]"); + } + return (Span) span; + } return this.tracer.currentSpan(); } @@ -97,10 +107,7 @@ public class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { if (currentSpan == null) { return this.handler.handleSend(request); } - try (Tracer.SpanInScope ws = this.tracer.withSpan(currentSpan)) { - Span clientSpan = this.tracer.nextSpan(); - return this.handler.handleSend(request, clientSpan.context()); - } + return this.handler.handleSend(request, currentSpan.context()); } private void addHeadersWithInput(HttpHeaders filteredHeaders, HttpHeaders headersWithInput) { diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java index 5cda42385..69777c4e7 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java @@ -24,6 +24,7 @@ import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.Test; import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; +import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; import org.springframework.http.HttpHeaders; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; @@ -44,7 +45,11 @@ public abstract class TraceRequestHttpHeadersFilterTests implements TestTracingA MockServerWebExchange exchange = MockServerWebExchange.builder(request).build(); HttpHeaders filteredHeaders = filter.filter(requestHeaders(httpHeaders), exchange); + thenTraceContinuedWithNewSpan(httpHeaders, filteredHeaders); + BDDAssertions.then((Object) exchange.getAttribute(TraceRequestHttpHeadersFilter.SPAN_ATTRIBUTE)).isNotNull(); + } + private void thenTraceContinuedWithNewSpan(HttpHeaders httpHeaders, HttpHeaders filteredHeaders) { // we want to continue the trace BDDAssertions.then(high(filteredHeaders.get("X-B3-TraceId"))).isEqualTo(high(httpHeaders.get("X-B3-TraceId"))); // but we want to have a new span id @@ -53,6 +58,25 @@ public abstract class TraceRequestHttpHeadersFilterTests implements TestTracingA BDDAssertions.then(filteredHeaders.get("X-Hello-Request")) .isEqualTo(Collections.singletonList("Request World")); BDDAssertions.then(filteredHeaders.get("X-Auth-User")).hasSize(1); + } + + @Test + public void should_continue_span_tracing_when_span_already_in_exchange_attributes() { + HttpHeadersFilter filter = new TraceRequestHttpHeadersFilter(tracerTest().tracing().tracer(), + tracerTest().tracing().httpClientHandler(), tracerTest().tracing().propagator()); + HttpHeaders httpHeaders = new HttpHeaders(); + Span span = tracerTest().tracing().tracer().nextSpan(); + httpHeaders.set("X-Hello", "World"); + httpHeaders.set("X-B3-TraceId", span.context().traceId()); + httpHeaders.set("X-B3-SpanId", span.context().spanId()); + MockServerHttpRequest request = MockServerHttpRequest.post("foo/bar").headers(httpHeaders).build(); + MockServerWebExchange exchange = MockServerWebExchange.builder(request).build(); + exchange.getAttributes().put(TraceRequestHttpHeadersFilter.TRACE_REQUEST_ATTR_FROM_TRACE_WEB_FILTER, span); + + HttpHeaders filteredHeaders = filter.filter(requestHeaders(httpHeaders), exchange); + + // we want to continue the trace + thenTraceContinuedWithNewSpan(httpHeaders, filteredHeaders); BDDAssertions.then((Object) exchange.getAttribute(TraceRequestHttpHeadersFilter.SPAN_ATTRIBUTE)).isNotNull(); } From 658490d8701a8f59b7247c4af1d52b2e401705a9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 15:53:28 +0100 Subject: [PATCH 31/78] Fixed web tests --- .../instrument/web/TraceFilterIntegrationTests.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java index c80a9efbb..6ed1f1983 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceFilterIntegrationTests.java @@ -45,7 +45,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.CurrentTraceContext; import org.springframework.cloud.sleuth.autoconfig.instrument.web.SleuthWebProperties; +import org.springframework.cloud.sleuth.http.HttpServerHandler; import org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter; import org.springframework.cloud.sleuth.util.SpanUtil; import org.springframework.context.annotation.Bean; @@ -78,7 +80,10 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { private static Span span; @Autowired - TracingFilter traceFilter; + CurrentTraceContext currentTraceContext; + + @Autowired + HttpServerHandler httpServerHandler; @Autowired MyFilter myFilter; @@ -222,7 +227,8 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { @Override protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) { - mockMvcBuilder.addFilters(this.traceFilter, this.myFilter); + mockMvcBuilder.addFilters(TracingFilter.create(this.currentTraceContext, this.httpServerHandler), + this.myFilter); } private MvcResult whenSentPingWithoutTracingData() throws Exception { From 4ba698c04065635137253434d635a7ad630f50ee Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 15:53:44 +0100 Subject: [PATCH 32/78] Updated the feign builder tracing logic without this change a default Feign.Builder doesn't have its feign.Client instrumented with this change we're using reflection to instrument that Client fixes gh-1870 --- .../TraceFeignClientAutoConfiguration.java | 6 ++ .../TraceFeignBuilderBeanPostProcessor.java | 60 +++++++++++++++++++ .../client/feign/TraceFeignObjectWrapper.java | 5 +- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java index 1357db692..82be97f8f 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java @@ -35,6 +35,7 @@ import org.springframework.cloud.sleuth.instrument.web.client.feign.FeignContext import org.springframework.cloud.sleuth.instrument.web.client.feign.OkHttpFeignClientBeanPostProcessor; import org.springframework.cloud.sleuth.instrument.web.client.feign.SleuthFeignBuilder; import org.springframework.cloud.sleuth.instrument.web.client.feign.TraceFeignAspect; +import org.springframework.cloud.sleuth.instrument.web.client.feign.TraceFeignBuilderBeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -68,6 +69,11 @@ public class TraceFeignClientAutoConfiguration { return new FeignContextBeanPostProcessor(beanFactory); } + @Bean + static TraceFeignBuilderBeanPostProcessor traceFeignBuilderBeanPostProcessor(BeanFactory beanFactory) { + return new TraceFeignBuilderBeanPostProcessor(beanFactory); + } + } @Configuration(proxyBeanMethods = false) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java new file mode 100644 index 000000000..103a80496 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.web.client.feign; + +import java.lang.reflect.Field; + +import feign.Client; +import feign.Feign; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.ReflectionUtils; + +/** + * {@link BeanPostProcessor} that ensures that each {@link Feign.Builder} has + * a trace representation of a {@link Client}. + * + * @since 3.0.2 + * @author Marcin Grzejszczak + */ +public class TraceFeignBuilderBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + public TraceFeignBuilderBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof Feign.Builder) { + Field client = ReflectionUtils.findField(Feign.Builder.class, "client"); + ReflectionUtils.makeAccessible(client); + Feign.Builder delegate = (Feign.Builder) bean; + Client clientInDelegate = (Client) ReflectionUtils.getField(client, delegate); + if (clientInDelegate instanceof LazyClient || clientInDelegate instanceof LazyTracingFeignClient) { + return bean; + } + delegate.client(new LazyClient(this.beanFactory, clientInDelegate)); + return bean; + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java index 0652d7c44..afdbb25ad 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignObjectWrapper.java @@ -70,8 +70,11 @@ final class TraceFeignObjectWrapper { private Object loadBalancerClientFactory; + private final TraceFeignBuilderBeanPostProcessor traceFeignBuilderBeanPostProcessor; + TraceFeignObjectWrapper(BeanFactory beanFactory) { this.beanFactory = beanFactory; + this.traceFeignBuilderBeanPostProcessor = new TraceFeignBuilderBeanPostProcessor(beanFactory); } Object wrap(Object bean) { @@ -87,7 +90,7 @@ final class TraceFeignObjectWrapper { } return new LazyTracingFeignClient(this.beanFactory, (Client) bean); } - return bean; + return this.traceFeignBuilderBeanPostProcessor.postProcessAfterInitialization(bean, null); } private Object instrumentedFeignLoadBalancerClient(Object bean) { From 8f9c51ac81136dda84bfacac0cdeda6d1191e029 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 15:57:54 +0100 Subject: [PATCH 33/78] Fixed checkstyle --- .../web/client/feign/TraceFeignBuilderBeanPostProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java index 103a80496..168f0314d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java @@ -30,8 +30,8 @@ import org.springframework.util.ReflectionUtils; * {@link BeanPostProcessor} that ensures that each {@link Feign.Builder} has * a trace representation of a {@link Client}. * - * @since 3.0.2 * @author Marcin Grzejszczak + * @since 3.0.2 */ public class TraceFeignBuilderBeanPostProcessor implements BeanPostProcessor { From e48ebb045eece0af29841ada41808f673bbd69d0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 16:16:15 +0100 Subject: [PATCH 34/78] Exposes TraceExchangeFilterFunction; fixes gh-1847 --- .../client/TraceExchangeFilterFunction.java | 386 ++++++++++++++++++ .../TraceWebClientBeanPostProcessor.java | 335 --------------- 2 files changed, 386 insertions(+), 335 deletions(-) create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java new file mode 100644 index 000000000..69e954b8f --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java @@ -0,0 +1,386 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.web.client; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.reactivestreams.Subscription; +import reactor.core.CoreSubscriber; +import reactor.core.Scannable; +import reactor.core.publisher.Mono; +import reactor.util.annotation.Nullable; +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.http.HttpClientHandler; +import org.springframework.cloud.sleuth.http.HttpClientRequest; +import org.springframework.cloud.sleuth.http.HttpClientResponse; +import org.springframework.cloud.sleuth.instrument.reactor.TraceContextPropagator; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.ExchangeFunction; + +/** + * Trace representation of {@link ExchangeFilterFunction}. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public final class TraceExchangeFilterFunction implements ExchangeFilterFunction { + + private static final Log log = LogFactory.getLog(TraceExchangeFilterFunction.class); + + final ConfigurableApplicationContext springContext; + + // Lazy initialized fields + HttpClientHandler handler; + + CurrentTraceContext currentTraceContext; + + TraceExchangeFilterFunction(ConfigurableApplicationContext springContext) { + this.springContext = springContext; + } + + public static ExchangeFilterFunction create(ConfigurableApplicationContext springContext) { + return new TraceExchangeFilterFunction(springContext); + } + + @Override + public Mono filter(ClientRequest request, ExchangeFunction next) { + return new MonoWebClientTrace(next, request, this); + } + + CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.springContext.getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + + HttpClientHandler handler() { + if (this.handler == null) { + this.handler = this.springContext.getBean(HttpClientHandler.class); + } + return this.handler; + } + + private static final class MonoWebClientTrace extends Mono + implements Scannable, TraceContextPropagator { + + final ExchangeFunction next; + + final ClientRequest request; + + final HttpClientHandler handler; + + final CurrentTraceContext currentTraceContext; + + MonoWebClientTrace(ExchangeFunction next, ClientRequest request, TraceExchangeFilterFunction filterFunction) { + this.next = next; + this.request = request; + this.handler = filterFunction.handler(); + this.currentTraceContext = filterFunction.currentTraceContext(); + } + + @Override + public void subscribe(CoreSubscriber subscriber) { + Context context = subscriber.currentContext(); + if (log.isTraceEnabled()) { + log.trace("Got the following context [" + context + "]"); + } + ClientRequestWrapper wrapper = new ClientRequestWrapper(this.request); + TraceContext parent = context.hasKey(TraceContext.class) ? context.get(TraceContext.class) : null; + Span span = handler.handleSend(wrapper, parent); + if (log.isTraceEnabled()) { + log.trace("HttpClientHandler::handleSend: " + span); + } + // NOTE: We are starting the client span for the request here, but it could be + // canceled prior to actually being invoked. TraceWebClientSubscription will + // abandon this span, if cancel() happens before request(). + this.next.exchange(wrapper.buildRequest()) + .subscribe(new TraceWebClientSubscriber(subscriber, context, span, parent, this)); + } + + @Nullable + @Override + public Object scanUnsafe(Attr key) { + if (key == Attr.RUN_STYLE) { + return Attr.RunStyle.SYNC; + } + return null; + } + + } + + /** + * Subscriber for WebClient. + */ + static final class TraceWebClientSubscriber extends AtomicReference + implements CoreSubscriber, Scannable { + + final CoreSubscriber actual; + + final Context context; + + @Nullable + final TraceContext parent; + + final HttpClientHandler handler; + + final CurrentTraceContext currentTraceContext; + + TraceWebClientSubscriber(CoreSubscriber actual, Context ctx, Span clientSpan, + TraceContext parent, MonoWebClientTrace mono) { + this.actual = actual; + this.parent = parent; + this.handler = mono.handler; + this.currentTraceContext = mono.currentTraceContext; + this.context = this.parent != null && !this.parent.equals(ctx.getOrDefault(TraceContext.class, null)) + ? ctx.put(TraceContext.class, this.parent) : ctx; + set(clientSpan); + } + + @Override + public void onSubscribe(Subscription subscription) { + this.actual.onSubscribe(new TraceWebClientSubscription(subscription, this)); + } + + @Override + public void onNext(ClientResponse response) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { + if (log.isTraceEnabled()) { + log.trace("OnNext"); + } + // decorate response body + this.actual.onNext(response); + } + finally { + Span span = getAndSet(null); + if (span != null) { + if (log.isTraceEnabled()) { + log.trace("OnNext finally"); + } + // TODO: is there a way to read the request at response time? + this.handler.handleReceive(new ClientResponseWrapper(response), span); + } + } + } + + @Override + public void onError(Throwable t) { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { + if (log.isTraceEnabled()) { + log.trace("OnError"); + } + this.actual.onError(t); + } + finally { + Span span = getAndSet(null); + if (span != null) { + if (log.isTraceEnabled()) { + log.trace("OnError finally"); + } + span.error(t); + span.end(); + } + } + } + + @Override + public void onComplete() { + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { + if (log.isTraceEnabled()) { + log.trace("OnComplete"); + } + this.actual.onComplete(); + } + finally { + Span span = getAndSet(null); + if (span != null) { + // TODO: backfill empty test: + // https://github.com/spring-cloud/spring-cloud-sleuth/issues/1570 + if (log.isTraceEnabled()) { + log.trace("Reached OnComplete without finishing [" + span + "]"); + } + span.abandon(); + } + } + } + + @Override + public Context currentContext() { + return this.context; + } + + @Override + public Object scanUnsafe(Attr key) { + if (key == Attr.RUN_STYLE) { + return Attr.RunStyle.SYNC; + } + return null; + } + + } + + static class TraceWebClientSubscription implements Subscription { + + static final Exception CANCELLED_ERROR = new CancellationException("CANCELLED") { + @Override + public Throwable fillInStackTrace() { + return this; // stack trace doesn't add value here + } + }; + + final AtomicReference pendingSpan; + + final Subscription delegate; + + volatile boolean requested; + + TraceWebClientSubscription(Subscription delegate, AtomicReference pendingSpan) { + this.delegate = delegate; + this.pendingSpan = pendingSpan; + } + + @Override + public void request(long n) { + requested = true; + delegate.request(n); // Not scoping to save overhead + } + + @Override + public void cancel() { + delegate.cancel(); // Not scoping to save overhead + + // Check to see if Subscription.cancel() happened after request(), + // but before another signal (like onComplete) completed the span. + Span span = pendingSpan.getAndSet(null); + if (span != null) { + if (log.isTraceEnabled()) { + log.trace("Subscription was cancelled. TraceWebClientBeanPostProcessor Will close the span [" + span + + "]"); + } + + if (!requested) { // Abandon the span. + span.abandon(); + } + else { // Request was canceled in-flight + span.error(CANCELLED_ERROR); + span.end(); + } + } + } + + } + + private static final class ClientRequestWrapper implements HttpClientRequest { + + final ClientRequest delegate; + + final ClientRequest.Builder builder; + + ClientRequestWrapper(ClientRequest delegate) { + this.delegate = delegate; + this.builder = ClientRequest.from(delegate); + } + + @Override + public Collection headerNames() { + return this.delegate.headers().keySet(); + } + + @Override + public Object unwrap() { + return delegate; + } + + @Override + public String method() { + return delegate.method().name(); + } + + @Override + public String path() { + return delegate.url().getPath(); + } + + @Override + public String url() { + return delegate.url().toString(); + } + + @Override + public String header(String name) { + return delegate.headers().getFirst(name); + } + + @Override + public void header(String name, String value) { + builder.header(name, value); + } + + ClientRequest buildRequest() { + return builder.build(); + } + + } + + static final class ClientResponseWrapper implements HttpClientResponse { + + final ClientResponse delegate; + + ClientResponseWrapper(ClientResponse delegate) { + this.delegate = delegate; + } + + @Override + public Collection headerNames() { + return this.delegate.headers().asHttpHeaders().keySet(); + } + + @Override + public Object unwrap() { + return delegate; + } + + @Override + public int statusCode() { + // unlike statusCode(), this doesn't throw + return Math.max(delegate.rawStatusCode(), 0); + } + + @Override + public String header(String header) { + List headers = delegate.headers().header(header); + if (headers.isEmpty()) { + return null; + } + return headers.get(0); + } + + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java index b9a6b171e..7485ffe59 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java @@ -103,338 +103,3 @@ public class TraceWebClientBeanPostProcessor implements BeanPostProcessor { } -final class TraceExchangeFilterFunction implements ExchangeFilterFunction { - - private static final Log log = LogFactory.getLog(TraceExchangeFilterFunction.class); - - final ConfigurableApplicationContext springContext; - - // Lazy initialized fields - HttpClientHandler handler; - - CurrentTraceContext currentTraceContext; - - TraceExchangeFilterFunction(ConfigurableApplicationContext springContext) { - this.springContext = springContext; - } - - public static ExchangeFilterFunction create(ConfigurableApplicationContext springContext) { - return new TraceExchangeFilterFunction(springContext); - } - - @Override - public Mono filter(ClientRequest request, ExchangeFunction next) { - return new MonoWebClientTrace(next, request, this); - } - - CurrentTraceContext currentTraceContext() { - if (this.currentTraceContext == null) { - this.currentTraceContext = this.springContext.getBean(CurrentTraceContext.class); - } - return this.currentTraceContext; - } - - HttpClientHandler handler() { - if (this.handler == null) { - this.handler = this.springContext.getBean(HttpClientHandler.class); - } - return this.handler; - } - - private static final class MonoWebClientTrace extends Mono - implements Scannable, TraceContextPropagator { - - final ExchangeFunction next; - - final ClientRequest request; - - final HttpClientHandler handler; - - final CurrentTraceContext currentTraceContext; - - MonoWebClientTrace(ExchangeFunction next, ClientRequest request, TraceExchangeFilterFunction filterFunction) { - this.next = next; - this.request = request; - this.handler = filterFunction.handler(); - this.currentTraceContext = filterFunction.currentTraceContext(); - } - - @Override - public void subscribe(CoreSubscriber subscriber) { - Context context = subscriber.currentContext(); - if (log.isTraceEnabled()) { - log.trace("Got the following context [" + context + "]"); - } - ClientRequestWrapper wrapper = new ClientRequestWrapper(this.request); - TraceContext parent = context.hasKey(TraceContext.class) ? context.get(TraceContext.class) : null; - Span span = handler.handleSend(wrapper, parent); - if (log.isTraceEnabled()) { - log.trace("HttpClientHandler::handleSend: " + span); - } - // NOTE: We are starting the client span for the request here, but it could be - // canceled prior to actually being invoked. TraceWebClientSubscription will - // abandon this span, if cancel() happens before request(). - this.next.exchange(wrapper.buildRequest()) - .subscribe(new TraceWebClientSubscriber(subscriber, context, span, parent, this)); - } - - @Nullable - @Override - public Object scanUnsafe(Scannable.Attr key) { - if (key == Scannable.Attr.RUN_STYLE) { - return Scannable.Attr.RunStyle.SYNC; - } - return null; - } - - } - - /** - * Subscriber for WebClient. - */ - static final class TraceWebClientSubscriber extends AtomicReference - implements CoreSubscriber, Scannable { - - final CoreSubscriber actual; - - final Context context; - - @Nullable - final TraceContext parent; - - final HttpClientHandler handler; - - final CurrentTraceContext currentTraceContext; - - TraceWebClientSubscriber(CoreSubscriber actual, Context ctx, Span clientSpan, - TraceContext parent, MonoWebClientTrace mono) { - this.actual = actual; - this.parent = parent; - this.handler = mono.handler; - this.currentTraceContext = mono.currentTraceContext; - this.context = this.parent != null && !this.parent.equals(ctx.getOrDefault(TraceContext.class, null)) - ? ctx.put(TraceContext.class, this.parent) : ctx; - set(clientSpan); - } - - @Override - public void onSubscribe(Subscription subscription) { - this.actual.onSubscribe(new TraceWebClientSubscription(subscription, this)); - } - - @Override - public void onNext(ClientResponse response) { - try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { - if (log.isTraceEnabled()) { - log.trace("OnNext"); - } - // decorate response body - this.actual.onNext(response); - } - finally { - Span span = getAndSet(null); - if (span != null) { - if (log.isTraceEnabled()) { - log.trace("OnNext finally"); - } - // TODO: is there a way to read the request at response time? - this.handler.handleReceive(new ClientResponseWrapper(response), span); - } - } - } - - @Override - public void onError(Throwable t) { - try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { - if (log.isTraceEnabled()) { - log.trace("OnError"); - } - this.actual.onError(t); - } - finally { - Span span = getAndSet(null); - if (span != null) { - if (log.isTraceEnabled()) { - log.trace("OnError finally"); - } - span.error(t); - span.end(); - } - } - } - - @Override - public void onComplete() { - try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(parent)) { - if (log.isTraceEnabled()) { - log.trace("OnComplete"); - } - this.actual.onComplete(); - } - finally { - Span span = getAndSet(null); - if (span != null) { - // TODO: backfill empty test: - // https://github.com/spring-cloud/spring-cloud-sleuth/issues/1570 - if (log.isTraceEnabled()) { - log.trace("Reached OnComplete without finishing [" + span + "]"); - } - span.abandon(); - } - } - } - - @Override - public Context currentContext() { - return this.context; - } - - @Override - public Object scanUnsafe(Scannable.Attr key) { - if (key == Scannable.Attr.RUN_STYLE) { - return Scannable.Attr.RunStyle.SYNC; - } - return null; - } - - } - - static class TraceWebClientSubscription implements Subscription { - - static final Exception CANCELLED_ERROR = new CancellationException("CANCELLED") { - @Override - public Throwable fillInStackTrace() { - return this; // stack trace doesn't add value here - } - }; - - final AtomicReference pendingSpan; - - final Subscription delegate; - - volatile boolean requested; - - TraceWebClientSubscription(Subscription delegate, AtomicReference pendingSpan) { - this.delegate = delegate; - this.pendingSpan = pendingSpan; - } - - @Override - public void request(long n) { - requested = true; - delegate.request(n); // Not scoping to save overhead - } - - @Override - public void cancel() { - delegate.cancel(); // Not scoping to save overhead - - // Check to see if Subscription.cancel() happened after request(), - // but before another signal (like onComplete) completed the span. - Span span = pendingSpan.getAndSet(null); - if (span != null) { - if (log.isTraceEnabled()) { - log.trace("Subscription was cancelled. TraceWebClientBeanPostProcessor Will close the span [" + span - + "]"); - } - - if (!requested) { // Abandon the span. - span.abandon(); - } - else { // Request was canceled in-flight - span.error(CANCELLED_ERROR); - span.end(); - } - } - } - - } - - private static final class ClientRequestWrapper implements HttpClientRequest { - - final ClientRequest delegate; - - final ClientRequest.Builder builder; - - ClientRequestWrapper(ClientRequest delegate) { - this.delegate = delegate; - this.builder = ClientRequest.from(delegate); - } - - @Override - public Collection headerNames() { - return this.delegate.headers().keySet(); - } - - @Override - public Object unwrap() { - return delegate; - } - - @Override - public String method() { - return delegate.method().name(); - } - - @Override - public String path() { - return delegate.url().getPath(); - } - - @Override - public String url() { - return delegate.url().toString(); - } - - @Override - public String header(String name) { - return delegate.headers().getFirst(name); - } - - @Override - public void header(String name, String value) { - builder.header(name, value); - } - - ClientRequest buildRequest() { - return builder.build(); - } - - } - - static final class ClientResponseWrapper implements HttpClientResponse { - - final ClientResponse delegate; - - ClientResponseWrapper(ClientResponse delegate) { - this.delegate = delegate; - } - - @Override - public Collection headerNames() { - return this.delegate.headers().asHttpHeaders().keySet(); - } - - @Override - public Object unwrap() { - return delegate; - } - - @Override - public int statusCode() { - // unlike statusCode(), this doesn't throw - return Math.max(delegate.rawStatusCode(), 0); - } - - @Override - public String header(String header) { - List headers = delegate.headers().header(header); - if (headers.isEmpty()) { - return null; - } - return headers.get(0); - } - - } - -} From 8d9e93fa085111a0756d11acb8516b9cef8a4943 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 16:25:42 +0100 Subject: [PATCH 35/78] Fixed checkstyle --- .../TraceWebClientBeanPostProcessor.java | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java index 7485ffe59..6a0127801 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java @@ -16,34 +16,12 @@ package org.springframework.cloud.sleuth.instrument.web.client; -import java.util.Collection; import java.util.List; -import java.util.concurrent.CancellationException; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.reactivestreams.Subscription; -import reactor.core.CoreSubscriber; -import reactor.core.Scannable; -import reactor.core.publisher.Mono; -import reactor.util.annotation.Nullable; -import reactor.util.context.Context; - import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.cloud.sleuth.CurrentTraceContext; -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.TraceContext; -import org.springframework.cloud.sleuth.http.HttpClientHandler; -import org.springframework.cloud.sleuth.http.HttpClientRequest; -import org.springframework.cloud.sleuth.http.HttpClientResponse; -import org.springframework.cloud.sleuth.instrument.reactor.TraceContextPropagator; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import org.springframework.web.reactive.function.client.ExchangeFunction; import org.springframework.web.reactive.function.client.WebClient; /** From 984f62c32d8278e9bbd31b6c9698c6b533d42c97 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Mar 2021 17:00:56 +0100 Subject: [PATCH 36/78] Fixed custom propagation mode option with this change when CUSTOM mode is turned on we will search for user provided Propagation bean or else noop fixes gh-1836 --- .../CompositePropagationFactorySupplier.java | 35 +++++- ...positePropagationFactorySupplierTests.java | 118 ++++++++++++++++++ .../TraceWebClientBeanPostProcessor.java | 1 - .../TraceFeignBuilderBeanPostProcessor.java | 4 +- 4 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java index 787d02fc2..167ccce25 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java @@ -30,6 +30,7 @@ import brave.propagation.TraceContextOrSamplingFlags; import brave.propagation.aws.AWSPropagation; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.sleuth.brave.propagation.PropagationFactorySupplier; import org.springframework.cloud.sleuth.brave.propagation.PropagationType; @@ -56,7 +57,7 @@ public class CompositePropagationFactorySupplier implements PropagationFactorySu @Override public Propagation.Factory get() { - return new CompositePropagationFactory( + return new CompositePropagationFactory(this.beanFactory, this.beanFactory.getBeanProvider(BraveBaggageManager.class).getIfAvailable(BraveBaggageManager::new), this.localFields, this.types); } @@ -69,8 +70,8 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga private final List types; - CompositePropagationFactory(BraveBaggageManager braveBaggageManager, List localFields, - List types) { + CompositePropagationFactory(BeanFactory beanFactory, BraveBaggageManager braveBaggageManager, + List localFields, List types) { this.types = types; this.mapping.put(PropagationType.AWS, AWSPropagation.FACTORY.get()); // Note: Versions <2.2.3 use injectFormat(MULTI) for non-remote (ex @@ -79,7 +80,7 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga this.mapping.put(PropagationType.B3, B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build().get()); this.mapping.put(PropagationType.W3C, new W3CPropagation(braveBaggageManager, localFields)); - this.mapping.put(PropagationType.CUSTOM, NoOpPropagation.INSTANCE); + this.mapping.put(PropagationType.CUSTOM, new LazyPropagation(beanFactory.getBeanProvider(Propagation.class))); } @Override @@ -116,6 +117,32 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga return StringPropagationAdapter.create(this, keyFactory); } + @SuppressWarnings("unchecked") + private static final class LazyPropagation implements Propagation { + + private final ObjectProvider delegate; + + private LazyPropagation(ObjectProvider delegate) { + this.delegate = delegate; + } + + @Override + public List keys() { + return this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE).keys(); + } + + @Override + public TraceContext.Injector injector(Setter setter) { + return this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE).injector(setter); + } + + @Override + public TraceContext.Extractor extractor(Getter getter) { + return this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE).extractor(getter); + } + + } + private static class NoOpPropagation implements Propagation { static final NoOpPropagation INSTANCE = new NoOpPropagation(); diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java new file mode 100644 index 000000000..1884a69a1 --- /dev/null +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java @@ -0,0 +1,118 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.bridge; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import brave.internal.codec.HexCodec; +import brave.internal.propagation.StringPropagationAdapter; +import brave.propagation.Propagation; +import brave.propagation.TraceContext; +import brave.propagation.TraceContextOrSamplingFlags; +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider; +import org.springframework.cloud.sleuth.brave.propagation.PropagationType; +import org.springframework.util.StringUtils; + +class CompositePropagationFactorySupplierTests { + + @Test + void should_pick_custom_registered_propagation_when_custom_mode_picked() { + BeanFactory beanFactory = Mockito.mock(BeanFactory.class); + Mockito.when(beanFactory.getBeanProvider(BraveBaggageManager.class)) + .thenReturn(new SimpleObjectProvider(new BraveBaggageManager())); + Mockito.when(beanFactory.getBeanProvider(Propagation.class)) + .thenReturn(new SimpleObjectProvider(new CustomTracePropagation())); + + CompositePropagationFactorySupplier supplier = new CompositePropagationFactorySupplier(beanFactory, + Collections.emptyList(), Collections.singletonList(PropagationType.CUSTOM)); + + BDDAssertions.then(supplier.get().get().keys()).containsExactly(CustomTraceExtractor.CUSTOM_TRACE_HEADER); + } + +} + +class CustomTracePropagation extends Propagation.Factory implements Propagation { + + public static final List KEYS = Collections.singletonList(CustomTraceExtractor.CUSTOM_TRACE_HEADER); + + @Override + public List keys() { + return KEYS; + } + + @Override + public TraceContext.Injector injector(Setter setter) { + return (traceContext, request) -> { + String trace = traceContext.traceIdString() + ":" + traceContext.spanIdString(); + setter.put(request, CustomTraceExtractor.CUSTOM_TRACE_HEADER, trace); + }; + } + + @Override + public TraceContext.Extractor extractor(Getter getter) { + Objects.requireNonNull(getter); + return new CustomTraceExtractor<>(getter); + } + + @Override + public Propagation create(KeyFactory keyFactory) { + return StringPropagationAdapter.create(this, keyFactory); + } + +} + +class CustomTraceExtractor implements TraceContext.Extractor { + + static final String CUSTOM_TRACE_HEADER = "x-custom-trace"; + + final Propagation.Getter getter; + + CustomTraceExtractor(Propagation.Getter getter) { + this.getter = getter; + } + + @Override + @SuppressWarnings("ReturnCount") + public TraceContextOrSamplingFlags extract(R request) { + String traceString = getter.get(request, CUSTOM_TRACE_HEADER); + if (!StringUtils.hasText(traceString)) { + return TraceContextOrSamplingFlags.EMPTY; + } + String[] trace = traceString.split(":"); + if (trace.length != 2) { + return TraceContextOrSamplingFlags.EMPTY; + } + + try { + TraceContext traceContext = TraceContext.newBuilder().traceId(HexCodec.lowerHexToUnsignedLong(trace[0])) + .spanId(HexCodec.lowerHexToUnsignedLong(trace[1])).build(); + + return TraceContextOrSamplingFlags.create(traceContext); + } + catch (NumberFormatException ex) { + return TraceContextOrSamplingFlags.EMPTY; + } + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java index 6a0127801..1dd21b4df 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientBeanPostProcessor.java @@ -80,4 +80,3 @@ public class TraceWebClientBeanPostProcessor implements BeanPostProcessor { } } - diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java index 168f0314d..c10596245 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignBuilderBeanPostProcessor.java @@ -27,8 +27,8 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.util.ReflectionUtils; /** - * {@link BeanPostProcessor} that ensures that each {@link Feign.Builder} has - * a trace representation of a {@link Client}. + * {@link BeanPostProcessor} that ensures that each {@link Feign.Builder} has a trace + * representation of a {@link Client}. * * @author Marcin Grzejszczak * @since 3.0.2 From 39094e16145a482169ca97dd2a0496b2d0de7ab2 Mon Sep 17 00:00:00 2001 From: Artem Ptushkin Date: Wed, 17 Mar 2021 10:46:55 +0100 Subject: [PATCH 37/78] #1874: make message header getter case insensitive for propagated headers (#1884) --- .../MessageHeaderPropagatorGetter.java | 49 ++++++++++++++----- .../baggage/MultipleHopsIntegrationTests.java | 7 ++- .../TracingChannelInterceptorTest.java | 14 +++++- .../MultipleHopsIntegrationTests.java | 8 ++- .../TracingChannelInterceptorTest.java | 40 +++++++++++++++ 5 files changed, 102 insertions(+), 16 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java index ac1513f06..ca96e37b0 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java @@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.instrument.messaging; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -60,26 +61,51 @@ public class MessageHeaderPropagatorGetter implements Propagator.Getter> nativeHeadersMap = nativeAccessor.toNativeHeaderMap(); + if (!nativeHeadersMap.isEmpty()) { + return getFromNativeHeaders(nativeHeadersMap, key); } } else { Object nativeHeaders = accessor.getHeader(NativeMessageHeaderAccessor.NATIVE_HEADERS); if (nativeHeaders instanceof Map) { - Object result = ((Map) nativeHeaders).get(key); - if (result instanceof List && !((List) result).isEmpty()) { - return String.valueOf(((List) result).get(0)); + Map nativeHeadersMap = (Map) nativeHeaders; + if (!nativeHeadersMap.isEmpty()) { + return getFromNativeHeaders(nativeHeadersMap, key); } } } - Object result = accessor.getHeader(key); - if (result != null) { - if (result instanceof byte[]) { - return new String((byte[]) result, StandardCharsets.UTF_8); + Set> headerEntries = accessor.getMessageHeaders().entrySet(); + return getFromHeaders(headerEntries, key); + } + + private String getFromHeaders(Set> headerEntries, String key) { + for (Map.Entry entry : headerEntries) { + if (entry.getKey().equalsIgnoreCase(key)) { + Object result = entry.getValue(); + if (result != null) { + if (result instanceof byte[]) { + return new String((byte[]) result, StandardCharsets.UTF_8); + } + return result.toString(); + } + } + } + return null; + } + + private String getFromNativeHeaders(Map nativeHeaders, String key) { + Set entrySet = nativeHeaders.entrySet(); + for (Map.Entry entries : entrySet) { + if (entries.getKey() instanceof String) { + String headersKey = (String) entries.getKey(); + if (headersKey.equalsIgnoreCase(key)) { + Object result = entries.getValue(); + if (result instanceof List && !((List) result).isEmpty()) { + return String.valueOf(((List) result).get(0)); + } + } } - return result.toString(); } return null; } @@ -88,5 +114,4 @@ public class MessageHeaderPropagatorGetter implements Propagator.Getter !span.equals(initialSpan)) - .allMatch(span -> "FO".equals(COUNTRY_CODE.getValue(BraveAccessor.traceContext(span.context())))); + // it propagates only and all the `spring.sleuth.baggage.remote-fields` in case insensitive way + .allMatch(span -> "FO".equals(COUNTRY_CODE.getValue(BraveAccessor.traceContext(span.context())))) + .allMatch(span -> "123".equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) + .allMatch(span -> NOT_PROPAGATED_HEADER.getValue(BraveAccessor.traceContext(span.context())) == null); } @Configuration(proxyBeanMethods = false) diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java index 2ff7ef924..7f0ce0993 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java @@ -20,6 +20,9 @@ import java.util.List; import java.util.Map; import brave.Tracing; +import brave.baggage.BaggageField; +import brave.baggage.BaggagePropagation; +import brave.baggage.BaggagePropagationConfig; import brave.propagation.B3Propagation; import brave.propagation.TraceContext; import org.junit.jupiter.api.Test; @@ -46,7 +49,14 @@ public class TracingChannelInterceptorTest @Override public Tracing.Builder tracingBuilder() { return super.tracingBuilder() - .propagationFactory(B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build()); + .propagationFactory(BaggagePropagation.newFactoryBuilder(B3Propagation.newFactoryBuilder() + .injectFormat(SINGLE) + .build() + ) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) + .build() + ); } }; this.testTracing.reset(); @@ -67,7 +77,7 @@ public class TracingChannelInterceptorTest TraceContext receiveContext = parseB3SingleFormat( ((List) ((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS)).get("b3")).get(0).toString()) - .context(); + .context(); assertThat(receiveContext.parentIdString()).isEqualTo("000000000000000b"); } diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java index 3011494ff..83514b534 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java @@ -52,7 +52,7 @@ import static org.assertj.core.api.BDDAssertions.then; import static org.awaitility.Awaitility.await; @ContextConfiguration(classes = MultipleHopsIntegrationTests.TestConfig.class) -@TestPropertySource(properties = { "spring.sleuth.baggage.remote-fields=x-vcap-request-id,country-code", +@TestPropertySource(properties = { "spring.sleuth.baggage.remote-fields=x-vcap-request-id,country-code,Foo-Id", "spring.sleuth.baggage.local-fields=bp", "spring.sleuth.integration.enabled=true" }) public abstract class MultipleHopsIntegrationTests { @@ -62,6 +62,10 @@ public abstract class MultipleHopsIntegrationTests { protected static final String COUNTRY_CODE = "country-code"; + protected static final String CASE_INSENSITIVE_ID = "Foo-Id"; + + protected static final String NOT_PROPAGATED_HEADER = "baz-id"; + @Autowired Tracer tracer; @@ -117,6 +121,8 @@ public abstract class MultipleHopsIntegrationTests { // set request ID in a header not with the api explicitly HttpHeaders headers = new HttpHeaders(); headers.put(REQUEST_ID, Collections.singletonList("f4308d05-2228-4468-80f6-92a8377ba193")); + headers.put(CASE_INSENSITIVE_ID, Collections.singletonList("123")); + headers.put(NOT_PROPAGATED_HEADER, Collections.singletonList("456")); RequestEntity requestEntity = new RequestEntity(headers, HttpMethod.GET, URI.create("http://localhost:" + this.testConfig.port + "/greeting")); this.restTemplate.exchange(requestEntity, String.class); diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index 323eaff91..d305300b9 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -45,8 +45,10 @@ import org.springframework.messaging.support.ErrorMessage; import org.springframework.messaging.support.ExecutorChannelInterceptor; import org.springframework.messaging.support.ExecutorSubscribableChannel; import org.springframework.messaging.support.MessageBuilder; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.StringUtils; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.messaging.support.NativeMessageHeaderAccessor.NATIVE_HEADERS; @@ -348,6 +350,44 @@ public abstract class TracingChannelInterceptorTest implements TestTracingAwareS assertThat(this.spans).extracting(FinishedSpan::getRemoteServiceName).containsOnly("broker", null); } + @Test + public void should_propagate_headers_case_insensitive() { + channel.addInterceptor(this.interceptor); + Map headers = new HashMap<>(); + headers.put("Foo-Id", "123"); + headers.put("baz-id", "456"); + + channel.send(MessageBuilder.createMessage("foo", new MessageHeaders(headers))); + + Message actualMessage = channel.receive(); + + assertThat(actualMessage.getHeaders()).isNotEmpty(); + assertThat(actualMessage.getHeaders().get("not-propagated-header")).isNull(); + assertThat(actualMessage.getHeaders().get("Foo-Id")).isEqualTo("123"); + assertThat(actualMessage.getHeaders().get("baz-id")).isEqualTo("456"); + } + + @Test + public void should_propagate_native_headers_case_insensitive() { + channel.addInterceptor(this.interceptor); + LinkedMultiValueMap nativeHeaders = new LinkedMultiValueMap<>(); + nativeHeaders.put("Foo-Id", singletonList("123")); + nativeHeaders.put("baz-id", singletonList("456")); + Map headers = new HashMap<>(); + headers.put(NATIVE_HEADERS, nativeHeaders); + + channel.send(MessageBuilder.createMessage("foo", new MessageHeaders(headers))); + + Message actualMessage = channel.receive(); + + assertThat(actualMessage.getHeaders()).isNotEmpty(); + LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders().get(NATIVE_HEADERS); + assertThat(actualNativeHeaders).isNotEmpty(); + assertThat(actualNativeHeaders.get("not-propagated-header")).isNull(); + assertThat(actualNativeHeaders.get("Foo-Id")).isEqualTo(singletonList("123")); + assertThat(actualNativeHeaders.get("baz-id")).isEqualTo(singletonList("456")); + } + public ChannelInterceptor producerSideOnly(ChannelInterceptor delegate) { return new ChannelInterceptorAdapter() { @Override From 551094af4a1cb079996f996a6088a592f5ba00c4 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Wed, 17 Mar 2021 22:09:09 +0000 Subject: [PATCH 38/78] Update SNAPSHOT to 3.0.2 --- benchmarks/pom.xml | 4 +- docs/pom.xml | 2 +- pom.xml | 20 +- spring-cloud-sleuth-api/pom.xml | 2 +- spring-cloud-sleuth-autoconfigure/pom.xml | 2 +- spring-cloud-sleuth-brave/pom.xml | 2 +- .../.flattened-pom.xml | 224 ++++++++++++++++++ spring-cloud-sleuth-dependencies/pom.xml | 4 +- spring-cloud-sleuth-instrumentation/pom.xml | 2 +- .../MessageHeaderPropagatorGetter.java | 1 + spring-cloud-sleuth-samples/pom.xml | 2 +- .../spring-cloud-sleuth-sample-feign/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-sample-zipkin/pom.xml | 2 +- .../spring-cloud-sleuth-sample/pom.xml | 2 +- spring-cloud-sleuth-zipkin/pom.xml | 2 +- spring-cloud-starter-sleuth/pom.xml | 2 +- tests/brave/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../baggage/MultipleHopsIntegrationTests.java | 6 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../TracingChannelInterceptorTest.java | 16 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-zipkin-tests/pom.xml | 2 +- tests/common/pom.xml | 2 +- .../TracingChannelInterceptorTest.java | 3 +- tests/pom.xml | 2 +- 41 files changed, 284 insertions(+), 60 deletions(-) create mode 100644 spring-cloud-sleuth-dependencies/.flattened-pom.xml diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 2e529b161..c20620fca 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -22,7 +22,7 @@ Benchmarks Benchmarks (JMH) org.springframework.cloud - 3.0.2-SNAPSHOT + 3.0.2 benchmarks @@ -41,7 +41,7 @@ 4.9.0 0.2.0.RELEASE 1.26 - 3.1.1-SNAPSHOT + 3.1.2 diff --git a/docs/pom.xml b/docs/pom.xml index 03a3c3b77..edc16ecbf 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -21,7 +21,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 spring-cloud-sleuth-docs jar diff --git a/pom.xml b/pom.xml index 4f25baa78..024e931c2 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 4.0.0 spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 pom Spring Cloud Sleuth Spring Cloud Sleuth @@ -29,7 +29,7 @@ org.springframework.cloud spring-cloud-build - 3.0.2-SNAPSHOT + 3.0.2 @@ -62,14 +62,14 @@ 1.8 1.8 1.8 - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT - 2.0.1-SNAPSHOT - 3.1.1-SNAPSHOT - 3.1.2-SNAPSHOT - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT + 3.0.2 + 3.0.2 + 3.0.2 + 2.0.1 + 3.1.2 + 3.1.2 + 3.0.2 + 3.0.2 5.13.2 0.32.0 2.3.4.RELEASE diff --git a/spring-cloud-sleuth-api/pom.xml b/spring-cloud-sleuth-api/pom.xml index 9fb4fbeb6..238ad194a 100644 --- a/spring-cloud-sleuth-api/pom.xml +++ b/spring-cloud-sleuth-api/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index 734ef1bd9..c299ffde4 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-brave/pom.xml b/spring-cloud-sleuth-brave/pom.xml index 80ab5d2b9..2b56f6ba4 100644 --- a/spring-cloud-sleuth-brave/pom.xml +++ b/spring-cloud-sleuth-brave/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-dependencies/.flattened-pom.xml b/spring-cloud-sleuth-dependencies/.flattened-pom.xml new file mode 100644 index 000000000..bd1d8cc5c --- /dev/null +++ b/spring-cloud-sleuth-dependencies/.flattened-pom.xml @@ -0,0 +1,224 @@ + + + + 4.0.0 + + org.springframework.cloud + spring-cloud-dependencies-parent + 3.0.2 + + + org.springframework.cloud + spring-cloud-sleuth-dependencies + 3.0.2 + pom + spring-cloud-sleuth-dependencies + Spring Cloud Sleuth Dependencies + https://projects.spring.io/spring-cloud/spring-cloud-sleuth-dependencies/ + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2015 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 + + https://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. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + Project lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + Project lead + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git + https://github.com/spring-cloud/spring-cloud-sleuth + + + + repo.spring.io + Spring Release Repository + https://repo.spring.io/libs-release-local + + + repo.spring.io + Spring Snapshot Repository + https://repo.spring.io/libs-snapshot-local + + + spring-docs + scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-cloud/docs/spring-cloud-dependencies-parent/3.0.2/spring-cloud-sleuth-dependencies + + https://github.com/spring-cloud + + + 0.37.4 + 4.2.2 + 5.13.2 + + + + + org.springframework.cloud + spring-cloud-sleuth-autoconfigure + ${project.version} + + + org.springframework.cloud + spring-cloud-sleuth-api + ${project.version} + + + org.springframework.cloud + spring-cloud-sleuth-instrumentation + ${project.version} + + + org.springframework.cloud + spring-cloud-sleuth-brave + ${project.version} + + + org.springframework.cloud + spring-cloud-sleuth-zipkin + ${project.version} + + + org.springframework.cloud + spring-cloud-starter-sleuth + ${project.version} + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + ${project.version} + + + io.zipkin.brave + brave-bom + ${brave.version} + pom + import + + + io.opentracing.brave + brave-opentracing + ${brave.opentracing.version} + + + * + io.zipkin.brave + + + + + io.github.lognet + grpc-spring-boot-starter + ${grpc.spring.boot.version} + + + + + + spring + + + + false + + + true + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + + + false + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + false + + spring-releases + Spring Releases + https://repo.spring.io/release + + + + + + false + + + true + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + + + false + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + + diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index c5ecf9cbb..d946db557 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -22,11 +22,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 3.0.2-SNAPSHOT + 3.0.2 spring-cloud-sleuth-dependencies - 3.0.2-SNAPSHOT + 3.0.2 pom spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 51daaf149..cc0323008 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java index ca96e37b0..c9726fe60 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java @@ -114,4 +114,5 @@ public class MessageHeaderPropagatorGetter implements Propagator.Getter org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml index 895d61229..8fb704f19 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml index 470aea321..c78353932 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml index 83dcff828..0ad8c5f25 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml index 2a4fe52fb..7e810455d 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml index 876c93ce1..3d9d5063e 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml index 26571c0ec..afa1d02a2 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-sleuth-zipkin/pom.xml b/spring-cloud-sleuth-zipkin/pom.xml index f11729614..6421099ec 100644 --- a/spring-cloud-sleuth-zipkin/pom.xml +++ b/spring-cloud-sleuth-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/spring-cloud-starter-sleuth/pom.xml b/spring-cloud-starter-sleuth/pom.xml index 13f2e124f..f7b11b2db 100644 --- a/spring-cloud-starter-sleuth/pom.xml +++ b/spring-cloud-starter-sleuth/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. spring-cloud-starter-sleuth diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index ccf59fa70..763275d2d 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml index d321841ea..25aa20347 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml index 073eedb9f..261329309 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml index 2370f6da9..70f359cec 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java index d36135877..96dafebfe 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java @@ -63,9 +63,11 @@ public class MultipleHopsIntegrationTests // baz is not tagged in the initial span, only downstream! then(this.application.allSpans()).as("All downstream have country-code") .filteredOn(span -> !span.equals(initialSpan)) - // it propagates only and all the `spring.sleuth.baggage.remote-fields` in case insensitive way + // it propagates only and all the `spring.sleuth.baggage.remote-fields` in + // case insensitive way .allMatch(span -> "FO".equals(COUNTRY_CODE.getValue(BraveAccessor.traceContext(span.context())))) - .allMatch(span -> "123".equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) + .allMatch(span -> "123" + .equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) .allMatch(span -> NOT_PROPAGATED_HEADER.getValue(BraveAccessor.traceContext(span.context())) == null); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml index 098bc29b8..398ffb601 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml index a1a85169f..e15bf5d70 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml index 987711d66..577ac9b15 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml index 741cb5bce..d1ec762b1 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml index f9990c973..d8b2f7381 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml index 81ba8081a..56d694ce9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java index 7f0ce0993..c4ba0202e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java @@ -48,15 +48,11 @@ public class TracingChannelInterceptorTest this.testTracing = new BraveTestTracing() { @Override public Tracing.Builder tracingBuilder() { - return super.tracingBuilder() - .propagationFactory(BaggagePropagation.newFactoryBuilder(B3Propagation.newFactoryBuilder() - .injectFormat(SINGLE) - .build() - ) - .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) - .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) - .build() - ); + return super.tracingBuilder().propagationFactory(BaggagePropagation + .newFactoryBuilder(B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build()) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) + .build()); } }; this.testTracing.reset(); @@ -77,7 +73,7 @@ public class TracingChannelInterceptorTest TraceContext receiveContext = parseB3SingleFormat( ((List) ((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS)).get("b3")).get(0).toString()) - .context(); + .context(); assertThat(receiveContext.parentIdString()).isEqualTo("000000000000000b"); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml index 8c332e30b..56f3c5d15 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml index 70d15c0bd..99895b1dc 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml index 4d0df14c2..da4866809 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml index d6a27ca70..3fd87c2e8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml index c77afa4e8..753042c86 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml index 98c8eae83..4d6890c70 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml index 53a55d021..30f864a69 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/common/pom.xml b/tests/common/pom.xml index eefbe4201..4a2970ea9 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.2-SNAPSHOT + 3.0.2 .. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index d305300b9..ae6a36018 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -381,7 +381,8 @@ public abstract class TracingChannelInterceptorTest implements TestTracingAwareS Message actualMessage = channel.receive(); assertThat(actualMessage.getHeaders()).isNotEmpty(); - LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders().get(NATIVE_HEADERS); + LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders() + .get(NATIVE_HEADERS); assertThat(actualNativeHeaders).isNotEmpty(); assertThat(actualNativeHeaders.get("not-propagated-header")).isNull(); assertThat(actualNativeHeaders.get("Foo-Id")).isEqualTo(singletonList("123")); diff --git a/tests/pom.xml b/tests/pom.xml index 5e22d09e2..f9834ca05 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.2 .. From dfc5674ceab83afaf13bb90aadcdf0bf371012cf Mon Sep 17 00:00:00 2001 From: buildmaster Date: Wed, 17 Mar 2021 22:12:44 +0000 Subject: [PATCH 39/78] Going back to snapshots --- benchmarks/pom.xml | 4 +- docs/pom.xml | 2 +- pom.xml | 20 +- spring-cloud-sleuth-api/pom.xml | 2 +- spring-cloud-sleuth-autoconfigure/pom.xml | 2 +- spring-cloud-sleuth-brave/pom.xml | 2 +- .../.flattened-pom.xml | 224 ------------------ spring-cloud-sleuth-dependencies/pom.xml | 4 +- spring-cloud-sleuth-instrumentation/pom.xml | 2 +- .../MessageHeaderPropagatorGetter.java | 1 - spring-cloud-sleuth-samples/pom.xml | 2 +- .../spring-cloud-sleuth-sample-feign/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-sample-zipkin/pom.xml | 2 +- .../spring-cloud-sleuth-sample/pom.xml | 2 +- spring-cloud-sleuth-zipkin/pom.xml | 2 +- spring-cloud-starter-sleuth/pom.xml | 2 +- tests/brave/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../baggage/MultipleHopsIntegrationTests.java | 6 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../TracingChannelInterceptorTest.java | 16 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-zipkin-tests/pom.xml | 2 +- tests/common/pom.xml | 2 +- .../TracingChannelInterceptorTest.java | 3 +- tests/pom.xml | 2 +- 41 files changed, 60 insertions(+), 284 deletions(-) delete mode 100644 spring-cloud-sleuth-dependencies/.flattened-pom.xml diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index c20620fca..2e529b161 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -22,7 +22,7 @@ Benchmarks Benchmarks (JMH) org.springframework.cloud - 3.0.2 + 3.0.2-SNAPSHOT benchmarks @@ -41,7 +41,7 @@ 4.9.0 0.2.0.RELEASE 1.26 - 3.1.2 + 3.1.1-SNAPSHOT diff --git a/docs/pom.xml b/docs/pom.xml index edc16ecbf..03a3c3b77 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -21,7 +21,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT spring-cloud-sleuth-docs jar diff --git a/pom.xml b/pom.xml index 024e931c2..4f25baa78 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 4.0.0 spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT pom Spring Cloud Sleuth Spring Cloud Sleuth @@ -29,7 +29,7 @@ org.springframework.cloud spring-cloud-build - 3.0.2 + 3.0.2-SNAPSHOT @@ -62,14 +62,14 @@ 1.8 1.8 1.8 - 3.0.2 - 3.0.2 - 3.0.2 - 2.0.1 - 3.1.2 - 3.1.2 - 3.0.2 - 3.0.2 + 3.0.2-SNAPSHOT + 3.0.2-SNAPSHOT + 3.0.2-SNAPSHOT + 2.0.1-SNAPSHOT + 3.1.1-SNAPSHOT + 3.1.2-SNAPSHOT + 3.0.2-SNAPSHOT + 3.0.2-SNAPSHOT 5.13.2 0.32.0 2.3.4.RELEASE diff --git a/spring-cloud-sleuth-api/pom.xml b/spring-cloud-sleuth-api/pom.xml index 238ad194a..9fb4fbeb6 100644 --- a/spring-cloud-sleuth-api/pom.xml +++ b/spring-cloud-sleuth-api/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index c299ffde4..734ef1bd9 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-brave/pom.xml b/spring-cloud-sleuth-brave/pom.xml index 2b56f6ba4..80ab5d2b9 100644 --- a/spring-cloud-sleuth-brave/pom.xml +++ b/spring-cloud-sleuth-brave/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-dependencies/.flattened-pom.xml b/spring-cloud-sleuth-dependencies/.flattened-pom.xml deleted file mode 100644 index bd1d8cc5c..000000000 --- a/spring-cloud-sleuth-dependencies/.flattened-pom.xml +++ /dev/null @@ -1,224 +0,0 @@ - - - - 4.0.0 - - org.springframework.cloud - spring-cloud-dependencies-parent - 3.0.2 - - - org.springframework.cloud - spring-cloud-sleuth-dependencies - 3.0.2 - pom - spring-cloud-sleuth-dependencies - Spring Cloud Sleuth Dependencies - https://projects.spring.io/spring-cloud/spring-cloud-sleuth-dependencies/ - - Pivotal Software, Inc. - https://www.spring.io - - - - Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0 - Copyright 2014-2015 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 - - https://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. - - - - - dsyer - Dave Syer - dsyer at pivotal.io - Pivotal Software, Inc. - https://www.spring.io - - Project lead - - - - sgibb - Spencer Gibb - sgibb at pivotal.io - Pivotal Software, Inc. - https://www.spring.io - - Project lead - - - - - scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git - scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git - https://github.com/spring-cloud/spring-cloud-sleuth - - - - repo.spring.io - Spring Release Repository - https://repo.spring.io/libs-release-local - - - repo.spring.io - Spring Snapshot Repository - https://repo.spring.io/libs-snapshot-local - - - spring-docs - scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-cloud/docs/spring-cloud-dependencies-parent/3.0.2/spring-cloud-sleuth-dependencies - - https://github.com/spring-cloud - - - 0.37.4 - 4.2.2 - 5.13.2 - - - - - org.springframework.cloud - spring-cloud-sleuth-autoconfigure - ${project.version} - - - org.springframework.cloud - spring-cloud-sleuth-api - ${project.version} - - - org.springframework.cloud - spring-cloud-sleuth-instrumentation - ${project.version} - - - org.springframework.cloud - spring-cloud-sleuth-brave - ${project.version} - - - org.springframework.cloud - spring-cloud-sleuth-zipkin - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-sleuth - ${project.version} - - - org.springframework.cloud - spring-cloud-sleuth-tests-common - ${project.version} - - - io.zipkin.brave - brave-bom - ${brave.version} - pom - import - - - io.opentracing.brave - brave-opentracing - ${brave.opentracing.version} - - - * - io.zipkin.brave - - - - - io.github.lognet - grpc-spring-boot-starter - ${grpc.spring.boot.version} - - - - - - spring - - - - false - - - true - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - - - false - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - - - false - - spring-releases - Spring Releases - https://repo.spring.io/release - - - - - - false - - - true - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - - - false - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - - - - diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index d946db557..c5ecf9cbb 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -22,11 +22,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 3.0.2 + 3.0.2-SNAPSHOT spring-cloud-sleuth-dependencies - 3.0.2 + 3.0.2-SNAPSHOT pom spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index cc0323008..51daaf149 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java index c9726fe60..ca96e37b0 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java @@ -114,5 +114,4 @@ public class MessageHeaderPropagatorGetter implements Propagator.Getter org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml index 8fb704f19..895d61229 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml index c78353932..470aea321 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml index 0ad8c5f25..83dcff828 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml index 7e810455d..2a4fe52fb 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml index 3d9d5063e..876c93ce1 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml index afa1d02a2..26571c0ec 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-sleuth-zipkin/pom.xml b/spring-cloud-sleuth-zipkin/pom.xml index 6421099ec..f11729614 100644 --- a/spring-cloud-sleuth-zipkin/pom.xml +++ b/spring-cloud-sleuth-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/spring-cloud-starter-sleuth/pom.xml b/spring-cloud-starter-sleuth/pom.xml index f7b11b2db..13f2e124f 100644 --- a/spring-cloud-starter-sleuth/pom.xml +++ b/spring-cloud-starter-sleuth/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. spring-cloud-starter-sleuth diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index 763275d2d..ccf59fa70 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml index 25aa20347..d321841ea 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml index 261329309..073eedb9f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml index 70f359cec..2370f6da9 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java index 96dafebfe..d36135877 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/src/test/java/org/springframework/cloud/sleuth/brave/baggage/MultipleHopsIntegrationTests.java @@ -63,11 +63,9 @@ public class MultipleHopsIntegrationTests // baz is not tagged in the initial span, only downstream! then(this.application.allSpans()).as("All downstream have country-code") .filteredOn(span -> !span.equals(initialSpan)) - // it propagates only and all the `spring.sleuth.baggage.remote-fields` in - // case insensitive way + // it propagates only and all the `spring.sleuth.baggage.remote-fields` in case insensitive way .allMatch(span -> "FO".equals(COUNTRY_CODE.getValue(BraveAccessor.traceContext(span.context())))) - .allMatch(span -> "123" - .equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) + .allMatch(span -> "123".equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) .allMatch(span -> NOT_PROPAGATED_HEADER.getValue(BraveAccessor.traceContext(span.context())) == null); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml index 398ffb601..098bc29b8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml index e15bf5d70..a1a85169f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml index 577ac9b15..987711d66 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml index d1ec762b1..741cb5bce 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml index d8b2f7381..f9990c973 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml index 56d694ce9..81ba8081a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java index c4ba0202e..7f0ce0993 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java @@ -48,11 +48,15 @@ public class TracingChannelInterceptorTest this.testTracing = new BraveTestTracing() { @Override public Tracing.Builder tracingBuilder() { - return super.tracingBuilder().propagationFactory(BaggagePropagation - .newFactoryBuilder(B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build()) - .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) - .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) - .build()); + return super.tracingBuilder() + .propagationFactory(BaggagePropagation.newFactoryBuilder(B3Propagation.newFactoryBuilder() + .injectFormat(SINGLE) + .build() + ) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) + .build() + ); } }; this.testTracing.reset(); @@ -73,7 +77,7 @@ public class TracingChannelInterceptorTest TraceContext receiveContext = parseB3SingleFormat( ((List) ((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS)).get("b3")).get(0).toString()) - .context(); + .context(); assertThat(receiveContext.parentIdString()).isEqualTo("000000000000000b"); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml index 56f3c5d15..8c332e30b 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml index 99895b1dc..70d15c0bd 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml index da4866809..4d0df14c2 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml index 3fd87c2e8..d6a27ca70 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml index 753042c86..c77afa4e8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml index 4d6890c70..98c8eae83 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml index 30f864a69..53a55d021 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/common/pom.xml b/tests/common/pom.xml index 4a2970ea9..eefbe4201 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.2 + 3.0.2-SNAPSHOT .. diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index ae6a36018..d305300b9 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -381,8 +381,7 @@ public abstract class TracingChannelInterceptorTest implements TestTracingAwareS Message actualMessage = channel.receive(); assertThat(actualMessage.getHeaders()).isNotEmpty(); - LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders() - .get(NATIVE_HEADERS); + LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders().get(NATIVE_HEADERS); assertThat(actualNativeHeaders).isNotEmpty(); assertThat(actualNativeHeaders.get("not-propagated-header")).isNull(); assertThat(actualNativeHeaders.get("Foo-Id")).isEqualTo(singletonList("123")); diff --git a/tests/pom.xml b/tests/pom.xml index f9834ca05..5e22d09e2 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2 + 3.0.2-SNAPSHOT .. From d2c29938b8818c2e20391baf647dc809160d91aa Mon Sep 17 00:00:00 2001 From: buildmaster Date: Wed, 17 Mar 2021 22:12:44 +0000 Subject: [PATCH 40/78] Bumping versions to 3.0.3-SNAPSHOT after release --- benchmarks/pom.xml | 4 ++-- docs/pom.xml | 2 +- pom.xml | 20 +++++++++---------- spring-cloud-sleuth-api/pom.xml | 2 +- spring-cloud-sleuth-autoconfigure/pom.xml | 2 +- spring-cloud-sleuth-brave/pom.xml | 2 +- spring-cloud-sleuth-dependencies/pom.xml | 4 ++-- spring-cloud-sleuth-instrumentation/pom.xml | 2 +- spring-cloud-sleuth-samples/pom.xml | 2 +- .../spring-cloud-sleuth-sample-feign/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-sample-zipkin/pom.xml | 2 +- .../spring-cloud-sleuth-sample/pom.xml | 2 +- spring-cloud-sleuth-zipkin/pom.xml | 2 +- spring-cloud-starter-sleuth/pom.xml | 2 +- tests/brave/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-zipkin-tests/pom.xml | 2 +- tests/common/pom.xml | 2 +- tests/pom.xml | 2 +- 36 files changed, 47 insertions(+), 47 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 2e529b161..f10a42bed 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -22,7 +22,7 @@ Benchmarks Benchmarks (JMH) org.springframework.cloud - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT benchmarks @@ -41,7 +41,7 @@ 4.9.0 0.2.0.RELEASE 1.26 - 3.1.1-SNAPSHOT + 3.1.2 diff --git a/docs/pom.xml b/docs/pom.xml index 03a3c3b77..f300fba2f 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -21,7 +21,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT spring-cloud-sleuth-docs jar diff --git a/pom.xml b/pom.xml index 4f25baa78..c223e2c66 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 4.0.0 spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT pom Spring Cloud Sleuth Spring Cloud Sleuth @@ -29,7 +29,7 @@ org.springframework.cloud spring-cloud-build - 3.0.2-SNAPSHOT + 3.0.2 @@ -62,14 +62,14 @@ 1.8 1.8 1.8 - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT - 2.0.1-SNAPSHOT - 3.1.1-SNAPSHOT - 3.1.2-SNAPSHOT - 3.0.2-SNAPSHOT - 3.0.2-SNAPSHOT + 3.0.2 + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 2.0.2-SNAPSHOT + 3.1.2 + 3.1.2 + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT 5.13.2 0.32.0 2.3.4.RELEASE diff --git a/spring-cloud-sleuth-api/pom.xml b/spring-cloud-sleuth-api/pom.xml index 9fb4fbeb6..223117cbd 100644 --- a/spring-cloud-sleuth-api/pom.xml +++ b/spring-cloud-sleuth-api/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index 734ef1bd9..8486942a0 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-brave/pom.xml b/spring-cloud-sleuth-brave/pom.xml index 80ab5d2b9..c3bb99eaf 100644 --- a/spring-cloud-sleuth-brave/pom.xml +++ b/spring-cloud-sleuth-brave/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index c5ecf9cbb..b06455a46 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -22,11 +22,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT spring-cloud-sleuth-dependencies - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT pom spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 51daaf149..a2e0f6ad5 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/pom.xml b/spring-cloud-sleuth-samples/pom.xml index 2289a3b7a..55161d7bc 100644 --- a/spring-cloud-sleuth-samples/pom.xml +++ b/spring-cloud-sleuth-samples/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml index 895d61229..09402560f 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml index 470aea321..ca51608fd 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml index 83dcff828..5a68fc05d 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml index 2a4fe52fb..802007fed 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml index 876c93ce1..2f555a022 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml index 26571c0ec..c5a00b133 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-sleuth-zipkin/pom.xml b/spring-cloud-sleuth-zipkin/pom.xml index f11729614..289913b92 100644 --- a/spring-cloud-sleuth-zipkin/pom.xml +++ b/spring-cloud-sleuth-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/spring-cloud-starter-sleuth/pom.xml b/spring-cloud-starter-sleuth/pom.xml index 13f2e124f..bc574d2d2 100644 --- a/spring-cloud-starter-sleuth/pom.xml +++ b/spring-cloud-starter-sleuth/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. spring-cloud-starter-sleuth diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index ccf59fa70..9bf63fe26 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml index d321841ea..4582b2c81 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml index 073eedb9f..f2949de3e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml index 2370f6da9..cddc90def 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml index 098bc29b8..b2b6fbb9e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml index a1a85169f..7316615ab 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml index 987711d66..87542def1 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml index 741cb5bce..81c7a1911 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml index f9990c973..6e5a5261e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml index 81ba8081a..ce3d0c390 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml index 8c332e30b..6e497304f 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml index 70d15c0bd..8973c1d27 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml index 4d0df14c2..c1c392076 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml index d6a27ca70..5135bf12b 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml index c77afa4e8..83b00e163 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml index 98c8eae83..7b884de73 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml index 53a55d021..02bee2432 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/common/pom.xml b/tests/common/pom.xml index eefbe4201..fc31548be 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. diff --git a/tests/pom.xml b/tests/pom.xml index 5e22d09e2..df2f5dcf9 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT .. From bf467a9a15e5cda3bdeb3643d6d2904634fcbce1 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Thu, 18 Mar 2021 05:29:41 +0000 Subject: [PATCH 41/78] Bumping versions --- pom.xml | 4 ++-- spring-cloud-sleuth-dependencies/pom.xml | 2 +- .../messaging/MessageHeaderPropagatorGetter.java | 1 + .../baggage/MultipleHopsIntegrationTests.java | 6 ++++-- .../messaging/TracingChannelInterceptorTest.java | 16 ++++++---------- .../messaging/TracingChannelInterceptorTest.java | 3 ++- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index c223e2c66..bca0d4caa 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.springframework.cloud spring-cloud-build - 3.0.2 + 3.0.3-SNAPSHOT @@ -62,7 +62,7 @@ 1.8 1.8 1.8 - 3.0.2 + 3.0.3-SNAPSHOT 3.0.3-SNAPSHOT 3.0.3-SNAPSHOT 2.0.2-SNAPSHOT diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index b06455a46..1e06ac341 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -22,7 +22,7 @@ spring-cloud-dependencies-parent org.springframework.cloud - 3.0.3-SNAPSHOT + 3.0.2 spring-cloud-sleuth-dependencies diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java index ca96e37b0..c9726fe60 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/MessageHeaderPropagatorGetter.java @@ -114,4 +114,5 @@ public class MessageHeaderPropagatorGetter implements Propagator.Getter !span.equals(initialSpan)) - // it propagates only and all the `spring.sleuth.baggage.remote-fields` in case insensitive way + // it propagates only and all the `spring.sleuth.baggage.remote-fields` in + // case insensitive way .allMatch(span -> "FO".equals(COUNTRY_CODE.getValue(BraveAccessor.traceContext(span.context())))) - .allMatch(span -> "123".equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) + .allMatch(span -> "123" + .equalsIgnoreCase(CASE_INSENSITIVE_ID.getValue(BraveAccessor.traceContext(span.context())))) .allMatch(span -> NOT_PROPAGATED_HEADER.getValue(BraveAccessor.traceContext(span.context())) == null); } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java index 7f0ce0993..c4ba0202e 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TracingChannelInterceptorTest.java @@ -48,15 +48,11 @@ public class TracingChannelInterceptorTest this.testTracing = new BraveTestTracing() { @Override public Tracing.Builder tracingBuilder() { - return super.tracingBuilder() - .propagationFactory(BaggagePropagation.newFactoryBuilder(B3Propagation.newFactoryBuilder() - .injectFormat(SINGLE) - .build() - ) - .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) - .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) - .build() - ); + return super.tracingBuilder().propagationFactory(BaggagePropagation + .newFactoryBuilder(B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build()) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Foo-Id"))) + .add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("Baz-Id"))) + .build()); } }; this.testTracing.reset(); @@ -77,7 +73,7 @@ public class TracingChannelInterceptorTest TraceContext receiveContext = parseB3SingleFormat( ((List) ((Map) this.channel.receive().getHeaders().get(NATIVE_HEADERS)).get("b3")).get(0).toString()) - .context(); + .context(); assertThat(receiveContext.parentIdString()).isEqualTo("000000000000000b"); } diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index d305300b9..ae6a36018 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -381,7 +381,8 @@ public abstract class TracingChannelInterceptorTest implements TestTracingAwareS Message actualMessage = channel.receive(); assertThat(actualMessage.getHeaders()).isNotEmpty(); - LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders().get(NATIVE_HEADERS); + LinkedMultiValueMap actualNativeHeaders = (LinkedMultiValueMap) actualMessage.getHeaders() + .get(NATIVE_HEADERS); assertThat(actualNativeHeaders).isNotEmpty(); assertThat(actualNativeHeaders.get("not-propagated-header")).isNull(); assertThat(actualNativeHeaders.get("Foo-Id")).isEqualTo(singletonList("123")); From 7ad006b440147a284189b6bef3c53b24a4008d78 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 18 Mar 2021 13:35:47 +0100 Subject: [PATCH 42/78] Added support for netty-http-brave; fixes gh-1690 --- .../web/BraveHttpConfiguration.java | 16 +++++ .../cloud/sleuth/brave/bridge/BraveSpan.java | 8 +-- .../web/BraveSpanFromContextRetriever.java | 61 ++++++++++++++++++ .../BraveSpanFromContextRetrieverTests.java | 63 +++++++++++++++++++ .../web/SpanFromContextRetriever.java | 41 ++++++++++++ .../sleuth/instrument/web/TraceWebFilter.java | 24 ++++++- 6 files changed, 206 insertions(+), 7 deletions(-) create mode 100644 spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetriever.java create mode 100644 spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SpanFromContextRetriever.java diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java index 34facbe8f..5732b79b2 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpConfiguration.java @@ -21,12 +21,15 @@ import java.util.regex.Pattern; import javax.validation.constraints.NotNull; +import brave.Tracer; import brave.Tracing; import brave.http.HttpRequest; import brave.http.HttpTracing; import brave.http.HttpTracingCustomizer; +import brave.propagation.CurrentTraceContext; import brave.sampler.SamplerFunction; import brave.sampler.SamplerFunctions; +import reactor.util.context.Context; import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -38,6 +41,7 @@ import org.springframework.cloud.sleuth.autoconfig.instrument.web.SleuthWebPrope import org.springframework.cloud.sleuth.brave.bridge.BraveHttpRequestParser; import org.springframework.cloud.sleuth.brave.bridge.BraveHttpResponseParser; import org.springframework.cloud.sleuth.brave.bridge.BraveSamplerFunction; +import org.springframework.cloud.sleuth.brave.instrument.web.BraveSpanFromContextRetriever; import org.springframework.cloud.sleuth.brave.instrument.web.CompositeHttpSampler; import org.springframework.cloud.sleuth.brave.instrument.web.SkipPatternHttpClientSampler; import org.springframework.cloud.sleuth.brave.instrument.web.SkipPatternHttpServerSampler; @@ -50,6 +54,7 @@ import org.springframework.cloud.sleuth.instrument.web.HttpServerRequestParser; import org.springframework.cloud.sleuth.instrument.web.HttpServerResponseParser; import org.springframework.cloud.sleuth.instrument.web.HttpServerSampler; import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider; +import org.springframework.cloud.sleuth.instrument.web.SpanFromContextRetriever; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -205,4 +210,15 @@ public class BraveHttpConfiguration { return new SkipPatternHttpClientSampler(Pattern.compile(skipPattern)); } + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Context.class) + static class BraveWebFilterConfiguration { + + @Bean + SpanFromContextRetriever braveSpanFromContextRetriever(CurrentTraceContext currentTraceContext, Tracer tracer) { + return new BraveSpanFromContextRetriever(currentTraceContext, tracer); + } + + } + } diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java index 3525029eb..15b977be7 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java @@ -27,11 +27,11 @@ import org.springframework.cloud.sleuth.TraceContext; * @author Marcin Grzejszczak * @since 3.0.0 */ -class BraveSpan implements Span { +public class BraveSpan implements Span { final brave.Span delegate; - BraveSpan(brave.Span delegate) { + public BraveSpan(brave.Span delegate) { this.delegate = delegate; } @@ -91,11 +91,11 @@ class BraveSpan implements Span { return this.delegate != null ? this.delegate.toString() : "null"; } - static brave.Span toBrave(Span span) { + public static brave.Span toBrave(Span span) { return ((BraveSpan) span).delegate; } - static Span fromBrave(brave.Span span) { + public static Span fromBrave(brave.Span span) { return new BraveSpan(span); } diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetriever.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetriever.java new file mode 100644 index 000000000..a2107fcd3 --- /dev/null +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetriever.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.web; + +import brave.Tracer; +import brave.propagation.CurrentTraceContext; +import brave.propagation.TraceContext; +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.brave.bridge.BraveSpan; +import org.springframework.cloud.sleuth.instrument.web.SpanFromContextRetriever; + +/** + * Retrieves Brave specific classes from Reactor context. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public class BraveSpanFromContextRetriever implements SpanFromContextRetriever { + + private final CurrentTraceContext currentTraceContext; + + private final Tracer tracer; + + public BraveSpanFromContextRetriever(CurrentTraceContext currentTraceContext, Tracer tracer) { + this.currentTraceContext = currentTraceContext; + this.tracer = tracer; + } + + @Override + public Span findSpan(Context context) { + Object braveSpan = context.getOrDefault(brave.Span.class, null); + if (braveSpan != null) { + return BraveSpan.fromBrave((brave.Span) braveSpan); + } + Object braveContext = context.getOrDefault(TraceContext.class, null); + if (braveContext != null) { + TraceContext traceContext = (TraceContext) braveContext; + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(traceContext)) { + return BraveSpan.fromBrave(this.tracer.currentSpan()); + } + } + return null; + } + +} diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java new file mode 100644 index 000000000..c8bf0265d --- /dev/null +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.web; + +import brave.Span; +import brave.Tracing; +import brave.propagation.StrictCurrentTraceContext; +import brave.propagation.TraceContext; +import brave.sampler.Sampler; +import brave.test.TestSpanHandler; +import org.junit.jupiter.api.Test; +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.brave.bridge.BraveSpan; + +import static org.assertj.core.api.BDDAssertions.then; + +class BraveSpanFromContextRetrieverTests { + + TestSpanHandler spans = new TestSpanHandler(); + + StrictCurrentTraceContext traceContext = StrictCurrentTraceContext.create(); + + Tracing tracing = Tracing.newBuilder().currentTraceContext(this.traceContext) + .sampler(Sampler.ALWAYS_SAMPLE).addSpanHandler(this.spans).build(); + + brave.Tracer tracer = this.tracing.tracer(); + + BraveSpanFromContextRetriever retriever = new BraveSpanFromContextRetriever(this.traceContext, this.tracer); + + @Test + void should_return_null_when_no_brave_specific_entries_are_present_in_context() { + then(retriever.findSpan(Context.empty())).isNull(); + } + + @Test + void should_return_span_when_brave_span_present_in_context() { + Span span = this.tracer.nextSpan(); + + then(BraveSpan.toBrave(retriever.findSpan(Context.of(Span.class, span)))).isSameAs(span); + } + + @Test + void should_return_span_when_brave_trace_context_present_in_context() { + Span span = this.tracer.nextSpan(); + + then(BraveSpan.toBrave(retriever.findSpan(Context.of(TraceContext.class, span.context())))).isEqualTo(span); + } +} \ No newline at end of file diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SpanFromContextRetriever.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SpanFromContextRetriever.java new file mode 100644 index 000000000..6a7d3f3ba --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/SpanFromContextRetriever.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.web; + +import java.util.regex.Pattern; + +import reactor.util.context.Context; + +import org.springframework.cloud.sleuth.Span; + +/** + * Provides a URL {@link Pattern} for spans that should be not sampled. + * + * @author Marcin Grzejszczak + * @since 3.0.2 + */ +public interface SpanFromContextRetriever { + + /** + * @param context - Reactor context + * @return span or {@code null} if no span present + */ + default Span findSpan(Context context) { + return null; + }; + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java index 84bdb6788..4fb8edd66 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java @@ -81,6 +81,8 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa private int order; + private SpanFromContextRetriever spanFromContextRetriever; + @Deprecated public TraceWebFilter(Tracer tracer, HttpServerHandler handler) { this.tracer = tracer; @@ -102,7 +104,7 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa if (log.isDebugEnabled()) { log.debug("Received a request to uri [" + uri + "]"); } - return new MonoWebFilterTrace(source, exchange, tracePresent, this); + return new MonoWebFilterTrace(source, exchange, tracePresent, this, spanFromContextRetriever()); } private boolean isTracePresent() { @@ -135,6 +137,15 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa return this.currentTraceContext; } + private SpanFromContextRetriever spanFromContextRetriever() { + if (this.spanFromContextRetriever == null) { + this.spanFromContextRetriever = this.applicationContext.getBeanProvider(SpanFromContextRetriever.class) + .getIfAvailable(() -> new SpanFromContextRetriever() { + }); + } + return this.spanFromContextRetriever; + } + private static class MonoWebFilterTrace extends MonoOperator implements TraceContextPropagator { final ServerWebExchange exchange; @@ -151,8 +162,10 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa final CurrentTraceContext currentTraceContext; + final SpanFromContextRetriever spanFromContextRetriever; + MonoWebFilterTrace(Mono source, ServerWebExchange exchange, boolean initialTracePresent, - TraceWebFilter parent) { + TraceWebFilter parent, SpanFromContextRetriever spanFromContextRetriever) { super(source); this.tracer = parent.tracer; this.handler = parent.handler; @@ -160,6 +173,7 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa this.exchange = exchange; this.span = exchange.getAttribute(TRACE_REQUEST_ATTR); this.initialTracePresent = initialTracePresent; + this.spanFromContextRetriever = spanFromContextRetriever; } @Override @@ -207,12 +221,16 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa log.debug("Found span in attribute " + span); } } - else { + span = this.spanFromContextRetriever.findSpan(c); + if (this.span == null && span == null) { span = this.handler.handleReceive(new WrappedRequest(this.exchange.getRequest())); if (log.isDebugEnabled()) { log.debug("Handled receive of span " + span); } } + else if (log.isDebugEnabled()) { + log.debug("Found tracer specific span in reactor context [" + span + "]"); + } this.exchange.getAttributes().put(TRACE_REQUEST_ATTR, span); } return span; From fcd85362dd5d38f8b44c9ddfdfdb8820fb2bb849 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 18 Mar 2021 17:25:47 +0100 Subject: [PATCH 43/78] Reuses configuration from the given propagation type; fixes gh-1846 --- .../web/SkipPatternConfiguration.java | 2 + .../CompositePropagationFactoryTests.java | 80 ++++++++++ .../CompositePropagationFactorySupplier.java | 140 +++++++++++++++--- ...positePropagationFactorySupplierTests.java | 2 + .../BraveSpanFromContextRetrieverTests.java | 7 +- .../MessagingApplicationTests.java | 30 ++-- 6 files changed, 224 insertions(+), 37 deletions(-) create mode 100644 spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CompositePropagationFactoryTests.java diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java index f910c767c..49dc59cf6 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternConfiguration.java @@ -200,6 +200,7 @@ class SkipPatternConfiguration { @Bean @ConditionalOnManagementPort(ManagementPortType.SAME) + @ConditionalOnBean(WebEndpointProperties.class) SingleSkipPattern skipPatternForActuatorEndpointsSamePort(Environment environment, final ServerProperties serverProperties, final WebEndpointProperties webEndpointProperties, final EndpointsSupplier endpointsSupplier) { @@ -211,6 +212,7 @@ class SkipPatternConfiguration { @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) @ConditionalOnProperty(name = "management.server.servlet.context-path", havingValue = "/", matchIfMissing = true) + @ConditionalOnBean(WebEndpointProperties.class) SingleSkipPattern skipPatternForActuatorEndpointsDifferentPort(Environment environment, final WebEndpointProperties webEndpointProperties, ObjectProvider managementServerProperties, diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CompositePropagationFactoryTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CompositePropagationFactoryTests.java new file mode 100644 index 000000000..08076e397 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/baggage/CompositePropagationFactoryTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.brave.baggage; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.cloud.sleuth.DisableWebFluxSecurity; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration; +import org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebAutoConfiguration; +import org.springframework.context.annotation.Import; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.hamcrest.core.IsEqual.equalTo; + +@WebFluxTest(controllers = TracingResource.class, properties = "spring.main.web-application-type=reactive") +@ImportAutoConfiguration({ BraveAutoConfiguration.class, TraceWebAutoConfiguration.class, + TraceReactorAutoConfiguration.class }) +@Import(TracingResource.class) +@DisableWebFluxSecurity +public class CompositePropagationFactoryTests { + + @Autowired + TracingResource tracingResource; + + @Test + void should_delegate_configuration_to_propagation_factory(@Autowired WebTestClient webTestClient) { + // issue 1846 - without the fix supportJoin is assumed to be false + // because it's not taken from the configuration but from not overridden + // methods from CompositePropagationFactorySupplier + String spanId = "a2fb4a1d1a96d312"; + webTestClient.get().uri("/api/tracing/spanId").header("X-B3-TraceId", "463ac35c9f6413ad48485a3953bb6124") + .header("X-B3-SpanId", spanId).header("X-B3-ParentSpanId", "0020000000000001").header("X-B3-Flags", "1") + .exchange().expectStatus().isOk().expectBody(String.class) + .value(returnedSpanId -> returnedSpanId, equalTo(spanId)); + + } + +} + +@RestController +@RequestMapping("/api/tracing") +class TracingResource { + + private static final Class KEY = TraceContext.class; + + @GetMapping("spanId") + public Mono spanId() { + return Mono.deferContextual(view -> traceContext(view)).map(c -> c.spanId()); + + } + + private Mono traceContext(ContextView contextView) { + return Mono.justOrEmpty(contextView.get(KEY)); + } + +} diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java index 167ccce25..269dedef2 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplier.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.brave.bridge; +import java.util.AbstractMap; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -66,32 +67,43 @@ public class CompositePropagationFactorySupplier implements PropagationFactorySu class CompositePropagationFactory extends Propagation.Factory implements Propagation { - private final Map> mapping = new HashMap<>(); + private final Map>> mapping = new HashMap<>(); private final List types; CompositePropagationFactory(BeanFactory beanFactory, BraveBaggageManager braveBaggageManager, List localFields, List types) { this.types = types; - this.mapping.put(PropagationType.AWS, AWSPropagation.FACTORY.get()); + this.mapping.put(PropagationType.AWS, + new AbstractMap.SimpleEntry<>(AWSPropagation.FACTORY, AWSPropagation.FACTORY.get())); // Note: Versions <2.2.3 use injectFormat(MULTI) for non-remote (ex // spring-messaging) // See #1643 - this.mapping.put(PropagationType.B3, - B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build().get()); - this.mapping.put(PropagationType.W3C, new W3CPropagation(braveBaggageManager, localFields)); - this.mapping.put(PropagationType.CUSTOM, new LazyPropagation(beanFactory.getBeanProvider(Propagation.class))); + Factory b3Factory = b3Factory(); + this.mapping.put(PropagationType.B3, new AbstractMap.SimpleEntry<>(b3Factory, b3Factory.get())); + W3CPropagation w3CPropagation = new W3CPropagation(braveBaggageManager, localFields); + this.mapping.put(PropagationType.W3C, new AbstractMap.SimpleEntry<>(w3CPropagation, w3CPropagation.get())); + LazyPropagationFactory lazyPropagationFactory = new LazyPropagationFactory( + beanFactory.getBeanProvider(Factory.class)); + this.mapping.put(PropagationType.CUSTOM, + new AbstractMap.SimpleEntry<>(lazyPropagationFactory, lazyPropagationFactory.get())); + } + + private Factory b3Factory() { + return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build(); } @Override public List keys() { - return this.types.stream().map(this.mapping::get).flatMap(p -> p.keys().stream()).collect(Collectors.toList()); + return this.types.stream().map(this.mapping::get).flatMap(p -> p.getValue().keys().stream()) + .collect(Collectors.toList()); } @Override public TraceContext.Injector injector(Setter setter) { return (traceContext, request) -> { - this.types.stream().map(this.mapping::get).forEach(p -> p.injector(setter).inject(traceContext, request)); + this.types.stream().map(this.mapping::get) + .forEach(p -> p.getValue().injector(setter).inject(traceContext, request)); }; } @@ -99,7 +111,11 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga public TraceContext.Extractor extractor(Getter getter) { return request -> { for (PropagationType type : this.types) { - Propagation propagator = this.mapping.get(type); + Map.Entry> entry = this.mapping.get(type); + if (entry == null) { + continue; + } + Propagation propagator = entry.getValue(); if (propagator == null || propagator == NoOpPropagation.INSTANCE) { continue; } @@ -117,33 +133,112 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga return StringPropagationAdapter.create(this, keyFactory); } + @Override + public boolean supportsJoin() { + return this.types.stream().map(this.mapping::get).allMatch(e -> e.getKey().supportsJoin()); + } + + @Override + public boolean requires128BitTraceId() { + return this.types.stream().map(this.mapping::get).allMatch(e -> e.getKey().requires128BitTraceId()); + } + + @Override + public TraceContext decorate(TraceContext context) { + for (PropagationType type : this.types) { + Map.Entry> entry = this.mapping.get(type); + if (entry == null) { + continue; + } + TraceContext decorate = entry.getKey().decorate(context); + if (decorate != context) { + return decorate; + } + } + return super.decorate(context); + } + @SuppressWarnings("unchecked") - private static final class LazyPropagation implements Propagation { + private static final class LazyPropagationFactory extends Propagation.Factory { - private final ObjectProvider delegate; + private final ObjectProvider delegate; - private LazyPropagation(ObjectProvider delegate) { + private volatile Propagation.Factory propagationFactory; + + private LazyPropagationFactory(ObjectProvider delegate) { this.delegate = delegate; } - @Override - public List keys() { - return this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE).keys(); + private Propagation.Factory propagationFactory() { + if (this.propagationFactory == null) { + this.propagationFactory = this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE); + } + return this.propagationFactory; } @Override - public TraceContext.Injector injector(Setter setter) { - return this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE).injector(setter); + public Propagation create(KeyFactory keyFactory) { + return propagationFactory().create(keyFactory); } @Override - public TraceContext.Extractor extractor(Getter getter) { - return this.delegate.getIfAvailable(() -> NoOpPropagation.INSTANCE).extractor(getter); + public boolean supportsJoin() { + return propagationFactory().supportsJoin(); + } + + @Override + public boolean requires128BitTraceId() { + return propagationFactory().requires128BitTraceId(); + } + + @Override + public Propagation get() { + return new LazyPropagation(this); + } + + @Override + public TraceContext decorate(TraceContext context) { + return propagationFactory().decorate(context); } } - private static class NoOpPropagation implements Propagation { + @SuppressWarnings("unchecked") + private static final class LazyPropagation implements Propagation { + + private final LazyPropagationFactory delegate; + + private volatile Propagation propagation; + + private LazyPropagation(LazyPropagationFactory delegate) { + this.delegate = delegate; + } + + private Propagation propagation() { + if (this.propagation == null) { + this.propagation = this.delegate.propagationFactory().get(); + } + return this.propagation; + } + + @Override + public List keys() { + return propagation().keys(); + } + + @Override + public TraceContext.Injector injector(Setter setter) { + return propagation().injector(setter); + } + + @Override + public TraceContext.Extractor extractor(Getter getter) { + return propagation().extractor(getter); + } + + } + + private static class NoOpPropagation extends Propagation.Factory implements Propagation { static final NoOpPropagation INSTANCE = new NoOpPropagation(); @@ -164,6 +259,11 @@ class CompositePropagationFactory extends Propagation.Factory implements Propaga return request -> TraceContextOrSamplingFlags.EMPTY; } + @Override + public Propagation create(KeyFactory keyFactory) { + return StringPropagationAdapter.create(this, keyFactory); + } + } } diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java index 1884a69a1..236bf90d7 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/CompositePropagationFactorySupplierTests.java @@ -41,6 +41,8 @@ class CompositePropagationFactorySupplierTests { BeanFactory beanFactory = Mockito.mock(BeanFactory.class); Mockito.when(beanFactory.getBeanProvider(BraveBaggageManager.class)) .thenReturn(new SimpleObjectProvider(new BraveBaggageManager())); + Mockito.when(beanFactory.getBeanProvider(Propagation.Factory.class)) + .thenReturn(new SimpleObjectProvider(new CustomTracePropagation())); Mockito.when(beanFactory.getBeanProvider(Propagation.class)) .thenReturn(new SimpleObjectProvider(new CustomTracePropagation())); diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java index c8bf0265d..5a5eea915 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/BraveSpanFromContextRetrieverTests.java @@ -35,8 +35,8 @@ class BraveSpanFromContextRetrieverTests { StrictCurrentTraceContext traceContext = StrictCurrentTraceContext.create(); - Tracing tracing = Tracing.newBuilder().currentTraceContext(this.traceContext) - .sampler(Sampler.ALWAYS_SAMPLE).addSpanHandler(this.spans).build(); + Tracing tracing = Tracing.newBuilder().currentTraceContext(this.traceContext).sampler(Sampler.ALWAYS_SAMPLE) + .addSpanHandler(this.spans).build(); brave.Tracer tracer = this.tracing.tracer(); @@ -60,4 +60,5 @@ class BraveSpanFromContextRetrieverTests { then(BraveSpan.toBrave(retriever.findSpan(Context.of(TraceContext.class, span.context())))).isEqualTo(span); } -} \ No newline at end of file + +} diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java index bbe5cc46c..15b06e31a 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java @@ -16,6 +16,7 @@ package integration; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -107,16 +108,19 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private void thenThereIsAtLeastOneTagWithKey(String key) { - then(this.testSpanHandler.spans.stream().map(MutableSpan::tags).flatMap(m -> m.keySet().stream()) - .anyMatch(b -> b.equals(key))).isTrue(); + then(spans().stream().map(MutableSpan::tags).flatMap(m -> m.keySet().stream()).anyMatch(b -> b.equals(key))) + .isTrue(); + } + + private List spans() { + return new ArrayList<>(this.testSpanHandler.spans); } private void thenAllSpansHaveTraceIdEqualTo(long traceId) { String traceIdHex = Long.toHexString(traceId); - log.info("Stored spans: [\n" - + this.testSpanHandler.spans.stream().map(MutableSpan::toString).collect(Collectors.joining("\n")) + log.info("Stored spans: [\n" + spans().stream().map(MutableSpan::toString).collect(Collectors.joining("\n")) + "\n]"); - then(this.testSpanHandler.spans.stream().filter(span -> !span.traceId().equals(SpanUtil.idToHex(traceId))) + then(spans().stream().filter(span -> !span.traceId().equals(SpanUtil.idToHex(traceId))) .collect(Collectors.toList())).describedAs("All spans have same trace id [" + traceIdHex + "]") .isEmpty(); } @@ -130,8 +134,8 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { // "http:/parent/" -> "message:messages" -> "http:/foo" (CS + CR) -> "http:/foo" // (SS) thenAllSpansArePresent(firstHttpSpan, eventSpans, lastHttpSpansParent, eventSentSpan, producerSpan); - List spans = this.testSpanHandler.spans; - then(spans).as("There were 7 spans").hasSize(7); + List spans = spans(); + then(spans).as("There were 6 spans").hasSize(6); log.info("Checking the parent child structure"); List> parentChild = spans.stream().filter(span -> span.parentId() != null).map(span -> { Optional any = spans.stream().filter(span1 -> span1.id().equals(span.parentId())).findAny(); @@ -146,21 +150,20 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private Optional findLastHttpSpansParent() { - return this.testSpanHandler.spans.stream().filter(span -> "GET /".equals(span.name()) && span.kind() != null) - .findFirst(); + return spans().stream().filter(span -> "GET /".equals(span.name()) && span.kind() != null).findFirst(); } private Optional findSpanWithKind(Span.Kind kind) { - return this.testSpanHandler.spans.stream().filter(span -> kind.equals(span.kind())).findFirst(); + return spans().stream().filter(span -> kind.equals(span.kind())).findFirst(); } private List findAllEventRelatedSpans() { - return this.testSpanHandler.spans.stream().filter(span -> "send".equals(span.name()) && span.parentId() != null) + return spans().stream().filter(span -> "send".equals(span.name()) && span.parentId() != null) .collect(Collectors.toList()); } private Optional findFirstHttpRequestSpan() { - return this.testSpanHandler.spans.stream() + return spans().stream() // home is the name of the method .filter(span -> span.tags().values().stream().anyMatch("home"::equals)).findFirst(); } @@ -174,8 +177,7 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { log.info("Event sent span " + eventSentSpan); log.info("Event received span " + eventReceivedSpan); log.info("Last http span " + lastHttpSpan); - log.info("All found spans \n" - + this.testSpanHandler.spans.stream().map(MutableSpan::toString).collect(Collectors.joining("\n"))); + log.info("All found spans \n" + spans().stream().map(MutableSpan::toString).collect(Collectors.joining("\n"))); then(firstHttpSpan.isPresent()).isTrue(); then(eventSpans).isNotEmpty(); then(eventSentSpan.isPresent()).isTrue(); From 40c3ff9abc56a42808ce95e7d43ea72cca8c71be Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Thu, 18 Mar 2021 19:30:40 -0400 Subject: [PATCH 44/78] Aligning Sleuth docs with rest of the projects --- docs/src/main/asciidoc/_index.adoc | 18 ------------------ docs/src/main/asciidoc/_index_pdf.adoc | 13 ------------- docs/src/main/asciidoc/_index_single.adoc | 14 -------------- docs/src/main/asciidoc/index.adoc | 1 + docs/src/main/asciidoc/index.htmladoc | 2 +- docs/src/main/asciidoc/index.htmlsingleadoc | 2 +- docs/src/main/asciidoc/index.pdfadoc | 1 + .../main/asciidoc/spring-cloud-sleuth.adoc | 19 ++++++++++++++++++- .../spring-cloud-sleuth.htmlsingleadoc | 15 ++++++++++++++- .../main/asciidoc/spring-cloud-sleuth.pdfadoc | 14 +++++++++++++- 10 files changed, 49 insertions(+), 50 deletions(-) delete mode 100644 docs/src/main/asciidoc/_index.adoc delete mode 100644 docs/src/main/asciidoc/_index_pdf.adoc delete mode 100644 docs/src/main/asciidoc/_index_single.adoc create mode 120000 docs/src/main/asciidoc/index.adoc mode change 100644 => 120000 docs/src/main/asciidoc/index.htmladoc mode change 100644 => 120000 docs/src/main/asciidoc/index.htmlsingleadoc create mode 120000 docs/src/main/asciidoc/index.pdfadoc mode change 120000 => 100644 docs/src/main/asciidoc/spring-cloud-sleuth.adoc mode change 120000 => 100644 docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc diff --git a/docs/src/main/asciidoc/_index.adoc b/docs/src/main/asciidoc/_index.adoc deleted file mode 100644 index d0a241950..000000000 --- a/docs/src/main/asciidoc/_index.adoc +++ /dev/null @@ -1,18 +0,0 @@ -[[spring-cloud-sleuth-reference-documentation]] -= Spring Cloud Sleuth Reference Documentation -Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant - -:docinfo: shared -include::_attributes.adoc[] - -The reference documentation consists of the following sections: - -[horizontal] -<> :: Legal information. -<> :: About the Documentation, Getting Help, First Steps, and more. -<> :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application -<> :: {project-full-name} usage examples and workflows. -<> :: Span creation, context propagation, and more. -<> :: Add sampling, propagate remote tags, and more. -<> :: Instrumentation configuration, context propagation, and more. -<> :: Configuration properties. diff --git a/docs/src/main/asciidoc/_index_pdf.adoc b/docs/src/main/asciidoc/_index_pdf.adoc deleted file mode 100644 index e1edcb891..000000000 --- a/docs/src/main/asciidoc/_index_pdf.adoc +++ /dev/null @@ -1,13 +0,0 @@ -[[spring-cloud-sleuth-reference-documentation]] -= Spring Cloud Sleuth Reference Documentation -Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant - -include::_attributes.adoc[] - -include::legal.adoc[leveloffset=+1] -include::getting-started.adoc[leveloffset=+1] -include::using.adoc[leveloffset=+1] -include::project-features.adoc[leveloffset=+1] -include::howto.adoc[leveloffset=+1] -include::integrations.adoc[leveloffset=+1] -include::appendix.adoc[leveloffset=+1] diff --git a/docs/src/main/asciidoc/_index_single.adoc b/docs/src/main/asciidoc/_index_single.adoc deleted file mode 100644 index 741b91da1..000000000 --- a/docs/src/main/asciidoc/_index_single.adoc +++ /dev/null @@ -1,14 +0,0 @@ -[[spring-cloud-sleuth-reference-documentation]] -= Spring Cloud Sleuth Reference Documentation -Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant - -:docinfo: shared -include::_attributes.adoc[] - -include::legal.adoc[leveloffset=+1] -include::getting-started.adoc[leveloffset=+1] -include::using.adoc[leveloffset=+1] -include::project-features.adoc[leveloffset=+1] -include::howto.adoc[leveloffset=+1] -include::integrations.adoc[leveloffset=+1] -include::appendix.adoc[leveloffset=+1] \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc new file mode 120000 index 000000000..2ab5e96e8 --- /dev/null +++ b/docs/src/main/asciidoc/index.adoc @@ -0,0 +1 @@ +spring-cloud-sleuth.adoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmladoc b/docs/src/main/asciidoc/index.htmladoc deleted file mode 100644 index c674268b6..000000000 --- a/docs/src/main/asciidoc/index.htmladoc +++ /dev/null @@ -1 +0,0 @@ -include::_index.adoc[] \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmladoc b/docs/src/main/asciidoc/index.htmladoc new file mode 120000 index 000000000..2ab5e96e8 --- /dev/null +++ b/docs/src/main/asciidoc/index.htmladoc @@ -0,0 +1 @@ +spring-cloud-sleuth.adoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmlsingleadoc b/docs/src/main/asciidoc/index.htmlsingleadoc deleted file mode 100644 index 67d39bee3..000000000 --- a/docs/src/main/asciidoc/index.htmlsingleadoc +++ /dev/null @@ -1 +0,0 @@ -include::_index_single.adoc[] \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.htmlsingleadoc b/docs/src/main/asciidoc/index.htmlsingleadoc new file mode 120000 index 000000000..f8d93d10b --- /dev/null +++ b/docs/src/main/asciidoc/index.htmlsingleadoc @@ -0,0 +1 @@ +spring-cloud-sleuth.htmlsingleadoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/index.pdfadoc b/docs/src/main/asciidoc/index.pdfadoc new file mode 120000 index 000000000..d4beca5b9 --- /dev/null +++ b/docs/src/main/asciidoc/index.pdfadoc @@ -0,0 +1 @@ +spring-cloud-sleuth.pdfadoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc deleted file mode 120000 index 1abdb4fda..000000000 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc +++ /dev/null @@ -1 +0,0 @@ -index.htmladoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc new file mode 100644 index 000000000..d0a241950 --- /dev/null +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc @@ -0,0 +1,18 @@ +[[spring-cloud-sleuth-reference-documentation]] += Spring Cloud Sleuth Reference Documentation +Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant + +:docinfo: shared +include::_attributes.adoc[] + +The reference documentation consists of the following sections: + +[horizontal] +<> :: Legal information. +<> :: About the Documentation, Getting Help, First Steps, and more. +<> :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application +<> :: {project-full-name} usage examples and workflows. +<> :: Span creation, context propagation, and more. +<> :: Add sampling, propagate remote tags, and more. +<> :: Instrumentation configuration, context propagation, and more. +<> :: Configuration properties. diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc b/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc deleted file mode 120000 index edc86da18..000000000 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc +++ /dev/null @@ -1 +0,0 @@ -index.htmlsingleadoc \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc b/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc new file mode 100644 index 000000000..741b91da1 --- /dev/null +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.htmlsingleadoc @@ -0,0 +1,14 @@ +[[spring-cloud-sleuth-reference-documentation]] += Spring Cloud Sleuth Reference Documentation +Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant + +:docinfo: shared +include::_attributes.adoc[] + +include::legal.adoc[leveloffset=+1] +include::getting-started.adoc[leveloffset=+1] +include::using.adoc[leveloffset=+1] +include::project-features.adoc[leveloffset=+1] +include::howto.adoc[leveloffset=+1] +include::integrations.adoc[leveloffset=+1] +include::appendix.adoc[leveloffset=+1] \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc b/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc index 572640be0..e1edcb891 100644 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.pdfadoc @@ -1 +1,13 @@ -include::_index_pdf.adoc[] \ No newline at end of file +[[spring-cloud-sleuth-reference-documentation]] += Spring Cloud Sleuth Reference Documentation +Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant + +include::_attributes.adoc[] + +include::legal.adoc[leveloffset=+1] +include::getting-started.adoc[leveloffset=+1] +include::using.adoc[leveloffset=+1] +include::project-features.adoc[leveloffset=+1] +include::howto.adoc[leveloffset=+1] +include::integrations.adoc[leveloffset=+1] +include::appendix.adoc[leveloffset=+1] From 1ff755d5645979a2a79728157ce209056e6913cf Mon Sep 17 00:00:00 2001 From: buildmaster Date: Fri, 19 Mar 2021 05:30:02 +0000 Subject: [PATCH 45/78] Bumping versions --- benchmarks/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index f10a42bed..27efc7a67 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -28,7 +28,7 @@ org.springframework.boot spring-boot-starter-parent - 2.4.3 + 2.4.4 From 7ef8f3886af61263b7811df1283c5091a469266b Mon Sep 17 00:00:00 2001 From: Jonatan Ivanov Date: Mon, 22 Mar 2021 11:39:31 -0700 Subject: [PATCH 46/78] Call out simple and Java for the sample in bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index aeafef9d3..215934a9a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,6 +12,6 @@ Please provide details of the problem, including the version of Spring Cloud tha are using. **Sample** -If possible, please provide a test case or sample application that reproduces +If possible, please provide a test case or a minimal sample **Java** application that reproduces the problem. This makes it much easier for us to diagnose the problem and to verify that we have fixed it. From 3b3bdfd31e3c745868e7895da5a7e657f34bff32 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Fri, 26 Mar 2021 13:07:27 -0400 Subject: [PATCH 47/78] Moves stream/fn to 3.1.3-SNAPSHOT and removes management of reactive mongo driver in favor of boot. --- pom.xml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index bca0d4caa..9b3809505 100644 --- a/pom.xml +++ b/pom.xml @@ -66,8 +66,8 @@ 3.0.3-SNAPSHOT 3.0.3-SNAPSHOT 2.0.2-SNAPSHOT - 3.1.2 - 3.1.2 + 3.1.3-SNAPSHOT + 3.1.3-SNAPSHOT 3.0.3-SNAPSHOT 3.0.3-SNAPSHOT 5.13.2 @@ -90,7 +90,6 @@ 4.0.3 0.21.3 0.14.1 - 4.0.0 @@ -278,11 +277,6 @@ archunit-junit5 ${archunit-junit5.version} - - org.mongodb - mongodb-driver-reactivestreams - ${mongodb-driver-reactivestreams.version} - From 3fc6c43c0521baabfb7417f36987ef69af6ab321 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Fri, 26 Mar 2021 14:18:26 -0400 Subject: [PATCH 48/78] Adds stream versions in specific locations --- benchmarks/pom.xml | 2 +- spring-cloud-sleuth-autoconfigure/pom.xml | 2 ++ spring-cloud-sleuth-instrumentation/pom.xml | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 27efc7a67..e0b4c0ef9 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -41,7 +41,7 @@ 4.9.0 0.2.0.RELEASE 1.26 - 3.1.2 + 3.1.3-SNAPSHOT diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index 8486942a0..a934b5b15 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -86,6 +86,8 @@ org.springframework.cloud spring-cloud-stream + + ${spring-cloud-stream.version} true diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index a2e0f6ad5..0b4f970a9 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -85,6 +85,8 @@ org.springframework.cloud spring-cloud-stream + + ${spring-cloud-stream.version} true From dad3d80408094bc842edfa36cf60c4e4a7448569 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 29 Mar 2021 14:12:04 +0200 Subject: [PATCH 49/78] Allows overriding of the default logging pattern fixes gh-1863 --- README.adoc | 54 +++++++- docs/src/main/asciidoc/_configprops.adoc | 115 +++++++++--------- .../main/asciidoc/spring-cloud-sleuth.adoc | 4 + .../TraceEnvironmentPostProcessor.java | 15 ++- ...itional-spring-configuration-metadata.json | 6 + .../TraceEnvironmentPostProcessorTests.java | 59 +++++++++ 6 files changed, 189 insertions(+), 64 deletions(-) create mode 100644 spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessorTests.java diff --git a/README.adoc b/README.adoc index fca6934f5..251732340 100644 --- a/README.adoc +++ b/README.adoc @@ -261,10 +261,10 @@ Consider the following example of a Logback configuration file (named https://gi - ​ + - ​ + - ​ + ${LOG_FILE} @@ -294,7 +294,7 @@ Consider the following example of a Logback configuration file (named https://gi utf8 - ​ + ${LOG_FILE}.json @@ -310,6 +310,7 @@ Consider the following example of a Logback configuration file (named https://gi { + "timestamp": "@timestamp", "severity": "%level", "service": "${springAppName:-}", "trace": "%X{traceId:-}", @@ -325,7 +326,48 @@ Consider the following example of a Logback configuration file (named https://gi - ​ + + + + + + ${LOGZ_IO_API_TOKEN} + https://listener.logz.io:8071 + + INFO + + true + + + + UTC + + + + { + "timestamp": "@timestamp", + "severity": "%level", + "service": "${springAppName:-}", + "trace": "%X{traceId:-}", + "span": "%X{spanId:-}", + "baggage": "%X{key:-}", + "pid": "${PID:-}", + "thread": "%thread", + "class": "%logger{40}", + "rest": "%message" + } + + + + + + + + + + + + @@ -714,7 +756,7 @@ If you do not use SLF4J, this pattern is NOT automatically applied. == Building -:jdkversion: 1.7 +:jdkversion: 1.8 === Basic Compile and Test diff --git a/docs/src/main/asciidoc/_configprops.adoc b/docs/src/main/asciidoc/_configprops.adoc index ce2caa7b7..7ea556945 100644 --- a/docs/src/main/asciidoc/_configprops.adoc +++ b/docs/src/main/asciidoc/_configprops.adoc @@ -1,80 +1,83 @@ |=== |Name | Default | Description -|spring.sleuth.annotation.enabled | true | -|spring.sleuth.async.configurer.enabled | true | Enable default AsyncConfigurer. -|spring.sleuth.async.enabled | true | Enable instrumenting async related components so that the tracing information is passed between threads. +|spring.sleuth.annotation.enabled | `true` | +|spring.sleuth.async.configurer.enabled | `true` | Enable default AsyncConfigurer. +|spring.sleuth.async.enabled | `true` | Enable instrumenting async related components so that the tracing information is passed between threads. |spring.sleuth.async.ignored-beans | | List of {@link java.util.concurrent.Executor} bean names that should be ignored and not wrapped in a trace representation. |spring.sleuth.baggage-keys | | List of baggage key names that should be propagated out of process. These keys will be prefixed with `baggage` before the actual key. This property is set in order to be backward compatible with previous Sleuth versions. @see brave.propagation.ExtraFieldPropagation.FactoryBuilder#addPrefixedFields(String, java.util.Collection) -|spring.sleuth.baggage.correlation-enabled | true | Adds a {@link CorrelationScopeDecorator} to put baggage values into the correlation context. +|spring.sleuth.baggage.correlation-enabled | `true` | Adds a {@link CorrelationScopeDecorator} to put baggage values into the correlation context. |spring.sleuth.baggage.correlation-fields | | A list of {@link BaggageField#name() fields} to add to correlation (MDC) context. @see CorrelationScopeConfig.SingleCorrelationField#create(BaggageField) |spring.sleuth.baggage.local-fields | | Same as {@link #remoteFields} except that this field is not propagated to remote services. @see BaggagePropagationConfig.SingleBaggageField#local(BaggageField) |spring.sleuth.baggage.remote-fields | | List of fields that are referenced the same in-process as it is on the wire. For example, the field "x-vcap-request-id" would be set as-is including the prefix. @see BaggagePropagationConfig.SingleBaggageField#remote(BaggageField) @see BaggagePropagationConfig.SingleBaggageField.Builder#addKeyName(String) |spring.sleuth.baggage.tag-fields | | A list of {@link BaggageField#name() fields} to tag into the span. @see Tags#BAGGAGE_FIELD -|spring.sleuth.circuitbreaker.enabled | true | Enable Spring Cloud CircuitBreaker instrumentation. -|spring.sleuth.enabled | true | -|spring.sleuth.feign.enabled | true | Enable span information propagation when using Feign. -|spring.sleuth.feign.processor.enabled | true | Enable post processor that wraps Feign Context in its tracing representations. -|spring.sleuth.grpc.enabled | true | Enable span information propagation when using GRPC. -|spring.sleuth.http.enabled | true | -|spring.sleuth.http.legacy.enabled | false | -|spring.sleuth.hystrix.strategy.enabled | true | Enable custom HystrixConcurrencyStrategy that wraps all Callable instances into their Sleuth representative - the TraceCallable. -|spring.sleuth.hystrix.strategy.passthrough | false | When enabled the tracing information is passed to the Hystrix execution threads but spans are not created for each execution. -|spring.sleuth.integration.enabled | true | Enable Spring Integration sleuth instrumentation. -|spring.sleuth.integration.patterns | [!hystrixStreamOutput*, *, !channel*] | An array of patterns against which channel names will be matched. @see org.springframework.integration.config.GlobalChannelInterceptor#patterns() Defaults to any channel name not matching the Hystrix Stream and functional Stream channel names. -|spring.sleuth.integration.websockets.enabled | true | Enable tracing for WebSockets. +|spring.sleuth.circuitbreaker.enabled | `true` | Enable Spring Cloud CircuitBreaker instrumentation. +|spring.sleuth.default-logging-pattern-enabled | `true` | Enable setting of a default logging pattern. +|spring.sleuth.enabled | `true` | +|spring.sleuth.feign.enabled | `true` | Enable span information propagation when using Feign. +|spring.sleuth.feign.processor.enabled | `true` | Enable post processor that wraps Feign Context in its tracing representations. +|spring.sleuth.grpc.enabled | `true` | Enable span information propagation when using GRPC. +|spring.sleuth.http.enabled | `true` | +|spring.sleuth.http.legacy.enabled | `false` | +|spring.sleuth.hystrix.strategy.enabled | `true` | Enable custom HystrixConcurrencyStrategy that wraps all Callable instances into their Sleuth representative - the TraceCallable. +|spring.sleuth.hystrix.strategy.passthrough | `false` | When enabled the tracing information is passed to the Hystrix execution threads but spans are not created for each execution. +|spring.sleuth.integration.enabled | `true` | Enable Spring Integration sleuth instrumentation. +|spring.sleuth.integration.patterns | `[!hystrixStreamOutput*, *, !channel*]` | An array of patterns against which channel names will be matched. @see org.springframework.integration.config.GlobalChannelInterceptor#patterns() Defaults to any channel name not matching the Hystrix Stream and functional Stream channel names. +|spring.sleuth.integration.websockets.enabled | `true` | Enable tracing for WebSockets. |spring.sleuth.keys.http.headers | | Additional headers that should be added as tags if they exist. If the header value is multi-valued, the tag value will be a comma-separated, single-quoted list. -|spring.sleuth.keys.http.prefix | http. | Prefix for header names if they are added as tags. +|spring.sleuth.keys.http.prefix | `http.` | Prefix for header names if they are added as tags. |spring.sleuth.local-keys | | Same as {@link #propagationKeys} except that this field is not propagated to remote services. @see brave.propagation.ExtraFieldPropagation.FactoryBuilder#addRedactedField(String) @deprecated use {@code spring.sleuth.baggage.local-fields} property -|spring.sleuth.log.slf4j.enabled | true | Enable a {@link Slf4jScopeDecorator} that prints tracing information in the logs. +|spring.sleuth.log.slf4j.enabled | `true` | Enable a {@link Slf4jScopeDecorator} that prints tracing information in the logs. |spring.sleuth.log.slf4j.whitelisted-mdc-keys | | A list of keys to be put from baggage to MDC. @deprecated use spring.sleuth.baggage.correlation-fields property -|spring.sleuth.messaging.enabled | false | Should messaging be turned on. -|spring.sleuth.messaging.jms.enabled | true | Enable tracing of JMS. -|spring.sleuth.messaging.jms.remote-service-name | jms | -|spring.sleuth.messaging.kafka.enabled | true | Enable tracing of Kafka. -|spring.sleuth.messaging.kafka.mapper.enabled | true | Enable DefaultKafkaHeaderMapper tracing for Kafka. -|spring.sleuth.messaging.kafka.remote-service-name | kafka | -|spring.sleuth.messaging.rabbit.enabled | true | Enable tracing of RabbitMQ. -|spring.sleuth.messaging.rabbit.remote-service-name | rabbitmq | -|spring.sleuth.opentracing.enabled | true | +|spring.sleuth.messaging.enabled | `false` | Should messaging be turned on. +|spring.sleuth.messaging.jms.enabled | `true` | Enable tracing of JMS. +|spring.sleuth.messaging.jms.remote-service-name | `jms` | +|spring.sleuth.messaging.kafka.enabled | `true` | Enable tracing of Kafka. +|spring.sleuth.messaging.kafka.mapper.enabled | `true` | Enable DefaultKafkaHeaderMapper tracing for Kafka. +|spring.sleuth.messaging.kafka.remote-service-name | `kafka` | +|spring.sleuth.messaging.rabbit.enabled | `true` | Enable tracing of RabbitMQ. +|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.

Note: {@code fieldName} will be implicitly lower-cased. @see brave.propagation.ExtraFieldPropagation.FactoryBuilder#addField(String) @deprecated use {@code spring.sleuth.baggage.remote-fields} property -|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 TagPropagationFinishedSpanHandler} 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. -|spring.sleuth.redis.enabled | true | Enable span information propagation when using Redis. -|spring.sleuth.redis.remote-service-name | redis | Service name for the remote Redis endpoint. -|spring.sleuth.rpc.enabled | true | Enable tracing of RPC. -|spring.sleuth.rxjava.schedulers.hook.enabled | true | Enable support for RxJava via RxJavaSchedulersHook. -|spring.sleuth.rxjava.schedulers.ignoredthreads | [HystrixMetricPoller, ^RxComputation.*$] | Thread names for which spans will not be sampled. +|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. If {@link SleuthReactorProperties#decorateQueues} is used, this decoration mode will NOT be used. +|spring.sleuth.reactor.decorate-queues | `true` | When true uses the new decorate queues feature from Project Reactor. Should allow the feature set of {@link SleuthReactorProperties#decorateOnEach} with the least impact on the performance. +|spring.sleuth.reactor.enabled | `true` | When true enables instrumentation for reactor. +|spring.sleuth.redis.enabled | `true` | Enable span information propagation when using Redis. +|spring.sleuth.redis.remote-service-name | `redis` | Service name for the remote Redis endpoint. +|spring.sleuth.rpc.enabled | `true` | Enable tracing of RPC. +|spring.sleuth.rxjava.schedulers.hook.enabled | `true` | Enable support for RxJava via RxJavaSchedulersHook. +|spring.sleuth.rxjava.schedulers.ignoredthreads | `[HystrixMetricPoller, ^RxComputation.*$]` | Thread names for which spans will not be sampled. |spring.sleuth.sampler.probability | | Probability of requests that should be sampled. E.g. 1.0 - 100% requests should be sampled. The precision is whole-numbers only (i.e. there's no support for 0.1% of the traces). -|spring.sleuth.sampler.rate | 10 | A rate per second can be a nice choice for low-traffic endpoints as it allows you surge protection. For example, you may never expect the endpoint to get more than 50 requests per second. If there was a sudden surge of traffic, to 5000 requests per second, you would still end up with 50 traces per second. Conversely, if you had a percentage, like 10%, the same surge would end up with 500 traces per second, possibly overloading your storage. Amazon X-Ray includes a rate-limited sampler (named Reservoir) for this purpose. Brave has taken the same approach via the {@link brave.sampler.RateLimitingSampler}. -|spring.sleuth.scheduled.enabled | true | Enable tracing for {@link org.springframework.scheduling.annotation.Scheduled}. -|spring.sleuth.scheduled.skip-pattern | org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask | Pattern for the fully qualified name of a class that should be skipped. -|spring.sleuth.supports-join | true | True means the tracing system supports sharing a span ID between a client and server. -|spring.sleuth.trace-id128 | false | When true, generate 128-bit trace IDs instead of 64-bit ones. +|spring.sleuth.sampler.rate | `10` | A rate per second can be a nice choice for low-traffic endpoints as it allows you surge protection. For example, you may never expect the endpoint to get more than 50 requests per second. If there was a sudden surge of traffic, to 5000 requests per second, you would still end up with 50 traces per second. Conversely, if you had a percentage, like 10%, the same surge would end up with 500 traces per second, possibly overloading your storage. Amazon X-Ray includes a rate-limited sampler (named Reservoir) for this purpose. Brave has taken the same approach via the {@link brave.sampler.RateLimitingSampler}. +|spring.sleuth.scheduled.enabled | `true` | Enable tracing for {@link org.springframework.scheduling.annotation.Scheduled}. +|spring.sleuth.scheduled.skip-pattern | `org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask` | Pattern for the fully qualified name of a class that should be skipped. +|spring.sleuth.supports-join | `true` | True means the tracing system supports sharing a span ID between a client and server. +|spring.sleuth.trace-id128 | `false` | When true, generate 128-bit trace IDs instead of 64-bit ones. |spring.sleuth.web.additional-skip-pattern | | Additional pattern for URLs that should be skipped in tracing. This will be appended to the {@link SleuthWebProperties#skipPattern}. -|spring.sleuth.web.client.enabled | true | Enable interceptor injecting into {@link org.springframework.web.client.RestTemplate}. +|spring.sleuth.web.client.enabled | `true` | Enable interceptor injecting into {@link org.springframework.web.client.RestTemplate}. |spring.sleuth.web.client.skip-pattern | | Pattern for URLs that should be skipped in client side tracing. -|spring.sleuth.web.enabled | true | When true enables instrumentation for web applications. -|spring.sleuth.web.exception-logging-filter-enabled | true | Flag to toggle the presence of a filter that logs thrown exceptions. -|spring.sleuth.web.exception-throwing-filter-enabled | true | Flag to toggle the presence of a filter that logs thrown exceptions. @deprecated use {@link #exceptionLoggingFilterEnabled} +|spring.sleuth.web.enabled | `true` | When true enables instrumentation for web applications. +|spring.sleuth.web.exception-logging-filter-enabled | `true` | Flag to toggle the presence of a filter that logs thrown exceptions. +|spring.sleuth.web.exception-throwing-filter-enabled | `true` | Flag to toggle the presence of a filter that logs thrown exceptions. @deprecated use {@link #exceptionLoggingFilterEnabled} |spring.sleuth.web.filter-order | | Order in which the tracing filters should be registered. Defaults to {@link TraceHttpAutoConfiguration#TRACING_FILTER_ORDER}. -|spring.sleuth.web.ignore-auto-configured-skip-patterns | false | If set to true, auto-configured skip patterns will be ignored. @see TraceWebAutoConfiguration -|spring.sleuth.web.skip-pattern | /api-docs.*\|/swagger.*\|.*\.png\|.*\.css\|.*\.js\|.*\.html\|/favicon.ico\|/hystrix.stream | Pattern for URLs that should be skipped in tracing. -|spring.sleuth.zuul.enabled | true | Enable span information propagation when using Zuul. -|spring.zipkin.activemq.message-max-bytes | 100000 | Maximum number of bytes for a given message with spans sent to Zipkin over ActiveMQ. -|spring.zipkin.activemq.queue | zipkin | Name of the ActiveMQ queue where spans should be sent to Zipkin. -|spring.zipkin.base-url | http://localhost:9411/ | URL of the zipkin query server instance. You can also provide the service id of the Zipkin server if Zipkin's registered in service discovery (e.g. https://zipkinserver/). -|spring.zipkin.compression.enabled | false | +|spring.sleuth.web.ignore-auto-configured-skip-patterns | `false` | If set to true, auto-configured skip patterns will be ignored. @see TraceWebAutoConfiguration +|spring.sleuth.web.skip-pattern | `/api-docs.*\|/swagger.*\|.*\.png\|.*\.css\|.*\.js\|.*\.html\|/favicon.ico\|/hystrix.stream` | Pattern for URLs that should be skipped in tracing. +|spring.sleuth.zuul.enabled | `true` | Enable span information propagation when using Zuul. +|spring.zipkin.activemq.message-max-bytes | `100000` | Maximum number of bytes for a given message with spans sent to Zipkin over ActiveMQ. +|spring.zipkin.activemq.queue | `zipkin` | Name of the ActiveMQ queue where spans should be sent to Zipkin. +|spring.zipkin.api-path | | The API path to append to baseUrl (above) as suffix. This applies if you use other monitoring tools, such as New Relic. The trace API doesn't need the API path, so you can set it to blank ("") in the configuration. +|spring.zipkin.base-url | `http://localhost:9411/` | URL of the zipkin query server instance. You can also provide the service id of the Zipkin server if Zipkin's registered in service discovery (e.g. https://zipkinserver/). +|spring.zipkin.compression.enabled | `false` | |spring.zipkin.discovery-client-enabled | | If set to {@code false}, will treat the {@link ZipkinProperties#baseUrl} as a URL always. -|spring.zipkin.enabled | true | Enables sending spans to Zipkin. +|spring.zipkin.enabled | `true` | Enables sending spans to Zipkin. |spring.zipkin.encoder | | Encoding type of spans sent to Zipkin. Set to {@link SpanBytesEncoder#JSON_V1} if your server is not recent. -|spring.zipkin.kafka.topic | zipkin | Name of the Kafka topic where spans should be sent to Zipkin. -|spring.zipkin.locator.discovery.enabled | false | Enabling of locating the host name via service discovery. -|spring.zipkin.message-timeout | 1 | Timeout in seconds before pending spans will be sent in batches to Zipkin. +|spring.zipkin.kafka.topic | `zipkin` | Name of the Kafka topic where spans should be sent to Zipkin. +|spring.zipkin.locator.discovery.enabled | `false` | Enabling of locating the host name via service discovery. +|spring.zipkin.message-timeout | `1` | Timeout in seconds before pending spans will be sent in batches to Zipkin. |spring.zipkin.rabbitmq.addresses | | Addresses of the RabbitMQ brokers used to send spans to Zipkin -|spring.zipkin.rabbitmq.queue | zipkin | Name of the RabbitMQ queue where spans should be sent to Zipkin. +|spring.zipkin.rabbitmq.queue | `zipkin` | Name of the RabbitMQ queue where spans should be sent to Zipkin. |spring.zipkin.sender.type | | Means of sending spans to Zipkin. |spring.zipkin.service.name | | The name of the service, from which the Span was sent via HTTP, that should appear in Zipkin. diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc index 006d39466..d81b1e0ea 100644 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc @@ -842,6 +842,10 @@ Running the preceding method with a value of `15` leads to setting a tag with a == Customizations +=== Disabling Default Logging Pattern + +Spring Cloud Sleuth sets a default logging pattern. To disable it set the `spring.sleuth.default-logging-pattern-enabled` property to `false`. + === Customizers With Brave 5.7 you have various options of providing customizers for your project. Brave ships with diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java index 48fbbbe7e..c38c19745 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java @@ -49,14 +49,25 @@ public class TraceEnvironmentPostProcessor implements EnvironmentPostProcessor { Map map = new HashMap(); // This doesn't work with all logging systems but it's a useful default so you see // traces in logs without having to configure it. - if (Boolean - .parseBoolean(environment.getProperty("spring.sleuth.enabled", "true"))) { + if (sleuthEnabled(environment) + && sleuthDefaultLoggingPatternEnabled(environment)) { map.put("logging.pattern.level", "%5p [${spring.zipkin.service.name:" + "${spring.application.name:}},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]"); } addOrReplace(environment.getPropertySources(), map); } + private boolean sleuthEnabled(ConfigurableEnvironment environment) { + return Boolean + .parseBoolean(environment.getProperty("spring.sleuth.enabled", "true")); + } + + private boolean sleuthDefaultLoggingPatternEnabled( + ConfigurableEnvironment environment) { + return Boolean.parseBoolean(environment + .getProperty("spring.sleuth.default-logging-pattern-enabled", "true")); + } + private void addOrReplace(MutablePropertySources propertySources, Map map) { MapPropertySource target = null; diff --git a/spring-cloud-sleuth-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-sleuth-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json index c4b959e08..72072b211 100644 --- a/spring-cloud-sleuth-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-sleuth-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -77,6 +77,12 @@ "type": "java.lang.Boolean", "description": "Enable tracing of RPC.", "defaultValue": true + }, + { + "name": "spring.sleuth.default-logging-pattern-enabled", + "type": "java.lang.Boolean", + "description": "Enable setting of a default logging pattern.", + "defaultValue": true } ] } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessorTests.java new file mode 100644 index 000000000..619ac4291 --- /dev/null +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessorTests.java @@ -0,0 +1,59 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig; + +import org.junit.jupiter.api.Test; + +import org.springframework.mock.env.MockEnvironment; + +import static org.assertj.core.api.BDDAssertions.then; + +class TraceEnvironmentPostProcessorTests { + + MockEnvironment mockEnvironment = new MockEnvironment(); + + TraceEnvironmentPostProcessor processor = new TraceEnvironmentPostProcessor(); + + @Test + void should_add_logging_pattern_when_not_disabled_explicitly() { + + this.processor.postProcessEnvironment(this.mockEnvironment, null); + + then(this.mockEnvironment.getProperty("logging.pattern.level")).isNotBlank(); + } + + @Test + void should_not_add_logging_pattern_when_sleuth_disabled() { + this.mockEnvironment.setProperty("spring.sleuth.enabled", "false"); + + this.processor.postProcessEnvironment(this.mockEnvironment, null); + + then(this.mockEnvironment.getProperty("logging.pattern.level")).isBlank(); + + } + + @Test + void should_not_add_logging_pattern_when_sleuth_default_logging_pattern_disabled() { + this.mockEnvironment.setProperty("spring.sleuth.default-logging-pattern-enabled", + "false"); + + this.processor.postProcessEnvironment(this.mockEnvironment, null); + + then(this.mockEnvironment.getProperty("logging.pattern.level")).isBlank(); + } + +} From 5ab1c13f0cacd7d46b8528427c825f16fbfac216 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 30 Mar 2021 13:22:35 +0200 Subject: [PATCH 50/78] Assuming 500 status code when an exception was thrown (#1889) * Assuming 500 status code when an exception was thrown in the controller; fixes gh-1880 * Ensures that the response is committed --- .../sleuth/instrument/web/TraceWebFilter.java | 7 +++++-- .../brave/instrument/web/TraceWebFluxTests.java | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java index 4fb8edd66..c2ed27cc8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java @@ -415,8 +415,11 @@ public class TraceWebFilter implements WebFilter, Ordered, ApplicationContextAwa @Override public int statusCode() { - if (this.throwable != null && this.throwable instanceof ResponseStatusException) { - return ((ResponseStatusException) this.throwable).getRawStatusCode(); + if (!this.delegate.isCommitted() && this.throwable != null) { + if (this.throwable instanceof ResponseStatusException) { + return ((ResponseStatusException) this.throwable).getRawStatusCode(); + } + return HttpStatus.INTERNAL_SERVER_ERROR.value(); } HttpStatus statusCode = this.delegate.getStatusCode(); return statusCode != null ? statusCode.value() : 0; diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java index 4cfdd8073..294c0e700 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/web/TraceWebFluxTests.java @@ -83,6 +83,12 @@ public class TraceWebFluxTests { thenSpanWith404StatusCodeWasReported(spans, response); spans.clear(); + // when + response = whenRequestIsSent(port, "/exception"); + // then + thenSpanWithExceptionWasReported(spans, response); + spans.clear(); + // when ClientResponse nonSampledResponse = whenNonSampledRequestIsSent(port); // then @@ -137,6 +143,12 @@ public class TraceWebFluxTests { then(spans.get(0).tags()).hasEntrySatisfying("http.status_code", value -> then(value).isEqualTo("404")); } + private void thenSpanWithExceptionWasReported(TestSpanHandler spans, ClientResponse response) { + Awaitility.await().untilAsserted(() -> then(response.statusCode().value()).isEqualTo(500)); + then(spans).hasSize(1); + then(spans.get(0).tags()).hasEntrySatisfying("http.status_code", value -> then(value).isEqualTo("500")); + } + private void thenNoSpanWasReported(TestSpanHandler spans, ClientResponse response, Controller2 controller2) { Awaitility.await().untilAsserted(() -> { then(response.statusCode().value()).isEqualTo(200); @@ -229,6 +241,11 @@ public class TraceWebFluxTests { return Flux.just(sampled.toString()); } + @GetMapping("/exception") + public Flux exception() { + throw new RuntimeException("Exception"); + } + } } From 017caaf9b2114a0573685f8cdf9009f5a6d79747 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 1 Apr 2021 09:18:19 +0200 Subject: [PATCH 51/78] WebClient reuses current trace context if present; fixes gh-1891 --- .../instrument/web/client/TraceExchangeFilterFunction.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java index 69e954b8f..487148e1e 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceExchangeFilterFunction.java @@ -113,6 +113,9 @@ public final class TraceExchangeFilterFunction implements ExchangeFilterFunction } ClientRequestWrapper wrapper = new ClientRequestWrapper(this.request); TraceContext parent = context.hasKey(TraceContext.class) ? context.get(TraceContext.class) : null; + if (parent == null) { + parent = this.currentTraceContext.context(); + } Span span = handler.handleSend(wrapper, parent); if (log.isTraceEnabled()) { log.trace("HttpClientHandler::handleSend: " + span); From 8321b23658ca72a3f493dffb085e954a9c6c2366 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 1 Apr 2021 12:24:38 +0200 Subject: [PATCH 52/78] Fixes benchmarks --- .../SleuthBenchmarkingStreamApplication.java | 4 +- .../jmh/mvc/HttpFilterBenchmarksTests.java | 36 +--- .../HttpFilterNoSleuthBenchmarksTests.java | 161 ++++++++++++++++++ .../jmh/stream/MicroBenchmarkStreamTests.java | 3 +- .../jmh/webflux/MicroBenchmarkHttpTests.java | 6 +- 5 files changed, 178 insertions(+), 32 deletions(-) create mode 100644 benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java index bcbff5f18..32f1fa718 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java @@ -59,8 +59,8 @@ public class SleuthBenchmarkingStreamApplication { // System.setProperty("spring.sleuth.reactor.instrumentation-type", // "DECORATE_ON_LAST"); // System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL"); - System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL"); - System.setProperty("spring.sleuth.function.type", "simple"); + System.setProperty("spring.sleuth.reactor.instrumentation-type", "DECORATE_QUEUES"); + System.setProperty("spring.sleuth.function.type", "DECORATE_QUEUES"); ConfigurableApplicationContext context = SpringApplication.run(SleuthBenchmarkingStreamApplication.class, args); for (int i = 0; i < 1; i++) { InputDestination input = context.getBean(InputDestination.class); diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java index 147876c02..8363de5cf 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterBenchmarksTests.java @@ -43,9 +43,12 @@ import org.openjdk.jmh.annotations.Threads; import org.openjdk.jmh.annotations.Warmup; import org.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController; +import org.springframework.cloud.sleuth.http.HttpServerHandler; import org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.http.MediaType; @@ -60,6 +63,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -67,6 +71,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Warmup(iterations = 5) +@Measurement(iterations = 10, time = 1) +@Fork(2) @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MICROSECONDS) @Threads(Threads.MAX) @@ -74,19 +80,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. public class HttpFilterBenchmarksTests { @Benchmark - @Measurement(iterations = 5, time = 1) - @Fork(2) - public void filterWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { - MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); - MockHttpServletResponse response = new MockHttpServletResponse(); - response.setContentType(MediaType.APPLICATION_JSON_VALUE); - - context.dummyFilter.doFilter(request, response, new MockFilterChain()); - } - - @Benchmark - @Measurement(iterations = 5, time = 1) - @Fork(2) public void filterWithSleuth(BenchmarkContext context) throws ServletException, IOException { MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -96,15 +89,6 @@ public class HttpFilterBenchmarksTests { } @Benchmark - @Measurement(iterations = 5, time = 10) - @Fork(10) - public void asyncWithoutSleuth(BenchmarkContext context) throws Exception { - performRequest(context.mockMvcForUntracedController, "vanilla", "vanilla"); - } - - @Benchmark - @Measurement(iterations = 5, time = 10) - @Fork(10) public void asyncWithSleuth(BenchmarkContext context) throws Exception { performRequest(context.mockMvcForTracedController, "bar", "bar"); } @@ -126,14 +110,10 @@ public class HttpFilterBenchmarksTests { volatile ConfigurableApplicationContext withSleuth; - volatile DummyFilter dummyFilter = new DummyFilter(); - volatile TracingFilter tracingFilter; volatile MockMvc mockMvcForTracedController; - volatile MockMvc mockMvcForUntracedController; - @Param private TracerImplementation tracerImplementation; @@ -142,10 +122,10 @@ public class HttpFilterBenchmarksTests { this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", "--spring.application.name=withSleuth_" + this.tracerImplementation.name()); - this.tracingFilter = this.withSleuth.getBean(TracingFilter.class); + assertThat(this.withSleuth.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNotNull(); + this.tracingFilter = TracingFilter.create(this.withSleuth.getBean(CurrentTraceContext.class), this.withSleuth.getBean(HttpServerHandler.class)); this.mockMvcForTracedController = MockMvcBuilders .standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)).build(); - this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build(); } @TearDown diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java new file mode 100644 index 000000000..bdf79cb61 --- /dev/null +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java @@ -0,0 +1,161 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.mvc; + +import java.io.IOException; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import jmh.mbr.junit5.Microbenchmark; +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.Param; +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.springframework.boot.SpringApplication; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp; +import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@Warmup(iterations = 5) +@Measurement(iterations = 10, time = 1) +@Fork(2) +@BenchmarkMode(Mode.SampleTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Threads(Threads.MAX) +@Microbenchmark +public class HttpFilterNoSleuthBenchmarksTests { + + @Benchmark + public void filterWithoutSleuth(BenchmarkContext context) throws IOException, ServletException { + MockHttpServletRequest request = builder().buildRequest(new MockServletContext()); + MockHttpServletResponse response = new MockHttpServletResponse(); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + + context.dummyFilter.doFilter(request, response, new MockFilterChain()); + } + + @Benchmark + public void asyncWithoutSleuth(BenchmarkContext context) throws Exception { + performRequest(context.mockMvcForUntracedController, "vanilla", "vanilla"); + } + + private MockHttpServletRequestBuilder builder() { + return get("/").accept(MediaType.APPLICATION_JSON).header("User-Agent", "MockMvc"); + } + + private void performRequest(MockMvc mockMvc, String url, String expectedResult) throws Exception { + MvcResult mvcResult = mockMvc.perform(get("/" + url)).andExpect(status().isOk()) + .andExpect(request().asyncStarted()).andReturn(); + + mockMvc.perform(asyncDispatch(mvcResult)).andExpect(status().isOk()) + .andExpect(content().string(expectedResult)); + } + + @State(Scope.Benchmark) + public static class BenchmarkContext { + + volatile ConfigurableApplicationContext app; + + volatile DummyFilter dummyFilter = new DummyFilter(); + + volatile MockMvc mockMvcForUntracedController; + + @Param + private TracerImplementation tracerImplementation; + + @Setup + public void setup() { + this.app = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", "--spring.sleuth.enabled=false", + + "--spring.application.name=noSleuth_" + this.tracerImplementation.name()); + assertThat(this.app.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNull(); + this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build(); + } + + @TearDown + public void clean() { + this.app.getBean(SleuthBenchmarkingSpringApp.class).clean(); + this.app.close(); + } + + } + + private static class DummyFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + + } + + @RestController + private static class VanillaController { + + @RequestMapping("/vanilla") + public Callable vanilla() { + return () -> "vanilla"; + } + + } + +} diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java index 9dcfb3cc5..225821b5a 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java @@ -163,7 +163,8 @@ public class MicroBenchmarkStreamTests { sleuthSimpleOnLast(function("simple"), Pair.onLast()), sleuthSimpleWithAroundOnQueues(function("simple_function_with_around")), noSleuthReactiveSimple(function("reactive_simple"), Pair.noSleuth()), - sleuthReactiveSimpleOnQueues(function("DECORATE_QUEUES")), + // TODO: CHECK WHY IT'S FAILING + // sleuthReactiveSimpleOnQueues(function("DECORATE_QUEUES")), sleuthReactiveSimpleOnEach(function("DECORATE_ON_EACH"), Pair.onEach(), integrationEnabled()), sleuthReactiveSimpleManual(function("reactive_simple_manual"), Pair.manual()), sleuthReactiveSimpleNoFunctionInstrumentationManual(function("reactive_simple_manual"), Pair.manual(), integrationEnabled(), functionDisabled()); diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java index 049dffd1d..d2c32cb56 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/MicroBenchmarkHttpTests.java @@ -101,7 +101,11 @@ public class MicroBenchmarkHttpTests { void run() { this.webTestClient.get().uri(instrumentation.url).header("X-B3-TraceId", "4883117762eb9420") .header("X-B3-SpanId", "4883117762eb9420").exchange().expectStatus().isOk(); - assertThat(this.applicationContext.getBean(Tracer.class).currentSpan()).isNull(); + if (this.instrumentation.name().toLowerCase().contains("nosleuth")) { + assertThat(this.applicationContext.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNull(); + } else { + assertThat(this.applicationContext.getBean(Tracer.class).currentSpan()).isNull(); + } } @TearDown From dc71088ff0ccae7c1940191c3eba251ac9129b9e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 2 Apr 2021 09:32:19 +0200 Subject: [PATCH 53/78] Improve the reactor netty instrumentation; fixes gh-1899 --- .../instrument/web/client/HttpClientBeanPostProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java index 0e3de4206..4f819f0ec 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/HttpClientBeanPostProcessor.java @@ -71,7 +71,7 @@ public class HttpClientBeanPostProcessor implements BeanPostProcessor { // preparation of a redirect follow-up. TracingDoOnResponse doOnResponse = new TracingDoOnResponse(springContext); return ((HttpClient) bean).doOnResponseError(new TracingDoOnErrorResponse(springContext)) - .doOnRedirect(doOnResponse).doOnResponse(doOnResponse) + .doOnRedirect(doOnResponse).doAfterResponseSuccess(doOnResponse) .doOnRequestError(new TracingDoOnErrorRequest(springContext)) .doOnRequest(new TracingDoOnRequest(springContext)).mapConnect(new TracingMapConnect(() -> { CurrentTraceContext ref = currentContext.get(); From 00b4771a74e2b578b3b2e2362fb088e47e9e1c7a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 6 Apr 2021 11:35:54 +0200 Subject: [PATCH 54/78] Fixed the build for boot 2.5 --- .../web/SkipPatternProviderConfigTest.java | 66 +++++++++++++------ 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java index c09b160fc..aca9c1387 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/web/SkipPatternProviderConfigTest.java @@ -106,7 +106,9 @@ public class SkipPatternProviderConfigTest { contextRunner .withConfiguration( UserConfigurations.of(ManagementContextAutoConfiguration.class, ServerPropertiesConfig.class)) - .withPropertyValues("management.server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", "foo.*", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -118,7 +120,9 @@ public class SkipPatternProviderConfigTest { contextRunner .withConfiguration( UserConfigurations.of(ManagementContextAutoConfiguration.class, ServerPropertiesConfig.class)) - .withPropertyValues("management.server.servlet.context-path=${test:value}").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.server.servlet.context-path=${test:value}") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", "value.*", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -137,16 +141,19 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_without_context_path() { - contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)).run(context -> { - BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( - "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); - }); + contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) + .withPropertyValues("management.endpoints.web.exposure.include=health,info").run(context -> { + BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( + "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); + }); } @Test public void should_return_endpoints_with_context_path() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -156,7 +163,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_with_placeholders() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("server.servlet.context-path=${test:foo}").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "server.servlet.context-path=${test:foo}") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -166,7 +175,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_without_context_path_and_base_path_set_to_root() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/(health|health/.*|info|info/.*)", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); @@ -175,7 +186,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_without_context_path_and_base_path_set_to_root_with_placeholders() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=${test:/}").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=${test:/}") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/(health|health/.*|info|info/.*)", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); @@ -184,7 +197,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/", "server.servlet.context-path=foo") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -194,7 +208,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root_with_placeholder() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=${test:/}", "server.servlet.context-path=foo") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=${test:/}", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -204,7 +219,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/", "management.server.port=0", + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/", "management.server.port=0", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( @@ -217,7 +233,8 @@ public class SkipPatternProviderConfigTest { contextRunner .withConfiguration( UserConfigurations.of(ServerPropertiesConfig.class, ManagementServerPropertiesConfig.class)) - .withPropertyValues("management.server.base-path=/foo", "management.endpoints.web.base-path=/actuator", + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.server.base-path=/foo", "management.endpoints.web.base-path=/actuator", "management.server.port=0") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( @@ -229,7 +246,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_and_base_path_set_to_root_different_port_with_placeholder() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/", "management.server.port=${some-port:0}", + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/", "management.server.port=${some-port:0}", "server.servlet.context-path=${some-path:foo}") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( @@ -240,7 +258,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_context_path_only() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/mgt", "server.servlet.context-path=foo") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/mgt", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/mgt(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -250,8 +269,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_context_path_only_with_placeholder() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/${test:mgt}", - "server.servlet.context-path=${test2:foo}") + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/${test:mgt}", "server.servlet.context-path=${test2:foo}") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "foo/mgt(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); @@ -261,7 +280,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_default_context_path_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.server.port=0", "server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", "management.server.port=0", + "server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); @@ -270,7 +291,8 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_actuator_context_path_only_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.endpoints.web.base-path=/mgt", "management.server.port=0", + .withPropertyValues("management.endpoints.web.exposure.include=health,info", + "management.endpoints.web.base-path=/mgt", "management.server.port=0", "server.servlet.context-path=foo") .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( @@ -281,7 +303,9 @@ public class SkipPatternProviderConfigTest { @Test public void should_return_endpoints_with_context_path_different_port() { contextRunner.withConfiguration(UserConfigurations.of(ServerPropertiesConfig.class)) - .withPropertyValues("management.server.port=0", "server.servlet.context-path=foo").run(context -> { + .withPropertyValues("management.endpoints.web.exposure.include=health,info", "management.server.port=0", + "server.servlet.context-path=foo") + .run(context -> { BDDAssertions.then(extractAllPatterns(context)).containsExactlyInAnyOrder( "/actuator(/|/(health|health/.*|info|info/.*))?", SleuthWebProperties.DEFAULT_SKIP_PATTERN); }); From 3709ed80e7f87397f9fe2b2425c9ad8e42e1d5c8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 6 Apr 2021 11:44:25 +0200 Subject: [PATCH 55/78] Fixed missing options for benchmarks --- .../org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java | 4 ++++ .../benchmarks/jmh/stream/MicroBenchmarkStreamTests.java | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java index 3a4e82416..67c0ca5fe 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java @@ -47,6 +47,10 @@ public class Pair { return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH.name()); } + public static Pair decorateQueues() { + return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES.name()); + } + public static Pair manual() { return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.MANUAL.name()); } diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java index 225821b5a..6ce4905df 100644 --- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java +++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/stream/MicroBenchmarkStreamTests.java @@ -163,8 +163,7 @@ public class MicroBenchmarkStreamTests { sleuthSimpleOnLast(function("simple"), Pair.onLast()), sleuthSimpleWithAroundOnQueues(function("simple_function_with_around")), noSleuthReactiveSimple(function("reactive_simple"), Pair.noSleuth()), - // TODO: CHECK WHY IT'S FAILING - // sleuthReactiveSimpleOnQueues(function("DECORATE_QUEUES")), + sleuthReactiveSimpleOnQueues(function("DECORATE_QUEUES"), Pair.decorateQueues(), integrationEnabled()), sleuthReactiveSimpleOnEach(function("DECORATE_ON_EACH"), Pair.onEach(), integrationEnabled()), sleuthReactiveSimpleManual(function("reactive_simple_manual"), Pair.manual()), sleuthReactiveSimpleNoFunctionInstrumentationManual(function("reactive_simple_manual"), Pair.manual(), integrationEnabled(), functionDisabled()); From 5ebed5305d0d86cc7136f685f4381d7ff99665e4 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Fri, 9 Apr 2021 05:30:08 +0000 Subject: [PATCH 56/78] Bumping versions --- benchmarks/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index e0b4c0ef9..34d1d4cd7 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -28,7 +28,7 @@ org.springframework.boot spring-boot-starter-parent - 2.4.4 + 2.4.5-SNAPSHOT From ebe684007e190b12eeb9cfd6e1ed33af0f6f3118 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Fri, 9 Apr 2021 13:46:32 +0200 Subject: [PATCH 57/78] Add binding mapping logic to TraceFunctionAroundWrapper Removed unnecessary 'if debug' checks --- .../messaging/TraceFunctionAroundWrapper.java | 35 ++++++------ .../TraceFunctionAroundWrapperTests.java | 56 +++++++++++++++++++ 2 files changed, 75 insertions(+), 16 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java index 5de057032..aa9a6214b 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java @@ -37,6 +37,7 @@ import org.springframework.messaging.support.MessageHeaderAccessor; * Trace representation of a {@link FunctionAroundWrapper}. * * @author Marcin Grzejszczak + * @author Oleg Zhurakousky * @since 3.0.0 */ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper @@ -73,7 +74,7 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper log.debug("Will retrieve the tracing headers from the message"); } MessageAndSpans wrappedInputMessage = traceMessageHandler.wrapInputMessage(message, - inputDestination(targetFunction)); + inputDestination(targetFunction.getFunctionDefinition())); if (log.isDebugEnabled()) { log.debug("Wrapped input msg " + wrappedInputMessage); } @@ -90,14 +91,12 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper traceMessageHandler.afterMessageHandled(wrappedInputMessage.childSpan, throwable); } if (result == null) { - if (log.isDebugEnabled()) { - log.debug("Returned message is null - we have a consumer"); - } + log.debug("Returned message is null - we have a consumer"); return null; } Message msgResult = toMessage(result); MessageAndSpan wrappedOutputMessage = traceMessageHandler.wrapOutputMessage(msgResult, - wrappedInputMessage.parentSpan, outputDestination(targetFunction)); + wrappedInputMessage.parentSpan, outputDestination(targetFunction.getFunctionDefinition())); if (log.isDebugEnabled()) { log.debug("Wrapped output msg " + wrappedOutputMessage); } @@ -112,23 +111,27 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper return (Message) result; } - private String inputDestination(SimpleFunctionRegistry.FunctionInvocationWrapper targetFunction) { - String functionDefinition = targetFunction.getFunctionDefinition(); - return this.functionToDestinationCache.computeIfAbsent(functionDefinition, - s -> this.environment.getProperty("spring.cloud.stream.bindings." + s + "-in-0.destination", s)); + private String inputDestination(String functionDefinition) { + return this.functionToDestinationCache.computeIfAbsent(functionDefinition, s -> { + String bindingMappingProperty = "spring.cloud.stream.function.bindings." + s + "-in-0"; + String bindingProperty = this.environment.containsProperty(bindingMappingProperty) + ? this.environment.getProperty(bindingMappingProperty) : s + "-in-0"; + return this.environment.getProperty("spring.cloud.stream.bindings." + bindingProperty + ".destination", s); + }); } - private String outputDestination(SimpleFunctionRegistry.FunctionInvocationWrapper targetFunction) { - String functionDefinition = targetFunction.getFunctionDefinition(); - return functionToDestinationCache.computeIfAbsent(functionDefinition, - s -> this.environment.getProperty("spring.cloud.stream.bindings." + s + "-out-0.destination", s)); + private String outputDestination(String functionDefinition) { + return this.functionToDestinationCache.computeIfAbsent(functionDefinition, s -> { + String bindingMappingProperty = "spring.cloud.stream.function.bindings." + s + "-out-0"; + String bindingProperty = this.environment.containsProperty(bindingMappingProperty) + ? this.environment.getProperty(bindingMappingProperty) : s + "-out-0"; + return this.environment.getProperty("spring.cloud.stream.bindings." + bindingProperty + ".destination", s); + }); } @Override public void onApplicationEvent(RefreshScopeRefreshedEvent event) { - if (log.isDebugEnabled()) { - log.debug("Context refreshed, will reset the cache"); - } + log.debug("Context refreshed, will reset the cache"); this.functionToDestinationCache.clear(); } diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java index 3717a0a62..3d1e0f63c 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java @@ -16,8 +16,14 @@ package org.springframework.cloud.sleuth.instrument.messaging; +import java.lang.reflect.Method; + import org.junit.jupiter.api.Test; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.BDDAssertions.then; class TraceFunctionAroundWrapperTests { @@ -33,4 +39,54 @@ class TraceFunctionAroundWrapperTests { then(wrapper.functionToDestinationCache).isEmpty(); } + @Test + void test_with_standard_bindings() throws Exception { + try (GenericApplicationContext context = new GenericApplicationContext()) { + System.setProperty("spring.cloud.stream.bindings.marcin-in-0.destination", "oleg"); + System.setProperty("spring.cloud.stream.bindings.marcin-out-0.destination", "bob"); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(context.getEnvironment(), null, null, + null, null); + + Method inputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, + "inputDestination", String.class); + inputDestinationMethod.setAccessible(true); + assertThat(inputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("oleg"); // gross + // overestimation + // ;) + + wrapper.functionToDestinationCache.clear(); + Method outputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, + "outputDestination", String.class); + outputDestinationMethod.setAccessible(true); + assertThat(outputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("bob"); + } + } + + @Test + void test_with_remapped_bindings() throws Exception { + try (GenericApplicationContext context = new GenericApplicationContext()) { + System.setProperty("spring.cloud.stream.function.bindings.marcin-in-0", "input"); + System.setProperty("spring.cloud.stream.bindings.input.destination", "oleg"); + System.setProperty("spring.cloud.stream.function.bindings.marcin-out-0", "output"); + System.setProperty("spring.cloud.stream.bindings.output.destination", "bob"); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(context.getEnvironment(), null, null, + null, null); + + Method inputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, + "inputDestination", String.class); + inputDestinationMethod.setAccessible(true); + assertThat(inputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("oleg"); // that's + // a + // gross + // overestimation + // ;) + + wrapper.functionToDestinationCache.clear(); + Method outputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, + "outputDestination", String.class); + outputDestinationMethod.setAccessible(true); + assertThat(outputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("bob"); + } + } + } From 88c7b664ca9902e59b31fe7840def4c7e51cbffe Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 9 Apr 2021 14:53:14 +0200 Subject: [PATCH 58/78] Polish --- .../messaging/TraceFunctionAroundWrapper.java | 12 ++-- .../TraceFunctionAroundWrapperTests.java | 67 +++++++------------ 2 files changed, 31 insertions(+), 48 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java index aa9a6214b..95ec169f2 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapper.java @@ -91,7 +91,9 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper traceMessageHandler.afterMessageHandled(wrappedInputMessage.childSpan, throwable); } if (result == null) { - log.debug("Returned message is null - we have a consumer"); + if (log.isDebugEnabled()) { + log.debug("Returned message is null - we have a consumer"); + } return null; } Message msgResult = toMessage(result); @@ -111,7 +113,7 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper return (Message) result; } - private String inputDestination(String functionDefinition) { + String inputDestination(String functionDefinition) { return this.functionToDestinationCache.computeIfAbsent(functionDefinition, s -> { String bindingMappingProperty = "spring.cloud.stream.function.bindings." + s + "-in-0"; String bindingProperty = this.environment.containsProperty(bindingMappingProperty) @@ -120,7 +122,7 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper }); } - private String outputDestination(String functionDefinition) { + String outputDestination(String functionDefinition) { return this.functionToDestinationCache.computeIfAbsent(functionDefinition, s -> { String bindingMappingProperty = "spring.cloud.stream.function.bindings." + s + "-out-0"; String bindingProperty = this.environment.containsProperty(bindingMappingProperty) @@ -131,7 +133,9 @@ public class TraceFunctionAroundWrapper extends FunctionAroundWrapper @Override public void onApplicationEvent(RefreshScopeRefreshedEvent event) { - log.debug("Context refreshed, will reset the cache"); + if (log.isDebugEnabled()) { + log.debug("Context refreshed, will reset the cache"); + } this.functionToDestinationCache.clear(); } diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java index 3d1e0f63c..5529ed2e4 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java @@ -16,12 +16,9 @@ package org.springframework.cloud.sleuth.instrument.messaging; -import java.lang.reflect.Method; - import org.junit.jupiter.api.Test; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.util.ReflectionUtils; +import org.springframework.mock.env.MockEnvironment; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.BDDAssertions.then; @@ -40,53 +37,35 @@ class TraceFunctionAroundWrapperTests { } @Test - void test_with_standard_bindings() throws Exception { - try (GenericApplicationContext context = new GenericApplicationContext()) { - System.setProperty("spring.cloud.stream.bindings.marcin-in-0.destination", "oleg"); - System.setProperty("spring.cloud.stream.bindings.marcin-out-0.destination", "bob"); - TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(context.getEnvironment(), null, null, - null, null); + void should_point_to_proper_destination_when_working_with_function_definition() { + MockEnvironment mockEnvironment = new MockEnvironment(); + mockEnvironment.setProperty("spring.cloud.stream.bindings.marcin-in-0.destination", "oleg"); + mockEnvironment.setProperty("spring.cloud.stream.bindings.marcin-out-0.destination", "bob"); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, + null, null); - Method inputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, - "inputDestination", String.class); - inputDestinationMethod.setAccessible(true); - assertThat(inputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("oleg"); // gross - // overestimation - // ;) + assertThat(wrapper.inputDestination("marcin")).isEqualTo("oleg"); - wrapper.functionToDestinationCache.clear(); - Method outputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, - "outputDestination", String.class); - outputDestinationMethod.setAccessible(true); - assertThat(outputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("bob"); - } + wrapper.functionToDestinationCache.clear(); + + assertThat(wrapper.outputDestination("marcin")).isEqualTo("bob"); } @Test - void test_with_remapped_bindings() throws Exception { - try (GenericApplicationContext context = new GenericApplicationContext()) { - System.setProperty("spring.cloud.stream.function.bindings.marcin-in-0", "input"); - System.setProperty("spring.cloud.stream.bindings.input.destination", "oleg"); - System.setProperty("spring.cloud.stream.function.bindings.marcin-out-0", "output"); - System.setProperty("spring.cloud.stream.bindings.output.destination", "bob"); - TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(context.getEnvironment(), null, null, - null, null); + void should_point_to_proper_destination_when_working_with_remapped_functions() { + MockEnvironment mockEnvironment = new MockEnvironment(); + mockEnvironment.setProperty("spring.cloud.stream.function.bindings.marcin-in-0", "input"); + mockEnvironment.setProperty("spring.cloud.stream.bindings.input.destination", "oleg"); + mockEnvironment.setProperty("spring.cloud.stream.function.bindings.marcin-out-0", "output"); + mockEnvironment.setProperty("spring.cloud.stream.bindings.output.destination", "bob"); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, + null, null); - Method inputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, - "inputDestination", String.class); - inputDestinationMethod.setAccessible(true); - assertThat(inputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("oleg"); // that's - // a - // gross - // overestimation - // ;) + assertThat(wrapper.inputDestination("marcin")).isEqualTo("oleg"); - wrapper.functionToDestinationCache.clear(); - Method outputDestinationMethod = ReflectionUtils.findMethod(TraceFunctionAroundWrapper.class, - "outputDestination", String.class); - outputDestinationMethod.setAccessible(true); - assertThat(outputDestinationMethod.invoke(wrapper, "marcin")).isEqualTo("bob"); - } + wrapper.functionToDestinationCache.clear(); + + assertThat(wrapper.outputDestination("marcin")).isEqualTo("bob"); } } From a2e5c2c1c588042059842dfecca3a4632ba371ac Mon Sep 17 00:00:00 2001 From: buildmaster Date: Sat, 10 Apr 2021 05:30:18 +0000 Subject: [PATCH 59/78] Bumping versions --- .../messaging/TraceFunctionAroundWrapperTests.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java index 5529ed2e4..45973688c 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceFunctionAroundWrapperTests.java @@ -41,8 +41,7 @@ class TraceFunctionAroundWrapperTests { MockEnvironment mockEnvironment = new MockEnvironment(); mockEnvironment.setProperty("spring.cloud.stream.bindings.marcin-in-0.destination", "oleg"); mockEnvironment.setProperty("spring.cloud.stream.bindings.marcin-out-0.destination", "bob"); - TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, - null, null); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, null, null); assertThat(wrapper.inputDestination("marcin")).isEqualTo("oleg"); @@ -58,8 +57,7 @@ class TraceFunctionAroundWrapperTests { mockEnvironment.setProperty("spring.cloud.stream.bindings.input.destination", "oleg"); mockEnvironment.setProperty("spring.cloud.stream.function.bindings.marcin-out-0", "output"); mockEnvironment.setProperty("spring.cloud.stream.bindings.output.destination", "bob"); - TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, - null, null); + TraceFunctionAroundWrapper wrapper = new TraceFunctionAroundWrapper(mockEnvironment, null, null, null, null); assertThat(wrapper.inputDestination("marcin")).isEqualTo("oleg"); From 8d86e19807521c50b333bca98bd938f43af9fcab Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 13 Apr 2021 08:57:45 +0200 Subject: [PATCH 60/78] Added remoteServiceName to Span interface; fixes gh-1901 --- .../java/org/springframework/cloud/sleuth/Span.java | 10 ++++++++++ .../cloud/sleuth/autoconfig/NoOpSpan.java | 5 +++++ .../cloud/sleuth/brave/bridge/BraveSpan.java | 6 ++++++ 3 files changed, 21 insertions(+) diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java index 7f3e2ab8c..74373c54d 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Span.java @@ -89,6 +89,16 @@ public interface Span extends SpanCustomizer { */ void abandon(); + /** + * Sets the remote service name for the span. + * @param remoteServiceName remote service name + * @return this span + * @since 3.0.3 + */ + default Span remoteServiceName(String remoteServiceName) { + return this; + } + /** * Type of span. Can be used to specify additional relationships between spans in * addition to a parent/child relationship. diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java index 39f082734..e12d42b04 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpSpan.java @@ -72,4 +72,9 @@ class NoOpSpan implements Span { } + @Override + public Span remoteServiceName(String remoteServiceName) { + return this; + } + } diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java index 15b977be7..abf330535 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveSpan.java @@ -86,6 +86,12 @@ public class BraveSpan implements Span { this.delegate.abandon(); } + @Override + public Span remoteServiceName(String remoteServiceName) { + this.delegate.remoteServiceName(remoteServiceName); + return this; + } + @Override public String toString() { return this.delegate != null ? this.delegate.toString() : "null"; From 39617c6cf61e76947a4cdeb164b7d71c355e0beb Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 14 Apr 2021 13:25:13 +0000 Subject: [PATCH 61/78] Updated the project to work with jdk16 (#1902) * Updated the project to work with jdk16 * Updates build for jdk8 * Added tests --- .github/workflows/maven.yml | 35 +- .../instrument/web/client/WebClientTests.java | 5 +- .../LazyTraceScheduledThreadPoolExecutor.java | 128 +++-- .../LazyTraceThreadPoolTaskExecutor.java | 40 +- .../LazyTraceThreadPoolTaskScheduler.java | 27 +- .../async/ExecutorInstrumentorTests.java | 18 + ...TraceScheduledThreadPoolExecutorTests.java | 31 +- .../async/TraceAsyncIntegrationTests.java | 11 +- ...adPoolExecutorAnotherConstructorTests.java | 35 ++ ...TraceScheduledThreadPoolExecutorTests.java | 35 ++ .../TraceThreadPoolTaskExecutorTests.java | 35 ++ .../TraceThreadPoolTaskSchedulerTests.java | 35 ++ ...LazyTraceThreadPoolTaskSchedulerTests.java | 4 +- ...adPoolExecutorAnotherConstructorTests.java | 44 ++ ...TraceScheduledThreadPoolExecutorTests.java | 355 ++++++++++++ .../TraceThreadPoolTaskExecutorTests.java | 234 ++++++++ .../TraceThreadPoolTaskSchedulerTests.java | 527 ++++++++++++++++++ .../integration/sampled/WebClientTests.java | 3 +- .../SleuthContextListenerAccessor.java | 0 19 files changed, 1514 insertions(+), 88 deletions(-) create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskExecutorTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskSchedulerTests.java create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorTests.java create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskExecutorTests.java create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskSchedulerTests.java rename tests/common/src/main/java/org/springframework/cloud/sleuth/{instrument/async => internal}/SleuthContextListenerAccessor.java (100%) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 32d179893..8b5ff26b1 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,6 +1,3 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - name: Build on: @@ -13,19 +10,23 @@ jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + java: ["8", "11", "16"] steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Cache local Maven repository - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build with Maven - run: ./mvnw clean install -B -U \ No newline at end of file + - uses: actions/checkout@v2 + - name: Setup java + uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: ${{ matrix.java }} + - name: Cache local Maven repository + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Build with Maven + run: ./mvnw clean install -B -U diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java index 665832d98..d874d7544 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/WebClientTests.java @@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.client; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Future; +import java.util.stream.Collectors; import brave.Span; import brave.Tracer; @@ -104,7 +105,7 @@ public class WebClientTests { then(this.tracer.currentSpan()).isNull(); then(this.spans).isNotEmpty().extracting("traceId", String.class).containsOnly(span.context().traceIdString()); - then(this.spans).extracting("kind.name").contains("CLIENT"); + then(this.spans.spans().stream().map(s -> s.kind().name()).collect(Collectors.toList())).contains("CLIENT"); } @Test @@ -140,7 +141,7 @@ public class WebClientTests { then(this.tracer.currentSpan()).isNull(); then(this.spans).isNotEmpty().extracting("traceId", String.class).containsOnly(span.context().traceIdString()); - then(this.spans).extracting("kind.name").contains("CLIENT"); + then(this.spans.spans().stream().map(s -> s.kind().name()).collect(Collectors.toList())).contains("CLIENT"); } @Configuration(proxyBeanMethods = false) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java index c75331036..b8d534f65 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutor.java @@ -66,8 +66,6 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { private final Method decorateTaskCallable; - private final Method finalize; - private final Method beforeExecute; private final Method afterExecute; @@ -88,32 +86,66 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { this.beanFactory = beanFactory; this.delegate = delegate; this.beanName = beanName; - this.decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + Method decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Runnable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskRunnable); - this.decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + this.decorateTaskRunnable = makeAccessibleIfNotNullAndOverridden(decorateTaskRunnable); + Method decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Callable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskCallable); - this.finalize = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "finalize", null); - makeAccessibleIfNotNull(this.finalize); - this.beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); - makeAccessibleIfNotNull(this.beforeExecute); - this.afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); - makeAccessibleIfNotNull(this.afterExecute); - this.terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated", null); - makeAccessibleIfNotNull(this.terminated); - this.newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.decorateTaskCallable = makeAccessibleIfNotNullAndOverridden(decorateTaskCallable); + Method beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); + this.beforeExecute = makeAccessibleIfNotNullAndOverridden(beforeExecute); + Method afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); + this.afterExecute = makeAccessibleIfNotNullAndOverridden(afterExecute); + Method terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated", null); + this.terminated = makeAccessibleIfNotNullAndOverridden(terminated); + Method newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Runnable.class, Object.class); - makeAccessibleIfNotNull(this.newTaskForRunnable); - this.newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.newTaskForRunnable = makeAccessibleIfNotNullAndOverridden(newTaskForRunnable); + Method newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Callable.class); - makeAccessibleIfNotNull(this.newTaskForCallable); + this.newTaskForCallable = makeAccessibleIfNotNullAndOverridden(newTaskForCallable); } - private void makeAccessibleIfNotNull(Method method) { + private Method makeAccessibleIfNotNullAndOverridden(Method method) { if (method != null) { - ReflectionUtils.makeAccessible(method); + if (isMethodOverridden(method)) { + try { + ReflectionUtils.makeAccessible(method); + return method; + } + catch (Throwable ex) { + if (anyCauseIsInaccessibleObjectException(ex)) { + throw new IllegalStateException("The executor [" + this.delegate.getClass() + + "] has overridden a method with name [" + method.getName() + + "] and the object is inaccessible. You have to run your JVM with [--add-opens] switch to allow such access. Example: [--add-opens java.base/java.util.concurrent=ALL-UNNAMED].", + ex); + } + throw ex; + } + } } + return null; + } + + private boolean anyCauseIsInaccessibleObjectException(Throwable t) { + Throwable parent = t; + Throwable cause = t.getCause(); + while (cause != null && cause != parent) { + if (cause.getClass().toString().contains("InaccessibleObjectException")) { + return true; + } + parent = cause; + cause = parent.getCause(); + } + return false; + } + + boolean isMethodOverridden(Method originalMethod) { + Method delegateMethod = ReflectionUtils.findMethod(this.delegate.getClass(), originalMethod.getName()); + if (delegateMethod == null) { + return false; + } + return !delegateMethod.equals(originalMethod); } LazyTraceScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, @@ -123,26 +155,24 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { this.beanFactory = beanFactory; this.delegate = delegate; this.beanName = beanName; - this.decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + Method decorateTaskRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Runnable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskRunnable); - this.decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", + this.decorateTaskRunnable = makeAccessibleIfNotNullAndOverridden(decorateTaskRunnable); + Method decorateTaskCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "decorateTask", Callable.class, RunnableScheduledFuture.class); - makeAccessibleIfNotNull(this.decorateTaskCallable); - this.finalize = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "finalize", null); - makeAccessibleIfNotNull(this.finalize); - this.beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); - makeAccessibleIfNotNull(this.beforeExecute); - this.afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); - makeAccessibleIfNotNull(this.afterExecute); - this.terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated"); - makeAccessibleIfNotNull(this.terminated); - this.newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.decorateTaskCallable = makeAccessibleIfNotNullAndOverridden(decorateTaskCallable); + Method beforeExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "beforeExecute", null); + this.beforeExecute = makeAccessibleIfNotNullAndOverridden(beforeExecute); + Method afterExecute = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "afterExecute", null); + this.afterExecute = makeAccessibleIfNotNullAndOverridden(afterExecute); + Method terminated = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "terminated", null); + this.terminated = makeAccessibleIfNotNullAndOverridden(terminated); + Method newTaskForRunnable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Runnable.class, Object.class); - makeAccessibleIfNotNull(this.newTaskForRunnable); - this.newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", + this.newTaskForRunnable = makeAccessibleIfNotNullAndOverridden(newTaskForRunnable); + Method newTaskForCallable = ReflectionUtils.findMethod(ScheduledThreadPoolExecutor.class, "newTaskFor", Callable.class); - makeAccessibleIfNotNull(this.newTaskForCallable); + this.newTaskForCallable = makeAccessibleIfNotNullAndOverridden(newTaskForCallable); } private Runnable traceRunnableWhenContextReady(Runnable delegate) { @@ -166,6 +196,9 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override @SuppressWarnings("unchecked") public RunnableScheduledFuture decorateTask(Runnable runnable, RunnableScheduledFuture task) { + if (this.decorateTaskRunnable == null) { + return super.decorateTask(traceRunnableWhenContextReady(runnable), task); + } return (RunnableScheduledFuture) ReflectionUtils.invokeMethod(this.decorateTaskRunnable, this.delegate, traceRunnableWhenContextReady(runnable), task); } @@ -173,6 +206,9 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override @SuppressWarnings("unchecked") public RunnableScheduledFuture decorateTask(Callable callable, RunnableScheduledFuture task) { + if (this.decorateTaskCallable == null) { + return super.decorateTask(traceCallableWhenContextReady(callable), task); + } return (RunnableScheduledFuture) ReflectionUtils.invokeMethod(this.decorateTaskCallable, this.delegate, traceCallableWhenContextReady(callable), task); } @@ -358,7 +394,7 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override public boolean remove(Runnable task) { - return this.delegate.remove(task); + return this.delegate.remove(traceRunnableWhenContextReady(task)); } @Override @@ -398,22 +434,37 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override public void beforeExecute(Thread t, Runnable r) { + if (this.beforeExecute == null) { + super.beforeExecute(t, traceRunnableWhenContextReady(r)); + return; + } ReflectionUtils.invokeMethod(this.beforeExecute, this.delegate, t, traceRunnableWhenContextReady(r)); } @Override public void afterExecute(Runnable r, Throwable t) { + if (this.afterExecute == null) { + super.afterExecute(traceRunnableWhenContextReady(r), t); + return; + } ReflectionUtils.invokeMethod(this.afterExecute, this.delegate, traceRunnableWhenContextReady(r), t); } @Override public void terminated() { + if (this.terminated == null) { + super.terminated(); + return; + } ReflectionUtils.invokeMethod(this.terminated, this.delegate); } @Override @SuppressWarnings("unchecked") public RunnableFuture newTaskFor(Runnable runnable, T value) { + if (this.newTaskForRunnable == null) { + return super.newTaskFor(traceRunnableWhenContextReady(runnable), value); + } return (RunnableFuture) ReflectionUtils.invokeMethod(this.newTaskForRunnable, this.delegate, traceRunnableWhenContextReady(runnable), value); } @@ -421,6 +472,9 @@ class LazyTraceScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { @Override @SuppressWarnings("unchecked") public RunnableFuture newTaskFor(Callable callable) { + if (this.newTaskForRunnable == null) { + return super.newTaskFor(traceCallableWhenContextReady(callable)); + } return (RunnableFuture) ReflectionUtils.invokeMethod(this.newTaskForCallable, this.delegate, traceCallableWhenContextReady(callable)); } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java index fe41d2698..0a5ad92ee 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskExecutor.java @@ -70,38 +70,32 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { @Override public void execute(Runnable task) { - this.delegate.execute(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName)); + this.delegate.execute(wrap(task)); } @Override public void execute(Runnable task, long startTimeout) { - this.delegate.execute(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName), startTimeout); + this.delegate.execute(wrap(task), startTimeout); } @Override public Future submit(Runnable task) { - return this.delegate.submit(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submit(wrap(task)); } @Override public Future submit(Callable task) { - return this.delegate.submit(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceCallable<>(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submit(wrap(task)); } @Override public ListenableFuture submitListenable(Runnable task) { - return this.delegate.submitListenable(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceRunnable(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submitListenable(wrap(task)); } @Override public ListenableFuture submitListenable(Callable task) { - return this.delegate.submitListenable(ContextUtil.isContextUnusable(this.beanFactory) ? task - : new TraceCallable<>(tracing(), spanNamer(), task, this.beanName)); + return this.delegate.submitListenable(wrap(task)); } @Override @@ -174,7 +168,23 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { @Override public Thread newThread(Runnable runnable) { - return this.delegate.newThread(runnable); + return this.delegate.newThread(wrap(runnable)); + } + + private Runnable wrap(Runnable runnable) { + if (runnable instanceof TraceRunnable) { + return runnable; + } + return ContextUtil.isContextUnusable(this.beanFactory) ? runnable + : new TraceRunnable(tracer(), spanNamer(), runnable, this.beanName); + } + + private Callable wrap(Callable callable) { + if (callable instanceof TraceCallable) { + return callable; + } + return ContextUtil.isContextUnusable(this.beanFactory) ? callable + : new TraceCallable<>(tracer(), spanNamer(), callable, this.beanName); } @Override @@ -224,7 +234,7 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { @Override public Thread createThread(Runnable runnable) { - return this.delegate.createThread(runnable); + return this.delegate.createThread(wrap(runnable)); } @Override @@ -272,7 +282,7 @@ public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { this.delegate.setTaskDecorator(taskDecorator); } - private Tracer tracing() { + private Tracer tracer() { if (this.tracer == null) { this.tracer = this.beanFactory.getBean(Tracer.class); } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java index e82266921..136ef830a 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskScheduler.java @@ -28,6 +28,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -106,6 +107,9 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { if (ContextUtil.isContextUnusable(this.beanFactory)) { return delegate; } + if (delegate instanceof TraceRunnable) { + return delegate; + } return new TraceRunnable(tracing(), spanNamer(), delegate, this.beanName); } @@ -113,6 +117,9 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { if (ContextUtil.isContextUnusable(this.beanFactory)) { return delegate; } + if (delegate instanceof TraceCallable) { + return delegate; + } return new TraceCallable<>(tracing(), spanNamer(), delegate, this.beanName); } @@ -135,15 +142,25 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { public ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) { ExecutorService executorService = (ExecutorService) ReflectionUtils.invokeMethod(this.initializeExecutor, - this.delegate, traceThreadFactory(threadFactory), rejectedExecutionHandler); + this.delegate, traceThreadFactory(threadFactory), + traceRejectedExecutionHandler(rejectedExecutionHandler)); if (executorService instanceof TraceableScheduledExecutorService) { return executorService; } return new TraceableExecutorService(this.beanFactory, executorService, this.beanName); } + private RejectedExecutionHandler traceRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) { + return new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + rejectedExecutionHandler.rejectedExecution(traceRunnableWhenContextReady(r), executor); + } + }; + } + private ThreadFactory traceThreadFactory(ThreadFactory threadFactory) { - return r -> threadFactory.newThread(new TraceRunnable(tracing(), spanNamer(), r, this.beanName)); + return r -> threadFactory.newThread(traceRunnableWhenContextReady(r)); } @Override @@ -151,7 +168,7 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { RejectedExecutionHandler rejectedExecutionHandler) { ScheduledExecutorService executorService = (ScheduledExecutorService) ReflectionUtils.invokeMethod( this.createExecutor, this.delegate, poolSize, traceThreadFactory(threadFactory), - rejectedExecutionHandler); + traceRejectedExecutionHandler(rejectedExecutionHandler)); if (executorService instanceof TraceableScheduledExecutorService) { return executorService; } @@ -313,7 +330,7 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { @Override public Thread newThread(Runnable runnable) { - return this.delegate.newThread(runnable); + return this.delegate.newThread(traceRunnableWhenContextReady(runnable)); } @Override @@ -359,7 +376,7 @@ class LazyTraceThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { @Override public Thread createThread(Runnable runnable) { - return this.delegate.createThread(runnable); + return this.delegate.createThread(traceRunnableWhenContextReady(runnable)); } @Override diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java index cfc61bd3b..dfed086bb 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/ExecutorInstrumentorTests.java @@ -36,6 +36,8 @@ import org.aopalliance.aop.Advice; import org.assertj.core.api.BDDAssertions; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.BDDMockito; import org.mockito.Mock; @@ -294,6 +296,7 @@ public class ExecutorInstrumentorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_use_cglib_proxy_when_an_executor_has_a_final_package_protected_method() { ExecutorInstrumentor beanPostProcessor = new ExecutorInstrumentor(Collections::emptyList, beanFactory); ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10); @@ -307,6 +310,21 @@ public class ExecutorInstrumentorTests { Awaitility.await().untilAsserted(() -> BDDAssertions.then(wasCalled).isTrue()); } + @Test + @EnabledForJreRange(min = JRE.JAVA_16) + public void should_use_jdk_proxy_when_an_executor_has_a_final_package_protected_method() { + ExecutorInstrumentor beanPostProcessor = new ExecutorInstrumentor(Collections::emptyList, beanFactory); + ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10); + ScheduledThreadPoolExecutor wrappedExecutor = (ScheduledThreadPoolExecutor) beanPostProcessor + .instrument(executor, "executor"); + + BDDAssertions.then(AopUtils.isCglibProxy(wrappedExecutor)).isFalse(); + + AtomicBoolean wasCalled = new AtomicBoolean(false); + wrappedExecutor.execute(() -> wasCalled.set(true)); + Awaitility.await().untilAsserted(() -> BDDAssertions.then(wasCalled).isTrue()); + } + @Test public void should_use_jdk_proxy_when_executor_service_has_final_methods() throws Exception { ExecutorInstrumentor beanPostProcessor = new ExecutorInstrumentor(Collections::emptyList, beanFactory); diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java index 0ace63e7f..8dc98bc85 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceScheduledThreadPoolExecutorTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.async; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -34,8 +35,11 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; +import org.mockito.BDDMockito; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -92,6 +96,14 @@ public class LazyTraceScheduledThreadPoolExecutorTests { boolean isContextUnusable() { return false; } + + @Override + boolean isMethodOverridden(Method originalMethod) { + if (JRE.currentVersion().ordinal() >= JRE.JAVA_16.ordinal()) { + return false; + } + return true; + } }); } @@ -107,13 +119,22 @@ public class LazyTraceScheduledThreadPoolExecutorTests { }; BeanFactory beanFactory = mock(BeanFactory.class); - new LazyTraceScheduledThreadPoolExecutor(10, beanFactory, executor, null).finalize(); + new LazyTraceScheduledThreadPoolExecutor(10, beanFactory, executor, null) { + @Override + boolean isMethodOverridden(Method originalMethod) { + if (JRE.currentVersion().ordinal() >= JRE.JAVA_16.ordinal()) { + return false; + } + return true; + } + }.finalize(); BDDAssertions.then(wasCalled).isFalse(); BDDAssertions.then(executor.isShutdown()).isFalse(); } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_decorateTask_with_runnable() { final Runnable runnable = mock(Runnable.class); final RunnableScheduledFuture value = mock(RunnableScheduledFuture.class); @@ -128,6 +149,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_decorateTask_with_callable() { final Callable callable = mock(Callable.class); final RunnableScheduledFuture value = mock(RunnableScheduledFuture.class); @@ -511,7 +533,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { executor.remove(expected); - verify(delegate).remove(expected); + verify(delegate).remove(BDDMockito.isA(TraceRunnable.class)); } @Test @@ -582,6 +604,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_beforeExecute() { final Thread thread = mock(Thread.class); final Runnable expected = mock(Runnable.class); @@ -593,6 +616,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_afterExecute() { final Throwable throwable = mock(Throwable.class); final Runnable expected = mock(Runnable.class); @@ -604,6 +628,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_terminated() { executor.terminated(); @@ -611,6 +636,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_newTaskForRunnable() { final Runnable runnable = mock(Runnable.class); final String expected = "testing"; @@ -625,6 +651,7 @@ public class LazyTraceScheduledThreadPoolExecutorTests { } @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_15) public void should_delegate_newTaskForCallable() { final Callable callable = mock(Callable.class); final RunnableFuture expected = mock(RunnableFuture.class); diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java index 22781b012..0f5afefd6 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceAsyncIntegrationTests.java @@ -78,9 +78,8 @@ public class TraceAsyncIntegrationTests { assertThat(span.traceId()).isEqualTo(context.traceIdString()); } finally { - parent.finish(); + parent.abandon(); } - } @Test @@ -100,7 +99,7 @@ public class TraceAsyncIntegrationTests { assertThat(span.traceId()).isEqualTo(context.traceIdString()); } finally { - parent.finish(); + parent.abandon(); } } @@ -108,10 +107,8 @@ public class TraceAsyncIntegrationTests { // We don't want that one. MutableSpan takeDesirableSpan(String name) { MutableSpan span1 = spans.takeLocalSpan(); - MutableSpan span2 = spans.takeLocalSpan(); - log.info("Two last spans [" + span2 + "] and [" + span1 + "]"); - MutableSpan span = span1 != null && name.equals(span1.name()) ? span1 - : span2 != null && name.equals(span2.name()) ? span2 : null; + log.info("Span [" + span1 + "] found"); + MutableSpan span = span1 != null && name.equals(span1.name()) ? span1 : null; assertThat(span).as("No span with name <> was found", name).isNotNull(); return span; } diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java new file mode 100644 index 000000000..6fe688f58 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceScheduledThreadPoolExecutorAnotherConstructorTests extends + org.springframework.cloud.sleuth.instrument.async.TraceScheduledThreadPoolExecutorAnotherConstructorTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorTests.java new file mode 100644 index 000000000..397e963fe --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceScheduledThreadPoolExecutorTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceScheduledThreadPoolExecutorTests + extends org.springframework.cloud.sleuth.instrument.async.TraceScheduledThreadPoolExecutorTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskExecutorTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskExecutorTests.java new file mode 100644 index 000000000..2f2df4800 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskExecutorTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceThreadPoolTaskExecutorTests + extends org.springframework.cloud.sleuth.instrument.async.TraceThreadPoolTaskExecutorTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskSchedulerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskSchedulerTests.java new file mode 100644 index 000000000..4d990fdfa --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/async/TraceThreadPoolTaskSchedulerTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.async; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class TraceThreadPoolTaskSchedulerTests + extends org.springframework.cloud.sleuth.instrument.async.TraceThreadPoolTaskSchedulerTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java index c75511d6b..3aa01c258 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/LazyTraceThreadPoolTaskSchedulerTests.java @@ -343,7 +343,7 @@ public abstract class LazyTraceThreadPoolTaskSchedulerTests implements TestTraci }; this.executor.newThread(runnable); - BDDMockito.then(this.delegate).should().newThread(runnable); + BDDMockito.then(this.delegate).should().newThread(BDDMockito.isA(TraceRunnable.class)); } @Test @@ -409,7 +409,7 @@ public abstract class LazyTraceThreadPoolTaskSchedulerTests implements TestTraci }; this.executor.createThread(r); - BDDMockito.then(this.delegate).should().createThread(r); + BDDMockito.then(this.delegate).should().createThread(BDDMockito.isA(TraceRunnable.class)); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java new file mode 100644 index 000000000..bd659a8f9 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorAnotherConstructorTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.async; + +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceScheduledThreadPoolExecutorAnotherConstructorTests + extends TraceScheduledThreadPoolExecutorTests { + + @Override + protected LazyTraceScheduledThreadPoolExecutor executor() { + return new LazyTraceScheduledThreadPoolExecutor(1, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r); + } + }, new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + + } + }, beanFactory, delegate, "foo"); + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorTests.java new file mode 100644 index 000000000..989ed5a90 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceScheduledThreadPoolExecutorTests.java @@ -0,0 +1,355 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.async; + +import java.util.concurrent.Callable; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; +import org.springframework.cloud.sleuth.internal.SleuthContextListenerAccessor; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceScheduledThreadPoolExecutorTests implements TestTracingAwareSupplier { + + ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); + + BeanFactory beanFactory = beanFactory(); + + LazyTraceScheduledThreadPoolExecutor traceThreadPoolTaskExecutor = executor(); + + protected LazyTraceScheduledThreadPoolExecutor executor() { + return new LazyTraceScheduledThreadPoolExecutor(1, this.beanFactory, this.delegate, "foo"); + } + + @BeforeEach + void setup() { + SleuthContextListenerAccessor.set(this.beanFactory, true); + } + + @AfterEach + void clear() { + this.delegate.shutdown(); + } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = BDDMockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(tracerTest().tracing().tracer()); + BDDMockito.given(beanFactory.getBean(SpanNamer.class)).willReturn(new DefaultSpanNamer()); + return beanFactory; + } + + @Test + public void should_schedule_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), 1, TimeUnit.MILLISECONDS).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_decorate_task_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + Runnable runnable = aRunnable(executed, span); + this.traceThreadPoolTaskExecutor.decorateTask(runnable, runnableScheduledFuture(runnable)).run(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_decorate_task_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + RunnableScheduledFuture fromCallable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + Callable callable = aCallable(span); + fromCallable = this.traceThreadPoolTaskExecutor.decorateTask(callable, runnableScheduledFuture(callable)); + fromCallable.run(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(fromCallable.get(10, TimeUnit.MILLISECONDS)).isNotNull(); + }); + } + + private RunnableScheduledFuture runnableScheduledFuture(Callable run) { + return new RunnableScheduledFuture() { + + private Span result; + + @Override + public boolean isPeriodic() { + return false; + } + + @Override + public long getDelay(TimeUnit unit) { + return 0; + } + + @Override + public int compareTo(Delayed o) { + return 0; + } + + @Override + public void run() { + try { + this.result = run.call(); + } + catch (Exception exception) { + } + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return false; + } + + @Override + public Span get() throws InterruptedException, ExecutionException { + return this.result; + } + + @Override + public Span get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return this.result; + } + }; + } + + private RunnableScheduledFuture runnableScheduledFuture(Runnable run) { + return new RunnableScheduledFuture() { + + @Override + public boolean isPeriodic() { + return false; + } + + @Override + public long getDelay(TimeUnit unit) { + return 0; + } + + @Override + public int compareTo(Delayed o) { + return 0; + } + + @Override + public void run() { + run.run(); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return false; + } + + @Override + public Object get() throws InterruptedException, ExecutionException { + return null; + } + + @Override + public Object get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return null; + } + }; + } + + @Test + public void should_schedule_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromCallable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromCallable = this.traceThreadPoolTaskExecutor.schedule(aCallable(span), 1, TimeUnit.MILLISECONDS) + .get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromCallable).isNotNull(); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), 1L, 1L, + TimeUnit.MILLISECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), 1L, 1L, + TimeUnit.MILLISECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_execute_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submit(aCallable(span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromListenable).isNotNull(); + } + + @Test + public void should_submit_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + Runnable aRunnable(AtomicBoolean executed, Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span).isNotNull(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + executed.set(true); + }; + } + + Callable aCallable(Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + return span; + }; + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskExecutorTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskExecutorTests.java new file mode 100644 index 000000000..45539d12b --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskExecutorTests.java @@ -0,0 +1,234 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.async; + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.assertj.core.api.BDDAssertions; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; +import org.springframework.cloud.sleuth.internal.SleuthContextListenerAccessor; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceThreadPoolTaskExecutorTests implements TestTracingAwareSupplier { + + ThreadPoolTaskExecutor delegate = new ThreadPoolTaskExecutor(); + + BeanFactory beanFactory = beanFactory(); + + LazyTraceThreadPoolTaskExecutor traceThreadPoolTaskExecutor = new LazyTraceThreadPoolTaskExecutor(this.beanFactory, + this.delegate); + + @BeforeEach + void setup() { + this.delegate.initialize(); + SleuthContextListenerAccessor.set(this.beanFactory, true); + } + + @AfterEach + void clear() { + this.delegate.shutdown(); + } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = BDDMockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(tracerTest().tracing().tracer()); + BDDMockito.given(beanFactory.getBean(SpanNamer.class)).willReturn(new DefaultSpanNamer()); + return beanFactory; + } + + @Test + public void should_create_thread_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_listenable_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submitListenable(aRunnable(executed, span)).get(); + } + finally { + span.end(); + } + + BDDAssertions.then(executed.get()).isTrue(); + } + + @Test + public void should_submit_listenable_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submitListenable(aCallable(span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + BDDAssertions.then(spanFromListenable).isNotNull(); + } + + @Test + public void should_execute_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_execute_with_timeout_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submit(aCallable(span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + BDDAssertions.then(spanFromListenable).isNotNull(); + } + + @Test + public void should_submit_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_new_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.newThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_create_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + BDDAssertions.then(executed.get()).isTrue(); + }); + } + + Runnable aRunnable(AtomicBoolean executed, Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + BDDAssertions.then(span).isNotNull(); + BDDAssertions.then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + executed.set(true); + }; + } + + Callable aCallable(Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + BDDAssertions.then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + return span; + }; + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskSchedulerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskSchedulerTests.java new file mode 100644 index 000000000..5c2716f76 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceThreadPoolTaskSchedulerTests.java @@ -0,0 +1,527 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.async; + +import java.sql.Date; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.Callable; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; +import org.springframework.cloud.sleuth.internal.SleuthContextListenerAccessor; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.TriggerContext; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public abstract class TraceThreadPoolTaskSchedulerTests implements TestTracingAwareSupplier { + + ThreadPoolTaskScheduler delegate = new ThreadPoolTaskScheduler(); + + BeanFactory beanFactory = beanFactory(); + + LazyTraceThreadPoolTaskScheduler traceThreadPoolTaskExecutor = new LazyTraceThreadPoolTaskScheduler( + this.beanFactory, this.delegate, "foo"); + + @BeforeEach + void setup() { + this.delegate.initialize(); + SleuthContextListenerAccessor.set(this.beanFactory, true); + } + + @AfterEach + void clear() { + this.delegate.shutdown(); + } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = BDDMockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(tracerTest().tracing().tracer()); + BDDMockito.given(beanFactory.getBean(SpanNamer.class)).willReturn(new DefaultSpanNamer()); + return beanFactory; + } + + @Test + public void should_initialize_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.initializeExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r); + } + }, new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + + } + }).submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_create_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createExecutor(1, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r); + } + }, new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + + } + }).submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_get_scheduled_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.getScheduledExecutor().submit(aRunnable(executed, span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_get_scheduled_thread_pool_wrapped_executor() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.getScheduledThreadPoolExecutor().submit(aRunnable(executed, span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_create_thread_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), Instant.now()).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_schedule_trace_runnable_with_start_time() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), Date.from(Instant.now())).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_schedule_trace_runnable_with_trigger() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.schedule(aRunnable(executed, span), new Trigger() { + @Override + public java.util.Date nextExecutionTime(TriggerContext triggerContext) { + return java.util.Date.from(Instant.now()); + } + }).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(executed.get()).isTrue(); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable_with_date() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), Date.from(Instant.now()), + 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable_with_instant() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), Instant.now(), + Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_at_fixed_rate_trace_runnable_with_duration() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleAtFixedRate(aRunnable(executed, span), Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable_with_date() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), Date.from(Instant.now()), + 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable_with_instant() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), Instant.now(), + Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_schedule_with_fixed_delay_trace_runnable_with_duration() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.scheduleWithFixedDelay(aRunnable(executed, span), Duration.ofMillis(10)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_listenable_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submitListenable(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_listenable_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submitListenable(aCallable(span)).get(1, + TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromListenable).isNotNull(); + } + + @Test + public void should_execute_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span)); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_execute_with_timeout_a_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.execute(aRunnable(executed, span), 1L); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_callable() throws Exception { + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + Span spanFromListenable; + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + spanFromListenable = this.traceThreadPoolTaskExecutor.submit(aCallable(span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + then(spanFromListenable).isNotNull(); + } + + @Test + public void should_submit_trace_runnable() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.submit(aRunnable(executed, span)).get(1, TimeUnit.SECONDS); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_new_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.newThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + @Test + public void should_submit_trace_runnable_via_create_thread() throws Exception { + AtomicBoolean executed = new AtomicBoolean(); + Span span = tracerTest().tracing().tracer().nextSpan().name("foo"); + + try (Tracer.SpanInScope ws = tracerTest().tracing().tracer().withSpan(span.start())) { + this.traceThreadPoolTaskExecutor.createThread(aRunnable(executed, span)).start(); + } + finally { + span.end(); + } + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + then(executed.get()).isTrue(); + }); + } + + Runnable aRunnable(AtomicBoolean executed, Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span).isNotNull(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + executed.set(true); + }; + } + + Callable aCallable(Span currentSpan) { + return () -> { + Span span = tracerTest().tracing().tracer().currentSpan(); + then(span.context().traceId()).isEqualTo(currentSpan.context().traceId()); + return span; + }; + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java index bebe8d0fd..89fad7d8f 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/integration/sampled/WebClientTests.java @@ -356,7 +356,8 @@ public abstract class WebClientTests { } thenThereIsNoCurrentSpan(); then(this.customizer.isExecuted()).isTrue(); - then(this.spans).extracting("kind.name").contains("CLIENT"); + then(this.spans.reportedSpans().stream().filter(s -> s.getKind() != null).map(s -> s.getKind().name()) + .collect(Collectors.toList())).contains("CLIENT"); } @Test diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthContextListenerAccessor.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java similarity index 100% rename from tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/async/SleuthContextListenerAccessor.java rename to tests/common/src/main/java/org/springframework/cloud/sleuth/internal/SleuthContextListenerAccessor.java From 4ede1ae5b0c148c5098688916b0b7891dd2cf722 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 16 Apr 2021 10:36:22 +0200 Subject: [PATCH 62/78] Update bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 215934a9a..813d3b5cf 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,6 +12,6 @@ Please provide details of the problem, including the version of Spring Cloud tha are using. **Sample** -If possible, please provide a test case or a minimal sample **Java** application that reproduces +If possible, please provide a test case or a minimal **Maven** sample written in **Java** that reproduces the problem. This makes it much easier for us to diagnose the problem and to verify that we have fixed it. From 9bd6c2e29bf0db613332eda634910e46d596a342 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 16 Apr 2021 12:20:34 +0200 Subject: [PATCH 63/78] Ensures that for decorate_hooks we add onLast instrumentation; fixes gh-1900 --- .../instrument/reactor/TraceReactorAutoConfiguration.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java index b7dd50fd1..a4bc41fa7 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/TraceReactorAutoConfiguration.java @@ -148,6 +148,7 @@ class HooksRefresher implements ApplicationListener log.trace("Adding queue wrapper instrumentation"); } HookRegisteringBeanDefinitionRegistryPostProcessor.addQueueWrapper(context); + Hooks.onLastOperator(SLEUTH_TRACE_REACTOR_KEY, ReactorSleuth.scopePassingSpanOperator(this.context)); Schedulers.onScheduleHook(TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY, ReactorSleuth.scopePassingOnScheduleHook(this.context)); } @@ -207,6 +208,7 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor implements BeanDefiniti } if (property == SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES) { addQueueWrapper(springContext); + decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext)); decorateScheduler(springContext); } else { From 911fb4838a091abe6d4da4a1f6a55682906715e5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 20 Apr 2021 08:53:38 +0200 Subject: [PATCH 64/78] 3.1.0 initial commit --- benchmarks/pom.xml | 2 +- docs/pom.xml | 2 +- pom.xml | 2 +- spring-cloud-sleuth-api/pom.xml | 2 +- spring-cloud-sleuth-autoconfigure/pom.xml | 2 +- spring-cloud-sleuth-brave/pom.xml | 2 +- spring-cloud-sleuth-dependencies/pom.xml | 2 +- spring-cloud-sleuth-instrumentation/pom.xml | 2 +- spring-cloud-sleuth-samples/pom.xml | 2 +- .../spring-cloud-sleuth-sample-feign/pom.xml | 2 +- .../spring-cloud-sleuth-sample-messaging/pom.xml | 2 +- .../spring-cloud-sleuth-sample-test-core/pom.xml | 2 +- .../spring-cloud-sleuth-sample-websocket/pom.xml | 2 +- .../spring-cloud-sleuth-sample-zipkin/pom.xml | 2 +- spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml | 2 +- spring-cloud-sleuth-zipkin/pom.xml | 2 +- spring-cloud-starter-sleuth/pom.xml | 2 +- tests/brave/pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-async-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-feign-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml | 2 +- .../brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml | 2 +- .../pom.xml | 2 +- .../spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml | 2 +- tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml | 2 +- tests/common/pom.xml | 2 +- tests/pom.xml | 2 +- 36 files changed, 36 insertions(+), 36 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 34d1d4cd7..d7b910b9a 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -22,7 +22,7 @@ Benchmarks Benchmarks (JMH) org.springframework.cloud - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT benchmarks diff --git a/docs/pom.xml b/docs/pom.xml index f300fba2f..cf86faac6 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -21,7 +21,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT spring-cloud-sleuth-docs jar diff --git a/pom.xml b/pom.xml index 9b3809505..2fb7cb011 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 4.0.0 spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT pom Spring Cloud Sleuth Spring Cloud Sleuth diff --git a/spring-cloud-sleuth-api/pom.xml b/spring-cloud-sleuth-api/pom.xml index 223117cbd..59766a458 100644 --- a/spring-cloud-sleuth-api/pom.xml +++ b/spring-cloud-sleuth-api/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index a934b5b15..15f4a93a0 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-brave/pom.xml b/spring-cloud-sleuth-brave/pom.xml index c3bb99eaf..1069e4dbe 100644 --- a/spring-cloud-sleuth-brave/pom.xml +++ b/spring-cloud-sleuth-brave/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index 1e06ac341..3f2160aa4 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -26,7 +26,7 @@ spring-cloud-sleuth-dependencies - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT pom spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 0b4f970a9..f049e8a35 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/pom.xml b/spring-cloud-sleuth-samples/pom.xml index 55161d7bc..db7df8acb 100644 --- a/spring-cloud-sleuth-samples/pom.xml +++ b/spring-cloud-sleuth-samples/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml index 09402560f..14012ee1d 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml index ca51608fd..75b4574a8 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml index 5a68fc05d..438700c2d 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-test-core/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml index 802007fed..2114093a3 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-websocket/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml index 2f555a022..85e6b2855 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml index c5a00b133..e4bb17d81 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth-samples - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-sleuth-zipkin/pom.xml b/spring-cloud-sleuth-zipkin/pom.xml index 289913b92..69642bfdb 100644 --- a/spring-cloud-sleuth-zipkin/pom.xml +++ b/spring-cloud-sleuth-zipkin/pom.xml @@ -28,7 +28,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/spring-cloud-starter-sleuth/pom.xml b/spring-cloud-starter-sleuth/pom.xml index bc574d2d2..7cf9452ec 100644 --- a/spring-cloud-starter-sleuth/pom.xml +++ b/spring-cloud-starter-sleuth/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. spring-cloud-starter-sleuth diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index 9bf63fe26..eb3531c41 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml index 4582b2c81..4e2cd0abb 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml index f2949de3e..7bf3f3a3a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-async-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml index cddc90def..2516a9b57 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml index b2b6fbb9e..cb4d4ae68 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml index 7316615ab..7d7134fa4 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml index 87542def1..294339997 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml index 81c7a1911..5e9c81e38 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml index 6e5a5261e..bf14afc5c 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml index ce3d0c390..e688ab54b 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml index 6e497304f..3c0302cb6 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml index 8973c1d27..5f5f7a6a4 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml index c1c392076..3b16a8fea 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml index 5135bf12b..e5a18622d 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml index 83b00e163..da9a7a566 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml index 7b884de73..80245b044 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml index 02bee2432..5a6baad01 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests-brave - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/common/pom.xml b/tests/common/pom.xml index fc31548be..1b79278cb 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth-tests - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. diff --git a/tests/pom.xml b/tests/pom.xml index df2f5dcf9..04b8b898f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-sleuth - 3.0.3-SNAPSHOT + 3.1.0-SNAPSHOT .. From 1207be7f4d9cf3b73bed47ecf6fa46f509e3c4bf Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 20 Apr 2021 09:08:20 +0200 Subject: [PATCH 65/78] Trying to fix github actions --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8b5ff26b1..95ed48397 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -29,4 +29,4 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - name: Build with Maven - run: ./mvnw clean install -B -U + run: ./mvnw clean install -B -U -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false From f2bf396eba0c6a8d5fc91d2ac486a145b5a9dc01 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 20 Apr 2021 09:13:39 +0200 Subject: [PATCH 66/78] Fixes gh actions --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 95ed48397..d74eae027 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -2,9 +2,9 @@ name: Build on: push: - branches: [ master ] + branches: [ 3.1.x ] pull_request: - branches: [ master ] + branches: [ 3.1.x ] jobs: build: From 10c67d64e570e63678b1ab616555e1c92a15e50e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 20 Apr 2021 09:26:26 +0200 Subject: [PATCH 67/78] Removed test commons version --- .../spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml | 1 - .../spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml | 1 - .../pom.xml | 1 - .../spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml | 1 - .../spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml | 1 - .../spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml | 1 - .../spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml | 1 - .../spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml | 1 - tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml | 1 - 9 files changed, 9 deletions(-) diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml index 4582b2c81..b02280d30 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-annotation-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.boot diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml index cddc90def..7ea306790 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-baggage-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.boot diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml index b2b6fbb9e..5c5eacb35 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.boot diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml index 87542def1..7e1e1fd96 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-gateway-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.cloud diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml index ce3d0c390..e15c465d8 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.boot diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml index 8973c1d27..2aa483231 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-quartz-tests/pom.xml @@ -58,7 +58,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.cloud diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml index c1c392076..17242bdd6 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.boot diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml index 5135bf12b..023453497 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.cloud diff --git a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml index 02bee2432..db4b3420d 100644 --- a/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-zipkin-tests/pom.xml @@ -54,7 +54,6 @@ org.springframework.cloud spring-cloud-sleuth-tests-common - ${project.version} org.springframework.boot From 6e8f86ed352d167276cb957b17d757268832f516 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 20 Apr 2021 10:03:36 +0000 Subject: [PATCH 68/78] Adds support for SC CircuitBreaker Reactive (#1914) * Adds support for SC CircuitBreaker Reactive * Changes following the review * Lazilly initializes the TraceFunction * Updated version fixes gh-1910 --- docs/src/main/asciidoc/integrations.adoc | 2 +- .../TraceCircuitBreakerAutoConfiguration.java | 13 +- .../TraceCircuitBreakerFactoryAspect.java | 7 +- .../circuitbreaker/TraceFunction.java | 1 + .../TraceReactiveCircuitBreaker.java | 138 +++++++++++++++++ ...ceReactiveCircuitBreakerFactoryAspect.java | 45 ++++++ .../circuitbreaker/TraceSupplier.java | 1 + tests/brave/pom.xml | 1 + .../pom.xml | 89 +++++++++++ ...eactiveCircuitBreakerIntegrationTests.java | 60 +++++++ .../ReactiveCircuitBreakerTests.java | 43 ++++++ .../src/test/resources/application.yml | 5 + tests/common/pom.xml | 5 + ...eactiveCircuitBreakerIntegrationTests.java | 146 ++++++++++++++++++ .../ReactiveCircuitBreakerTests.java | 94 +++++++++++ 15 files changed, 641 insertions(+), 9 deletions(-) create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreakerFactoryAspect.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/pom.xml create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/resources/application.yml create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java diff --git a/docs/src/main/asciidoc/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc index b56360cb0..6da99eafc 100644 --- a/docs/src/main/asciidoc/integrations.adoc +++ b/docs/src/main/asciidoc/integrations.adoc @@ -565,5 +565,5 @@ IMPORTANT: The suggested approach to reactive programming and Sleuth is to use t This feature is available for all tracer implementations. -If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. +If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. We will also instrument the reactive implementation of the CircuitBreaker. In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`. \ No newline at end of file diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java index e80b7d20c..f724943c5 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/TraceCircuitBreakerAutoConfiguration.java @@ -21,10 +21,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; +import org.springframework.cloud.sleuth.CurrentTraceContext; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; import org.springframework.cloud.sleuth.instrument.circuitbreaker.TraceCircuitBreakerFactoryAspect; +import org.springframework.cloud.sleuth.instrument.circuitbreaker.TraceReactiveCircuitBreakerFactoryAspect; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,7 +37,6 @@ import org.springframework.context.annotation.Configuration; * @since 2.2.1 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass(CircuitBreaker.class) @ConditionalOnBean(Tracer.class) @ConditionalOnProperty(value = "spring.sleuth.circuitbreaker.enabled", matchIfMissing = true) @EnableConfigurationProperties(SleuthCircuitBreakerProperties.class) @@ -44,8 +44,17 @@ import org.springframework.context.annotation.Configuration; public class TraceCircuitBreakerAutoConfiguration { @Bean + @ConditionalOnClass(name = "org.springframework.cloud.client.circuitbreaker.CircuitBreaker") TraceCircuitBreakerFactoryAspect traceCircuitBreakerFactoryAspect(Tracer tracer) { return new TraceCircuitBreakerFactoryAspect(tracer); } + @Bean + @ConditionalOnClass(name = { "reactor.core.publisher.Mono", + "org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker" }) + TraceReactiveCircuitBreakerFactoryAspect traceReactiveCircuitBreakerFactoryAspect(Tracer tracer, + CurrentTraceContext currentTraceContext) { + return new TraceReactiveCircuitBreakerFactoryAspect(tracer, currentTraceContext); + } + } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java index d5f3fb3a5..32505fbc7 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceCircuitBreakerFactoryAspect.java @@ -19,7 +19,6 @@ package org.springframework.cloud.sleuth.instrument.circuitbreaker; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; import org.springframework.cloud.sleuth.Tracer; @@ -39,11 +38,7 @@ public class TraceCircuitBreakerFactoryAspect { this.tracer = tracer; } - @Pointcut("execution(public * org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory.create(..))") - private void anyCircuitBreakerFactoryCreate() { - } // NOSONAR - - @Around("anyCircuitBreakerFactoryCreate()") + @Around("execution(public * org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory.create(..))") public Object wrapFactory(ProceedingJoinPoint pjp) throws Throwable { CircuitBreaker circuitBreaker = (CircuitBreaker) pjp.proceed(); return new TraceCircuitBreaker(circuitBreaker, this.tracer); diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java index 361400b51..d5f8f6df8 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceFunction.java @@ -44,6 +44,7 @@ class TraceFunction implements Function { @Override public T apply(Throwable throwable) { + // TODO: This name needs to be better String name = this.delegate.getClass().getSimpleName(); Span span = this.span.get().name(name); Throwable tr = null; diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java new file mode 100644 index 000000000..b283db6e8 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java @@ -0,0 +1,138 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.circuitbreaker; + +import java.util.function.Function; +import java.util.function.Supplier; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.context.Context; + +import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; + +class TraceReactiveCircuitBreaker implements ReactiveCircuitBreaker { + + private static final Log log = LogFactory.getLog(TraceReactiveCircuitBreaker.class); + + private final ReactiveCircuitBreaker delegate; + + private final Tracer tracer; + + private final CurrentTraceContext currentTraceContext; + + TraceReactiveCircuitBreaker(ReactiveCircuitBreaker delegate, Tracer tracer, + CurrentTraceContext currentTraceContext) { + this.delegate = delegate; + this.tracer = tracer; + this.currentTraceContext = currentTraceContext; + } + + @Override + public Mono run(Mono toRun) { + return runAndTraceMono(() -> this.delegate.run(toRun)); + } + + @Override + public Mono run(Mono toRun, Function> fallback) { + return runAndTraceMono( + () -> this.delegate.run(toRun, fallback != null ? new TraceFunction<>(this.tracer, fallback) : null)); + } + + @Override + public Flux run(Flux toRun) { + return runAndTraceFlux(() -> this.delegate.run(toRun)); + } + + @Override + public Flux run(Flux toRun, Function> fallback) { + return runAndTraceFlux( + () -> this.delegate.run(toRun, fallback != null ? new TraceFunction<>(this.tracer, fallback) : null)); + } + + private Mono runAndTraceMono(Supplier> mono) { + return Mono.deferContextual(contextView -> { + Span span = contextView.get(Span.class); + Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); + return mono.get().doOnError(span::error).doFinally(signalType -> { + span.end(); + scope.close(); + }); + }).contextWrite(this::enhanceContext); + } + + private Flux runAndTraceFlux(Supplier> flux) { + return Flux.deferContextual(contextView -> { + Span span = contextView.get(Span.class); + Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); + return flux.get().doOnError(span::error).doFinally(signalType -> { + span.end(); + scope.close(); + }); + }).contextWrite(this::enhanceContext); + } + + private Span spanFromContext(reactor.util.context.Context context) { + TraceContext traceContext = context.getOrDefault(TraceContext.class, null); + Span span = null; + if (traceContext == null) { + span = context.getOrDefault(Span.class, null); + } + if (traceContext == null && span == null) { + span = this.tracer.nextSpan(); + if (log.isDebugEnabled()) { + log.debug("There was no previous span in reactor context, created a new one [" + span + "]"); + } + } + else if (traceContext != null) { + // there was a previous span - we create a child one + try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(traceContext)) { + if (log.isDebugEnabled()) { + log.debug("Found a trace context in reactor context [" + traceContext + "]"); + } + span = this.tracer.nextSpan(); + if (log.isDebugEnabled()) { + log.debug("Created a child span [" + span + "]"); + } + } + } + else { + if (log.isDebugEnabled()) { + log.debug("Found a span in reactor context [" + span + "]"); + } + span = this.tracer.nextSpan(span); + if (log.isDebugEnabled()) { + log.debug("Created a child span [" + span + "]"); + } + } + // TODO: Better name? + return span.name("function"); + } + + private Context enhanceContext(Context context) { + Span span = spanFromContext(context); + return context.put(Span.class, span).put(TraceContext.class, span.context()).put(Tracer.SpanInScope.class, + this.tracer.withSpan(span)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreakerFactoryAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreakerFactoryAspect.java new file mode 100644 index 000000000..ea2d99f1e --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreakerFactoryAspect.java @@ -0,0 +1,45 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.circuitbreaker; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; + +import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Tracer; + +@Aspect +public class TraceReactiveCircuitBreakerFactoryAspect { + + private final Tracer tracer; + + private final CurrentTraceContext currentTraceContext; + + public TraceReactiveCircuitBreakerFactoryAspect(Tracer tracer, CurrentTraceContext currentTraceContext) { + this.tracer = tracer; + this.currentTraceContext = currentTraceContext; + } + + @Around("execution(public * org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory.create(..))") + public Object wrapFactory(ProceedingJoinPoint pjp) throws Throwable { + ReactiveCircuitBreaker circuitBreaker = (ReactiveCircuitBreaker) pjp.proceed(); + return new TraceReactiveCircuitBreaker(circuitBreaker, this.tracer, this.currentTraceContext); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java index 3e6ffa2d5..503229151 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceSupplier.java @@ -44,6 +44,7 @@ class TraceSupplier implements Supplier { @Override public T get() { + // TODO: This name needs to be better String name = this.delegate.getClass().getSimpleName(); Span span = this.span.get().name(name); Throwable tr = null; diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index eb3531c41..09478bd12 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -39,6 +39,7 @@ spring-cloud-sleuth-instrumentation-async-tests spring-cloud-sleuth-instrumentation-baggage-tests spring-cloud-sleuth-instrumentation-circuitbreaker-tests + spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests spring-cloud-sleuth-instrumentation-feign-tests spring-cloud-sleuth-instrumentation-gateway-tests spring-cloud-sleuth-instrumentation-grpc-tests diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/pom.xml new file mode 100644 index 000000000..43d9e1ab6 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/pom.xml @@ -0,0 +1,89 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests + jar + Spring Cloud Sleuth Brave Circuitbreaker Reactive Instrumentation Tests + Spring Cloud Sleuth Brave Circuitbreaker Reactive Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + ${project.version} + + + io.projectreactor + reactor-core + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-reactor-resilience4j + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java new file mode 100644 index 000000000..df5d1a819 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.circuitbreaker; + +import brave.sampler.Sampler; +import org.assertj.core.api.BDDAssertions; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = ReactiveCircuitBreakerIntegrationTests.Config.class) +public class ReactiveCircuitBreakerIntegrationTests + extends org.springframework.cloud.sleuth.instrument.circuitbreaker.ReactiveCircuitBreakerIntegrationTests { + + @Override + public void assertException(FinishedSpan finishedSpan) { + BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom"); + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java new file mode 100644 index 000000000..7ac516cce --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.circuitbreaker; + +import org.assertj.core.api.BDDAssertions; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class ReactiveCircuitBreakerTests + extends org.springframework.cloud.sleuth.instrument.circuitbreaker.ReactiveCircuitBreakerTests { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + + @Override + public void additionalAssertions(FinishedSpan finishedSpan) { + BDDAssertions.then(finishedSpan.getTags().get("error")).contains("boom2"); + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/resources/application.yml b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/resources/application.yml new file mode 100644 index 000000000..f5756fce9 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests/src/test/resources/application.yml @@ -0,0 +1,5 @@ +logging.level.org.springframework.cloud: DEBUG +logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR +logging.level.org.springframework.cloud.sleuth.brave.instrument.web.client.feign: TRACE + +spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.cloud.gateway.config.GatewayAutoConfiguration, org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration, org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration diff --git a/tests/common/pom.xml b/tests/common/pom.xml index 1b79278cb..628288865 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -89,6 +89,11 @@ spring-cloud-starter-circuitbreaker-resilience4j true + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-reactor-resilience4j + true + org.springframework.boot spring-boot-starter-quartz diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java new file mode 100644 index 000000000..3ee120771 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerIntegrationTests.java @@ -0,0 +1,146 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.circuitbreaker; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory; +import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; +import org.springframework.cloud.sleuth.ScopedSpan; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(classes = ReactiveCircuitBreakerIntegrationTests.TestConfig.class) +public abstract class ReactiveCircuitBreakerIntegrationTests { + + @Autowired + TestSpanHandler spans; + + @Autowired + Tracer tracer; + + @Autowired + ReactiveCircuitBreakerFactory factory; + + @Autowired + CircuitService circuitService; + + @BeforeEach + public void setup() { + this.spans.clear(); + } + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker() { + // given + Tracer tracer = this.tracer; + ScopedSpan scopedSpan = null; + try { + scopedSpan = tracer.startScopedSpan("start"); + // when + Span span = this.factory.create("name").run(Mono.defer(() -> Mono.just(tracer.currentSpan()))).block(); + + BDDAssertions.then(span).isNotNull(); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(span.context().traceId()); + } + finally { + scopedSpan.end(); + } + } + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker_with_fallback() { + // when + BDDAssertions.then(this.circuitService.call().block()).isEqualTo("fallback"); + + BDDAssertions.then(this.spans).hasSize(2); + String traceId = this.circuitService.firstSpan.context().traceId(); + BDDAssertions.then(this.circuitService.secondSpan.context().traceId()).isEqualTo(traceId); + + FinishedSpan finishedSpan = this.spans.get(0); + BDDAssertions.then(finishedSpan.getName()).contains("CircuitBreakerIntegrationTests"); + + finishedSpan = this.spans.get(1); + BDDAssertions.then(finishedSpan.getName()).contains("function"); + } + + public void assertException(FinishedSpan finishedSpan) { + throw new UnsupportedOperationException("Implement this assertion"); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + public static class TestConfig { + + @Bean + ReactiveResilience4JCircuitBreakerFactory reactiveResilience4JCircuitBreakerFactory() { + return new ReactiveResilience4JCircuitBreakerFactory(); + } + + @Bean + CircuitService circuitService(ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory, Tracer tracer) { + return new CircuitService(reactiveCircuitBreakerFactory, tracer); + } + + } + + static class CircuitService { + + private static final Logger log = LoggerFactory.getLogger(CircuitService.class); + + private final ReactiveCircuitBreakerFactory factory; + + private final Tracer tracer; + + Span firstSpan; + + Span secondSpan; + + CircuitService(ReactiveCircuitBreakerFactory factory, Tracer tracer) { + this.factory = factory; + this.tracer = tracer; + } + + Mono call() { + return this.factory.create("circuit").run(Mono.defer(() -> { + this.firstSpan = this.tracer.currentSpan(); + log.info(" Hello from consumer", + this.tracer.currentSpan().context().traceId()); + return Mono.error(new IllegalStateException("boom")); + }), throwable -> { + this.secondSpan = this.tracer.currentSpan(); + log.info(" Hello from producer", + this.tracer.currentSpan().context().traceId()); + return Mono.just("fallback"); + }); + } + + } + +} diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java new file mode 100644 index 000000000..021fbcd9e --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/ReactiveCircuitBreakerTests.java @@ -0,0 +1,94 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.circuitbreaker; + +import java.util.concurrent.atomic.AtomicReference; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory; +import org.springframework.cloud.sleuth.ScopedSpan; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; + +public abstract class ReactiveCircuitBreakerTests implements TestTracingAwareSupplier { + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker() { + // given + Tracer tracer = tracerTest().tracing().tracer(); + ScopedSpan scopedSpan = null; + try { + scopedSpan = tracer.startScopedSpan("start"); + // when + Span span = new TraceReactiveCircuitBreaker(new ReactiveResilience4JCircuitBreakerFactory().create("name"), + tracer, tracerTest().tracing().currentTraceContext()) + .run(Mono.defer(() -> Mono.just(tracer.currentSpan()))).block(); + + BDDAssertions.then(span).isNotNull(); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(span.context().traceId()); + } + finally { + scopedSpan.end(); + } + } + + @Test + public void should_pass_tracing_information_when_using_circuit_breaker_with_fallback() { + // given + Tracer tracer = tracerTest().tracing().tracer(); + AtomicReference first = new AtomicReference<>(); + AtomicReference second = new AtomicReference<>(); + ScopedSpan scopedSpan = null; + try { + scopedSpan = tracer.startScopedSpan("start"); + // when + BDDAssertions.thenThrownBy(() -> new TraceReactiveCircuitBreaker( + new ReactiveResilience4JCircuitBreakerFactory().create("name"), tracer, + tracerTest().tracing().currentTraceContext()).run(Mono.defer(() -> { + first.set(tracer.currentSpan()); + throw new IllegalStateException("boom"); + }), throwable -> { + second.set(tracer.currentSpan()); + throw new IllegalStateException("boom2"); + }).block()).isInstanceOf(IllegalStateException.class).hasMessageContaining("boom2"); + + BDDAssertions.then(tracerTest().handler().reportedSpans()).hasSize(2); + BDDAssertions.then(first.get()).isNotNull(); + BDDAssertions.then(second.get()).isNotNull(); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(first.get().context().traceId()); + BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(second.get().context().traceId()); + BDDAssertions.then(first.get().context().spanId()).isNotEqualTo(second.get().context().spanId()); + + FinishedSpan finishedSpan = tracerTest().handler().reportedSpans().get(1); + BDDAssertions.then(finishedSpan.getName()).contains("function"); + additionalAssertions(finishedSpan); + } + finally { + scopedSpan.end(); + } + } + + public void additionalAssertions(FinishedSpan finishedSpan) { + throw new UnsupportedOperationException("Assert errors"); + } + +} From 2fca60a112e360b6913ed7b2b9d12c768ce751ad Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 21 Apr 2021 10:11:28 +0200 Subject: [PATCH 69/78] Added spring-cloud-task support fixes gh-1903 --- .editorconfig | 4 + pom.xml | 8 ++ .../cloud/sleuth/SpanAndScope.java | 44 +++++++ .../cloud/sleuth/ThreadLocalSpan.java | 90 +++++++++++++++ spring-cloud-sleuth-autoconfigure/pom.xml | 5 + ...aceApplicationRunnerBeanPostProcessor.java | 47 ++++++++ ...aceCommandLineRunnerBeanPostProcessor.java | 47 ++++++++ .../task/TraceTaskAutoConfiguration.java | 61 ++++++++++ ...itional-spring-configuration-metadata.json | 8 +- .../main/resources/META-INF/spring.factories | 1 + spring-cloud-sleuth-instrumentation/pom.xml | 5 + .../messaging/TracingChannelInterceptor.java | 68 ++--------- .../task/TraceApplicationRunner.java | 65 +++++++++++ .../task/TraceCommandLineRunner.java | 64 +++++++++++ .../task/TraceTaskExecutionListener.java | 89 +++++++++++++++ tests/brave/pom.xml | 1 + .../pom.xml | 4 - .../pom.xml | 81 +++++++++++++ .../task/SpringCloudTaskIntegrationTests.java | 53 +++++++++ .../src/test/resources/application.yml | 1 + tests/common/pom.xml | 5 + .../task/SpringCloudTaskIntegrationTests.java | 107 ++++++++++++++++++ 22 files changed, 792 insertions(+), 66 deletions(-) create mode 100644 spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java create mode 100644 spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ThreadLocalSpan.java create mode 100644 spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceApplicationRunnerBeanPostProcessor.java create mode 100644 spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceCommandLineRunnerBeanPostProcessor.java create mode 100644 spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceTaskAutoConfiguration.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceApplicationRunner.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceCommandLineRunner.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceTaskExecutionListener.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-task-tests/pom.xml create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/task/SpringCloudTaskIntegrationTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/resources/application.yml create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/task/SpringCloudTaskIntegrationTests.java diff --git a/.editorconfig b/.editorconfig index ddda9782f..ffe385c6d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,9 @@ root = true +[*] +end_of_line = crlf +insert_final_newline = true + [*.java] indent_style = tab indent_size = 4 diff --git a/pom.xml b/pom.xml index 2fb7cb011..286d8b4e4 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,7 @@ 3.1.3-SNAPSHOT 3.0.3-SNAPSHOT 3.0.3-SNAPSHOT + 2.3.2-SNAPSHOT 5.13.2 0.32.0 2.3.4.RELEASE @@ -228,6 +229,13 @@ pom import + + org.springframework.cloud + spring-cloud-task-dependencies + ${spring-cloud-task.version} + pom + import + org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java new file mode 100644 index 000000000..e18e028d7 --- /dev/null +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +/** + * Container object for {@link Span} and its corresponding {@link Tracer.SpanInScope}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class SpanAndScope { + + private final Span span; + + private final Tracer.SpanInScope scope; + + public SpanAndScope(Span span, Tracer.SpanInScope scope) { + this.span = span; + this.scope = scope; + } + + public Span getSpan() { + return this.span; + } + + public Tracer.SpanInScope getScope() { + return this.scope; + } + +} diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ThreadLocalSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ThreadLocalSpan.java new file mode 100644 index 000000000..aa2c0226b --- /dev/null +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ThreadLocalSpan.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +import java.util.Deque; +import java.util.NoSuchElementException; +import java.util.concurrent.LinkedBlockingDeque; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Represents a {@link Span} stored in thread local. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class ThreadLocalSpan { + + private static final Log log = LogFactory.getLog(ThreadLocalSpan.class); + + private final ThreadLocal threadLocalSpan = new ThreadLocal<>(); + + private final Deque spans = new LinkedBlockingDeque<>(); + + private final Tracer tracer; + + public ThreadLocalSpan(Tracer tracer) { + this.tracer = tracer; + } + + /** + * Sets given span and scope. + * @param span - span to be put in scope + */ + public void set(Span span) { + Tracer.SpanInScope spanInScope = this.tracer.withSpan(span); + SpanAndScope newSpanAndScope = new SpanAndScope(span, spanInScope); + SpanAndScope scope = this.threadLocalSpan.get(); + if (scope != null) { + this.spans.addFirst(scope); + } + this.threadLocalSpan.set(newSpanAndScope); + } + + /** + * @return currently stored span and scope + */ + public SpanAndScope get() { + return this.threadLocalSpan.get(); + } + + /** + * Removes the current span from thread local and brings back the previous span to the + * current thread local. + */ + public void remove() { + this.threadLocalSpan.remove(); + if (this.spans.isEmpty()) { + return; + } + try { + SpanAndScope span = this.spans.removeFirst(); + if (log.isDebugEnabled()) { + log.debug("Took span [" + span + "] from thread local"); + } + this.threadLocalSpan.set(span); + } + catch (NoSuchElementException ex) { + if (log.isTraceEnabled()) { + log.trace("Failed to remove a span from the queue", ex); + } + } + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index 15f4a93a0..769757ac6 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -103,6 +103,11 @@ spring-cloud-context true + + org.springframework.cloud + spring-cloud-starter-task + true + io.reactivex rxjava diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceApplicationRunnerBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceApplicationRunnerBeanPostProcessor.java new file mode 100644 index 000000000..5efd90f4c --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceApplicationRunnerBeanPostProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.task; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.ApplicationRunner; +import org.springframework.cloud.sleuth.instrument.task.TraceApplicationRunner; + +/** + * Registers beans related to task scheduling. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceApplicationRunnerBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + public TraceApplicationRunnerBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof ApplicationRunner && !(bean instanceof TraceApplicationRunner)) { + return new TraceApplicationRunner(this.beanFactory, (ApplicationRunner) bean, beanName); + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceCommandLineRunnerBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceCommandLineRunnerBeanPostProcessor.java new file mode 100644 index 000000000..9fc69d7da --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceCommandLineRunnerBeanPostProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.task; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.cloud.sleuth.instrument.task.TraceCommandLineRunner; + +/** + * Registers beans related to task scheduling. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceCommandLineRunnerBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + public TraceCommandLineRunnerBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof CommandLineRunner && !(bean instanceof TraceCommandLineRunner)) { + return new TraceCommandLineRunner(this.beanFactory, (CommandLineRunner) bean, beanName); + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceTaskAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceTaskAutoConfiguration.java new file mode 100644 index 000000000..591ca5941 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/task/TraceTaskAutoConfiguration.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.task; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.task.TraceTaskExecutionListener; +import org.springframework.cloud.task.listener.TaskExecutionListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Registers beans related to Spring Cloud Task scheduling. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(TaskExecutionListener.class) +@ConditionalOnProperty(value = "spring.sleuth.task.enabled", matchIfMissing = true) +@ConditionalOnBean(Tracer.class) +@AutoConfigureAfter(BraveAutoConfiguration.class) +public class TraceTaskAutoConfiguration { + + @Bean + TraceTaskExecutionListener traceTaskExecutionListener(Tracer tracer, + @Value("${spring.application.name:default}") String appName) { + return new TraceTaskExecutionListener(tracer, appName); + } + + @Bean + static TraceCommandLineRunnerBeanPostProcessor traceCommandLineRunnerBeanPostProcessor(BeanFactory beanFactory) { + return new TraceCommandLineRunnerBeanPostProcessor(beanFactory); + } + + @Bean + static TraceApplicationRunnerBeanPostProcessor traceApplicationRunnerBeanPostProcessor(BeanFactory beanFactory) { + return new TraceApplicationRunnerBeanPostProcessor(beanFactory); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index d655251ff..e46fecde3 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -128,7 +128,13 @@ { "name": "spring.sleuth.integration.enabled", "type": "java.lang.Boolean", - "description": "Enable Spring Integration sleuth instrumentation.", + "description": "Enable Spring Integration instrumentation.", + "defaultValue": true + }, + { + "name": "spring.sleuth.task.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Task instrumentation.", "defaultValue": true } ] diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories index 1c5ba3eba..5e902cd8a 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories @@ -6,6 +6,7 @@ org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncDefaultAu org.springframework.cloud.sleuth.autoconfig.instrument.circuitbreaker.TraceCircuitBreakerAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.rxjava.TraceRxJavaAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.quartz.TraceQuartzAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.task.TraceTaskAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebClientAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.web.client.feign.TraceFeignClientAutoConfiguration,\ diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index f049e8a35..6aff38d57 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -127,6 +127,11 @@ spring-cloud-starter-gateway true + + org.springframework.cloud + spring-cloud-starter-task + true + org.aspectj aspectjrt diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java index 9640fdb2a..ed9d3780d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java @@ -18,8 +18,6 @@ package org.springframework.cloud.sleuth.instrument.messaging; import java.util.Iterator; import java.util.Map; -import java.util.NoSuchElementException; -import java.util.concurrent.LinkedBlockingDeque; import java.util.function.Function; import org.apache.commons.logging.Log; @@ -28,6 +26,8 @@ import org.apache.commons.logging.LogFactory; import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanAndScope; +import org.springframework.cloud.sleuth.ThreadLocalSpan; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.propagation.Propagator; import org.springframework.cloud.stream.binder.BinderType; @@ -107,7 +107,7 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter private final Propagator propagator; - private final ThreadLocalSpan threadLocalSpan = new ThreadLocalSpan(); + private final ThreadLocalSpan threadLocalSpan; private final Function remoteServiceNameMapper; @@ -115,6 +115,7 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter Propagator.Setter setter, Propagator.Getter getter, Function remoteServiceNameMapper, MessageSpanCustomizer messageSpanCustomizer) { this.tracer = tracer; + this.threadLocalSpan = new ThreadLocalSpan(tracer); this.propagator = propagator; this.injector = setter; this.extractor = getter; @@ -163,8 +164,7 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter } private void setSpanInScope(Span span) { - Tracer.SpanInScope spanInScope = this.tracer.withSpan(span); - this.threadLocalSpan.set(new SpanAndScope(span, spanInScope)); + this.threadLocalSpan.set(span); if (log.isDebugEnabled()) { log.debug("Put span in scope " + span); } @@ -362,8 +362,8 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter if (spanAndScope == null) { return; } - Span span = spanAndScope.span; - Tracer.SpanInScope scope = spanAndScope.scope; + Span span = spanAndScope.getSpan(); + Tracer.SpanInScope scope = spanAndScope.getScope(); if (span.isNoop()) { if (log.isDebugEnabled()) { log.debug("Span " + span + " is noop - will stope the scope"); @@ -424,57 +424,3 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter } } - -class SpanAndScope { - - final Span span; - - final Tracer.SpanInScope scope; - - SpanAndScope(Span span, Tracer.SpanInScope scope) { - this.span = span; - this.scope = scope; - } - -} - -class ThreadLocalSpan { - - private static final Log log = LogFactory.getLog(ThreadLocalSpan.class); - - final ThreadLocal threadLocalSpan = new ThreadLocal<>(); - - final LinkedBlockingDeque spans = new LinkedBlockingDeque<>(); - - void set(SpanAndScope spanAndScope) { - SpanAndScope scope = this.threadLocalSpan.get(); - if (scope != null) { - this.spans.addFirst(scope); - } - this.threadLocalSpan.set(spanAndScope); - } - - SpanAndScope get() { - return this.threadLocalSpan.get(); - } - - void remove() { - this.threadLocalSpan.remove(); - if (this.spans.isEmpty()) { - return; - } - try { - SpanAndScope span = this.spans.removeFirst(); - if (log.isDebugEnabled()) { - log.debug("Took span [" + span + "] from thread local"); - } - this.threadLocalSpan.set(span); - } - catch (NoSuchElementException ex) { - if (log.isTraceEnabled()) { - log.trace("Failed to remove a span from the queue", ex); - } - } - } - -} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceApplicationRunner.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceApplicationRunner.java new file mode 100644 index 000000000..4e3f6c77d --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceApplicationRunner.java @@ -0,0 +1,65 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.task; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * Trace representation of a {@link ApplicationRunner}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceApplicationRunner implements ApplicationRunner { + + private final BeanFactory beanFactory; + + private final ApplicationRunner delegate; + + private final String beanName; + + private Tracer tracer; + + public TraceApplicationRunner(BeanFactory beanFactory, ApplicationRunner delegate, String beanName) { + this.beanFactory = beanFactory; + this.delegate = delegate; + this.beanName = beanName; + } + + @Override + public void run(ApplicationArguments args) throws Exception { + Span span = tracer().nextSpan().name(this.beanName); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.run(args); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceCommandLineRunner.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceCommandLineRunner.java new file mode 100644 index 000000000..70b9ee320 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceCommandLineRunner.java @@ -0,0 +1,64 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.task; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * Trace representation of a {@link CommandLineRunner}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceCommandLineRunner implements CommandLineRunner { + + private final BeanFactory beanFactory; + + private final CommandLineRunner delegate; + + private final String beanName; + + private Tracer tracer; + + public TraceCommandLineRunner(BeanFactory beanFactory, CommandLineRunner delegate, String beanName) { + this.beanFactory = beanFactory; + this.delegate = delegate; + this.beanName = beanName; + } + + @Override + public void run(String... args) throws Exception { + Span span = tracer().nextSpan().name(this.beanName); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.run(args); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceTaskExecutionListener.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceTaskExecutionListener.java new file mode 100644 index 000000000..d50d7ab00 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/task/TraceTaskExecutionListener.java @@ -0,0 +1,89 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.task; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanAndScope; +import org.springframework.cloud.sleuth.ThreadLocalSpan; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.task.listener.TaskExecutionListener; +import org.springframework.cloud.task.repository.TaskExecution; +import org.springframework.core.Ordered; + +/** + * Sets the span upon starting and closes it upon ending a task. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceTaskExecutionListener implements TaskExecutionListener, Ordered { + + private static final Log log = LogFactory.getLog(TraceTaskExecutionListener.class); + + private final Tracer tracer; + + private final ThreadLocalSpan threadLocalSpan; + + private final String projectName; + + public TraceTaskExecutionListener(Tracer tracer, String projectName) { + this.tracer = tracer; + this.threadLocalSpan = new ThreadLocalSpan(tracer); + this.projectName = projectName; + } + + @Override + public void onTaskStartup(TaskExecution taskExecution) { + Span span = this.tracer.nextSpan().name(this.projectName).start(); + this.threadLocalSpan.set(span); + if (log.isDebugEnabled()) { + log.debug("Put the span [" + span + "] to thread local"); + } + } + + @Override + public void onTaskEnd(TaskExecution taskExecution) { + SpanAndScope spanAndScope = this.threadLocalSpan.get(); + Span span = spanAndScope.getSpan(); + span.end(); + spanAndScope.getScope().close(); + if (log.isDebugEnabled()) { + log.debug("Removed the [" + span + "] from thread local"); + } + } + + @Override + public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) { + SpanAndScope spanAndScope = this.threadLocalSpan.get(); + Span span = spanAndScope.getSpan(); + span.error(throwable); + span.end(); + spanAndScope.getScope().close(); + if (log.isDebugEnabled()) { + log.debug("Removed the [" + span + "] from thread local and added error"); + } + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + +} diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index 09478bd12..8796d03bf 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -50,6 +50,7 @@ spring-cloud-sleuth-instrumentation-reactor-tests spring-cloud-sleuth-instrumentation-rxjava-tests spring-cloud-sleuth-instrumentation-scheduling-tests + spring-cloud-sleuth-instrumentation-task-tests spring-cloud-sleuth-instrumentation-webflux-tests spring-cloud-sleuth-zipkin-tests diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml index da9a7a566..45d3de776 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml +++ b/tests/brave/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml @@ -51,10 +51,6 @@ - - org.springframework.cloud - spring-cloud-starter-sleuth - org.springframework.cloud spring-cloud-starter-sleuth diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/pom.xml new file mode 100644 index 000000000..667d54797 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/pom.xml @@ -0,0 +1,81 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-task-tests + jar + Spring Cloud Sleuth Brave Task Instrumentation Tests + Spring Cloud Sleuth Brave Task Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + ${project.version} + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-starter-task + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/task/SpringCloudTaskIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/task/SpringCloudTaskIntegrationTests.java new file mode 100644 index 000000000..55d08c60a --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/task/SpringCloudTaskIntegrationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.task; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@ContextConfiguration(classes = SpringCloudTaskIntegrationTests.Config.class) +public class SpringCloudTaskIntegrationTests + extends org.springframework.cloud.sleuth.instrument.task.SpringCloudTaskIntegrationTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/resources/application.yml b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/resources/application.yml new file mode 100644 index 000000000..2b87cbf49 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-task-tests/src/test/resources/application.yml @@ -0,0 +1 @@ +logging.level.org.springframework.cloud: DEBUG diff --git a/tests/common/pom.xml b/tests/common/pom.xml index 628288865..01c5cdc48 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -84,6 +84,11 @@ spring-cloud-starter-gateway true + + org.springframework.cloud + spring-cloud-starter-task + true + org.springframework.cloud spring-cloud-starter-circuitbreaker-resilience4j diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/task/SpringCloudTaskIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/task/SpringCloudTaskIntegrationTests.java new file mode 100644 index 000000000..e1c5f83f3 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/task/SpringCloudTaskIntegrationTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.task; + +import java.util.Iterator; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.cloud.task.configuration.EnableTask; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; + +import static org.assertj.core.api.BDDAssertions.then; + +@ContextConfiguration(classes = SpringCloudTaskIntegrationTests.TestConfig.class) +@TestPropertySource(properties = "spring.application.name=MyApplication") +public abstract class SpringCloudTaskIntegrationTests { + + @Autowired + TestSpanHandler spans; + + @Test + public void should_pass_tracing_information_when_using_spring_cloud_task() { + Set traceIds = this.spans.reportedSpans().stream().map(FinishedSpan::getTraceId) + .collect(Collectors.toSet()); + then(traceIds).as("There's one traceid").hasSize(1); + Set spanIds = this.spans.reportedSpans().stream().map(FinishedSpan::getSpanId) + .collect(Collectors.toSet()); + + then(spanIds).as("There are 3 spans").hasSize(3); + Iterator spanIterator = this.spans.reportedSpans().iterator(); + + FinishedSpan first = spanIterator.next(); + FinishedSpan second = spanIterator.next(); + FinishedSpan third = spanIterator.next(); + then(first.getName()).isEqualTo("myApplicationRunner"); + then(second.getName()).isEqualTo("myCommandLineRunner"); + then(third.getName()).isEqualTo("MyApplication"); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + @EnableTask + public static class TestConfig { + + @Bean + MyCommandLineRunner myCommandLineRunner() { + return new MyCommandLineRunner(); + } + + @Bean + MyApplicationRunner myApplicationRunner() { + return new MyApplicationRunner(); + } + + } + + static class MyCommandLineRunner implements CommandLineRunner { + + private static final Log log = LogFactory.getLog(MyCommandLineRunner.class); + + @Override + public void run(String... args) throws Exception { + log.info("Ran MyCommandLineRunner"); + } + + } + + static class MyApplicationRunner implements ApplicationRunner { + + private static final Log log = LogFactory.getLog(MyApplicationRunner.class); + + @Override + public void run(ApplicationArguments args) throws Exception { + log.info("Ran MyApplicationRunner"); + } + + } + +} From 92d0a30a959affc8e8ef3ad9cd880f4fafdd60b1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 21 Apr 2021 12:20:25 +0000 Subject: [PATCH 70/78] Added Spring Cloud Config server support; fixes 1915 (#1917) --- docs/src/main/asciidoc/integrations.adoc | 10 +- pom.xml | 8 ++ spring-cloud-sleuth-autoconfigure/pom.xml | 10 ++ ...aceSpringCloudConfigAutoConfiguration.java | 51 ++++++++++ ...itional-spring-configuration-metadata.json | 6 ++ .../main/resources/META-INF/spring.factories | 1 + ...ringCloudConfigAutoConfigurationTests.java | 39 ++++++++ spring-cloud-sleuth-instrumentation/pom.xml | 10 ++ .../TraceEnvironmentRepositoryAspect.java | 54 ++++++++++ tests/brave/pom.xml | 1 + .../pom.xml | 84 ++++++++++++++++ .../config/ConfigServerIntegrationTests.java | 53 ++++++++++ .../src/test/resources/application.yml | 3 + tests/common/pom.xml | 5 + .../config/ConfigServerIntegrationTests.java | 98 +++++++++++++++++++ 15 files changed, 432 insertions(+), 1 deletion(-) create mode 100644 spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfiguration.java create mode 100644 spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfigurationTests.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/config/TraceEnvironmentRepositoryAspect.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/pom.xml create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/config/ConfigServerIntegrationTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/resources/application.yml create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java diff --git a/docs/src/main/asciidoc/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc index 6da99eafc..a05b772c4 100644 --- a/docs/src/main/asciidoc/integrations.adoc +++ b/docs/src/main/asciidoc/integrations.adoc @@ -566,4 +566,12 @@ IMPORTANT: The suggested approach to reactive programming and Sleuth is to use t This feature is available for all tracer implementations. If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. We will also instrument the reactive implementation of the CircuitBreaker. -In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`. \ No newline at end of file +In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`. + +[[sleuth-config-server-integration]] +== Spring Cloud Config Server + +This feature is available for all tracer implementations. + +If you have Spring Cloud Config Server running on the classpath, we will wrap the `EnvironmentRepository` in a span. +In order to disable this instrumentation set `spring.sleuth.config.server.enabled` to `false`. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 286d8b4e4..08c6c9d63 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,7 @@ 3.0.3-SNAPSHOT 3.0.3-SNAPSHOT 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT 2.0.2-SNAPSHOT 3.1.3-SNAPSHOT 3.1.3-SNAPSHOT @@ -229,6 +230,13 @@ pom import + + org.springframework.cloud + spring-cloud-config-dependencies + ${spring-cloud-config.version} + pom + import + org.springframework.cloud spring-cloud-task-dependencies diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index 769757ac6..ac237bbf7 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -73,6 +73,16 @@ spring-integration-core true + + org.springframework.cloud + spring-cloud-config-server + true + + + org.springframework.cloud + spring-cloud-starter-config + true + org.springframework.cloud spring-cloud-function-context diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfiguration.java new file mode 100644 index 000000000..1276618a1 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.config; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.config.server.config.ConfigServerConfiguration; +import org.springframework.cloud.config.server.config.ConfigServerProperties; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.config.TraceEnvironmentRepositoryAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration + * Auto-configuration} that registers instrumentation for Spring Cloud Config Server and + * Client. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean({ Tracer.class, ConfigServerProperties.class }) +@ConditionalOnClass(ConfigServerConfiguration.class) +@ConditionalOnProperty(value = "spring.sleuth.config.server.enabled", matchIfMissing = true) +@AutoConfigureAfter(BraveAutoConfiguration.class) +public class TraceSpringCloudConfigAutoConfiguration { + + @Bean + TraceEnvironmentRepositoryAspect traceEnvironmentRepositoryAspect(Tracer tracer) { + return new TraceEnvironmentRepositoryAspect(tracer); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index e46fecde3..b2ebb1d5a 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -136,6 +136,12 @@ "type": "java.lang.Boolean", "description": "Enable Spring Cloud Task instrumentation.", "defaultValue": true + }, + { + "name": "spring.sleuth.config.server.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Config Server instrumentation.", + "defaultValue": true } ] } diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories index 5e902cd8a..d2df0f518 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories @@ -3,6 +3,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncCustomAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncDefaultAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.config.TraceSpringCloudConfigAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.circuitbreaker.TraceCircuitBreakerAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.rxjava.TraceRxJavaAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.quartz.TraceQuartzAutoConfiguration,\ diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfigurationTests.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfigurationTests.java new file mode 100644 index 000000000..8d75ab817 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/instrument/config/TraceSpringCloudConfigAutoConfigurationTests.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.config; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.config.server.config.ConfigServerProperties; +import org.springframework.cloud.sleuth.autoconfig.TraceNoOpAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.config.TraceEnvironmentRepositoryAspect; + +class TraceSpringCloudConfigAutoConfigurationTests { + + @Test + void should_register_the_aspect() { + new ApplicationContextRunner().withPropertyValues("spring.sleuth.noop.enabled=true") + .withBean(ConfigServerProperties.class) + .withConfiguration(AutoConfigurations.of(TraceNoOpAutoConfiguration.class, + TraceSpringCloudConfigAutoConfiguration.class)) + .run(context -> BDDAssertions.then(context).hasSingleBean(TraceEnvironmentRepositoryAspect.class)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 6aff38d57..356f74fe0 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -72,6 +72,16 @@ spring-integration-core true + + org.springframework.cloud + spring-cloud-config-server + true + + + org.springframework.cloud + spring-cloud-starter-config + true + org.springframework.cloud spring-cloud-function-context diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/config/TraceEnvironmentRepositoryAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/config/TraceEnvironmentRepositoryAspect.java new file mode 100644 index 000000000..93b420f00 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/config/TraceEnvironmentRepositoryAspect.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.config; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * Aspect wrapping resolution of properties. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Aspect +public class TraceEnvironmentRepositoryAspect { + + private final Tracer tracer; + + public TraceEnvironmentRepositoryAspect(Tracer tracer) { + this.tracer = tracer; + } + + @Around("execution (* org.springframework.cloud.config.server.environment.EnvironmentRepository.*(..))") + public Object traceFindEnvironment(final ProceedingJoinPoint pjp) throws Throwable { + Span findOneSpan = this.tracer.nextSpan().name("find"); + findOneSpan.tag("config.environment.class", pjp.getTarget().getClass().getName()); + findOneSpan.tag("config.environment.method", pjp.getSignature().getName()); + try (Tracer.SpanInScope ws = this.tracer.withSpan(findOneSpan.start())) { + return pjp.proceed(); + } + finally { + findOneSpan.end(); + } + } + +} diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index 8796d03bf..2e21ae75f 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -38,6 +38,7 @@ spring-cloud-sleuth-instrumentation-annotation-tests spring-cloud-sleuth-instrumentation-async-tests spring-cloud-sleuth-instrumentation-baggage-tests + spring-cloud-sleuth-instrumentation-config-server-tests spring-cloud-sleuth-instrumentation-circuitbreaker-tests spring-cloud-sleuth-instrumentation-circuitbreaker-reactive-tests spring-cloud-sleuth-instrumentation-feign-tests diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/pom.xml new file mode 100644 index 000000000..6d6f4eb10 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/pom.xml @@ -0,0 +1,84 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-config-server-tests + jar + Spring Cloud Sleuth Brave Config Server Instrumentation Tests + Spring Cloud Sleuth Brave Config Server Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-config-server + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/config/ConfigServerIntegrationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/config/ConfigServerIntegrationTests.java new file mode 100644 index 000000000..fe1251a31 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/config/ConfigServerIntegrationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.config; + +import brave.sampler.Sampler; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = ConfigServerIntegrationTests.Config.class) +public class ConfigServerIntegrationTests + extends org.springframework.cloud.sleuth.instrument.config.ConfigServerIntegrationTests { + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + TestSpanHandler testSpanHandlerSupplier(brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/resources/application.yml b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/resources/application.yml new file mode 100644 index 000000000..f0238e134 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-config-server-tests/src/test/resources/application.yml @@ -0,0 +1,3 @@ +logging.level.org.springframework.cloud: DEBUG + +spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration diff --git a/tests/common/pom.xml b/tests/common/pom.xml index 01c5cdc48..f405ccd78 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -119,6 +119,11 @@ spring-cloud-starter-loadbalancer true + + org.springframework.cloud + spring-cloud-config-server + true + org.apache.httpcomponents httpclient diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java new file mode 100644 index 000000000..e27a43140 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.config; + +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.BDDAssertions.then; +import static org.awaitility.Awaitility.await; + +@ContextConfiguration(classes = ConfigServerIntegrationTests.TestConfig.class) +@TestPropertySource(properties = { "server.port=0", + "spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo" }) +public abstract class ConfigServerIntegrationTests { + + @Autowired + TestSpanHandler spans; + + @Autowired + WebClientService webClientService; + + @LocalServerPort + int port; + + @BeforeEach + public void setup() { + this.spans.clear(); + } + + @Test + public void should_instrument_config_server() { + this.webClientService.call(port); + + await().atMost(30, TimeUnit.SECONDS).untilAsserted(() -> { + then(this.spans.reportedSpans()).as("1 for mvc, 1 for composite env repo and 1 for git env repo") + .hasSize(3); + then(this.spans.reportedSpans().stream().map(FinishedSpan::getTraceId).collect(Collectors.toSet())) + .as("There must be 1 trace id").hasSize(1); + }); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + @EnableConfigServer + public static class TestConfig { + + @Bean + WebClientService webClientService() { + return new WebClientService(); + } + + } + + public static class WebClientService { + + private static final Logger log = LoggerFactory.getLogger(WebClientService.class); + + void call(int port) { + log.info("Sending request"); + String result = new RestTemplate().getForObject("http://localhost:" + port + "/master/application.yml", + String.class); + log.info("Got [\n" + result + "\n]"); + } + + } + +} From 1bcccbae6e2716f09e3ad894dd1ee35d89929005 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 22 Apr 2021 11:27:08 +0200 Subject: [PATCH 71/78] Added missing method for AOP wrapping (#1924) fixes gh-1922 --- .../brave/instrument/messaging/SleuthKafkaAspect.java | 6 +++++- .../messaging/BraveMessagingAutoConfigurationTests.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java index 9f98bdb84..8c084dc25 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/instrument/messaging/SleuthKafkaAspect.java @@ -64,6 +64,10 @@ public class SleuthKafkaAspect { private void anyProducerFactory() { } // NOSONAR + @Pointcut("execution(public * org.springframework.kafka.core.ProducerFactory.createNonTransactionalProducer(..))") + private void anyNonTransactionalProducerFactory() { + } // NOSONAR + @Pointcut("execution(public * org.springframework.kafka.core.ConsumerFactory.createConsumer(..))") private void anyConsumerFactory() { } // NOSONAR @@ -76,7 +80,7 @@ public class SleuthKafkaAspect { private void anyCreateContainer() { } // NOSONAR - @Around("anyProducerFactory()") + @Around("anyProducerFactory() || anyNonTransactionalProducerFactory()") public Object wrapProducerFactory(ProceedingJoinPoint pjp) throws Throwable { Producer producer = (Producer) pjp.proceed(); return this.kafkaTracing.producer(producer); diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java index fe6945d64..990e5b61a 100644 --- a/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java +++ b/tests/brave/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/BraveMessagingAutoConfigurationTests.java @@ -96,6 +96,10 @@ public class BraveMessagingAutoConfigurationTests { public void should_wrap_kafka() { this.producerFactory.createProducer(); then(this.mySleuthKafkaAspect.producerWrapped).isTrue(); + this.mySleuthKafkaAspect.producerWrapped = false; + + this.producerFactory.createNonTransactionalProducer(); + then(this.mySleuthKafkaAspect.producerWrapped).isTrue(); this.consumerFactory.createConsumer(); then(this.mySleuthKafkaAspect.consumerWrapped).isTrue(); From c4ab9dcd498581605ff21e6b23333ada339f48d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Flaviu=20Mure=C8=99an?= Date: Thu, 22 Apr 2021 16:27:34 +0200 Subject: [PATCH 72/78] Kafka instrumentation (#1920) fixes gh-1906 --- pom.xml | 8 + spring-cloud-sleuth-instrumentation/pom.xml | 5 + .../kafka/KafkaTracingCallback.java | 70 ++++ .../instrument/kafka/KafkaTracingUtils.java | 46 +++ .../kafka/TracingKafkaConsumer.java | 314 ++++++++++++++++++ .../kafka/TracingKafkaProducer.java | 147 ++++++++ .../kafka/TracingKafkaProducerFactory.java | 54 +++ .../kafka/TracingKafkaPropagatorGetter.java | 44 +++ .../kafka/TracingKafkaPropagatorSetter.java | 40 +++ .../kafka/TracingKafkaReceiver.java | 112 +++++++ .../kafka/KafkaTracingCallbackTest.java | 65 ++++ .../kafka/TracingKafkaConsumerTest.java | 67 ++++ .../kafka/TracingKafkaProducerTest.java | 79 +++++ .../kafka/TracingKafkaReceiverTest.java | 61 ++++ tests/brave/pom.xml | 1 + .../pom.xml | 97 ++++++ .../instrument/kafka/KafkaProducerTest.java | 34 ++ tests/common/pom.xml | 20 ++ .../instrument/kafka/KafkaProducerTest.java | 98 ++++++ 19 files changed, 1362 insertions(+) create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallback.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingUtils.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumer.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducer.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerFactory.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorGetter.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorSetter.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiver.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallbackTest.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumerTest.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerTest.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiverTest.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/pom.xml create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/kafka/KafkaProducerTest.java create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaProducerTest.java diff --git a/pom.xml b/pom.xml index 08c6c9d63..7b1064f32 100644 --- a/pom.xml +++ b/pom.xml @@ -92,6 +92,7 @@ 4.0.3 0.21.3 0.14.1 + 1.15.3 @@ -293,6 +294,13 @@ archunit-junit5 ${archunit-junit5.version} + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 356f74fe0..4793fa853 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -52,6 +52,11 @@ reactor-core true + + io.projectreactor.kafka + reactor-kafka + true + org.reactivestreams reactive-streams diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallback.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallback.java new file mode 100644 index 000000000..4e8dfd44a --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallback.java @@ -0,0 +1,70 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.RecordMetadata; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +/** + * This decorates a Kafka {@link Callback} and completes the {@link Span.Kind#PRODUCER} + * span created for the record when {@code onCompletion()} is invoked (i.e. the broker has + * acknowledged or an {@link Exception}) was thrown. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class KafkaTracingCallback implements Callback { + + private static final Log log = LogFactory.getLog(KafkaTracingCallback.class); + + private final Callback callback; + + private final Tracer tracer; + + private final Span span; + + public KafkaTracingCallback(Callback callback, Tracer tracer, Span span) { + this.callback = callback; + this.tracer = tracer; + this.span = span; + } + + @Override + public void onCompletion(RecordMetadata recordMetadata, Exception e) { + try (Tracer.SpanInScope spanInScope = tracer.withSpan(this.span)) { + if (this.callback != null) { + this.callback.onCompletion(recordMetadata, e); + } + } + finally { + if (e != null) { + this.span.error(e); + } + this.span.end(); + if (log.isDebugEnabled()) { + log.debug("Finished producer span " + span); + } + } + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingUtils.java new file mode 100644 index 000000000..3c3b23461 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingUtils.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2020 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 + * + * https://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.instrument.kafka; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.kafka.clients.consumer.ConsumerRecord; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.propagation.Propagator; + +final class KafkaTracingUtils { + + private static final Log log = LogFactory.getLog(KafkaTracingUtils.class); + + private KafkaTracingUtils() { + } + + static void buildAndFinishSpan(ConsumerRecord consumerRecord, Propagator propagator, + Propagator.Getter> extractor) { + Span.Builder spanBuilder = propagator.extract(consumerRecord, extractor).kind(Span.Kind.CONSUMER) + .name("kafka.consume").tag("kafka.topic", consumerRecord.topic()) + .tag("kafka.offset", Long.toString(consumerRecord.offset())) + .tag("kafka.partition", Integer.toString(consumerRecord.partition())); + Span span = spanBuilder.start(); + if (log.isDebugEnabled()) { + log.debug("Extracted span from event headers " + span); + } + span.end(); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumer.java new file mode 100644 index 000000000..9698f15cd --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumer.java @@ -0,0 +1,314 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import java.time.Duration; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerGroupMetadata; +import org.apache.kafka.clients.consumer.ConsumerRebalanceListener; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.OffsetAndMetadata; +import org.apache.kafka.clients.consumer.OffsetAndTimestamp; +import org.apache.kafka.clients.consumer.OffsetCommitCallback; +import org.apache.kafka.common.Metric; +import org.apache.kafka.common.MetricName; +import org.apache.kafka.common.PartitionInfo; +import org.apache.kafka.common.TopicPartition; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a Kafka {@link Consumer}. It creates and completes a + * {@link Span.Kind#CONSUMER} span for each record received. This span will be a child + * span of the one extracted from the record headers. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaConsumer implements Consumer { + + private final Consumer delegate; + + private final Propagator propagator; + + private final Propagator.Getter> extractor; + + public TracingKafkaConsumer(Consumer consumer, Propagator propagator, + Propagator.Getter> getter) { + this.delegate = consumer; + this.propagator = propagator; + this.extractor = getter; + } + + @Override + public Set assignment() { + return this.delegate.assignment(); + } + + @Override + public Set subscription() { + return this.delegate.subscription(); + } + + @Override + public void subscribe(Collection collection) { + this.delegate.subscribe(collection); + } + + @Override + public void subscribe(Collection collection, ConsumerRebalanceListener consumerRebalanceListener) { + this.delegate.subscribe(collection, consumerRebalanceListener); + } + + @Override + public void assign(Collection collection) { + this.delegate.assign(collection); + } + + @Override + public void subscribe(Pattern pattern, ConsumerRebalanceListener consumerRebalanceListener) { + this.delegate.subscribe(pattern, consumerRebalanceListener); + } + + @Override + public void subscribe(Pattern pattern) { + this.delegate.subscribe(pattern); + } + + @Override + public void unsubscribe() { + this.delegate.unsubscribe(); + } + + @Deprecated + @Override + public ConsumerRecords poll(long l) { + ConsumerRecords consumerRecords = this.delegate.poll(l); + for (ConsumerRecord consumerRecord : consumerRecords) { + KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, this.extractor); + } + return consumerRecords; + } + + @Override + public ConsumerRecords poll(Duration duration) { + ConsumerRecords consumerRecords = this.delegate.poll(duration); + for (ConsumerRecord consumerRecord : consumerRecords) { + KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, this.extractor); + } + return consumerRecords; + } + + @Override + public void commitSync() { + this.delegate.commitSync(); + } + + @Override + public void commitSync(Duration duration) { + this.delegate.commitSync(duration); + } + + @Override + public void commitSync(Map map) { + this.delegate.commitSync(map); + } + + @Override + public void commitSync(Map map, Duration duration) { + this.delegate.commitSync(map, duration); + } + + @Override + public void commitAsync() { + this.delegate.commitAsync(); + } + + @Override + public void commitAsync(OffsetCommitCallback offsetCommitCallback) { + this.delegate.commitAsync(offsetCommitCallback); + } + + @Override + public void commitAsync(Map map, OffsetCommitCallback offsetCommitCallback) { + this.delegate.commitAsync(map, offsetCommitCallback); + } + + @Override + public void seek(TopicPartition topicPartition, long l) { + this.delegate.seek(topicPartition, l); + } + + @Override + public void seek(TopicPartition topicPartition, OffsetAndMetadata offsetAndMetadata) { + this.delegate.seek(topicPartition, offsetAndMetadata); + } + + @Override + public void seekToBeginning(Collection collection) { + this.delegate.seekToBeginning(collection); + } + + @Override + public void seekToEnd(Collection collection) { + this.delegate.seekToEnd(collection); + } + + @Override + public long position(TopicPartition topicPartition) { + return this.delegate.position(topicPartition); + } + + @Override + public long position(TopicPartition topicPartition, Duration duration) { + return this.delegate.position(topicPartition, duration); + } + + @Override + @Deprecated + public OffsetAndMetadata committed(TopicPartition topicPartition) { + return this.delegate.committed(topicPartition); + } + + @Override + @Deprecated + public OffsetAndMetadata committed(TopicPartition topicPartition, Duration duration) { + return this.delegate.committed(topicPartition, duration); + } + + @Override + public Map committed(Set set) { + return this.delegate.committed(set); + } + + @Override + public Map committed(Set set, Duration duration) { + return this.delegate.committed(set, duration); + } + + @Override + public Map metrics() { + return this.delegate.metrics(); + } + + @Override + public List partitionsFor(String s) { + return this.delegate.partitionsFor(s); + } + + @Override + public List partitionsFor(String s, Duration duration) { + return this.delegate.partitionsFor(s, duration); + } + + @Override + public Map> listTopics() { + return this.delegate.listTopics(); + } + + @Override + public Map> listTopics(Duration duration) { + return this.delegate.listTopics(duration); + } + + @Override + public Set paused() { + return this.delegate.paused(); + } + + @Override + public void pause(Collection collection) { + this.delegate.pause(collection); + } + + @Override + public void resume(Collection collection) { + this.delegate.resume(collection); + } + + @Override + public Map offsetsForTimes(Map map) { + return this.delegate.offsetsForTimes(map); + } + + @Override + public Map offsetsForTimes(Map map, Duration duration) { + return this.delegate.offsetsForTimes(map, duration); + } + + @Override + public Map beginningOffsets(Collection collection) { + return this.delegate.beginningOffsets(collection); + } + + @Override + public Map beginningOffsets(Collection collection, Duration duration) { + return this.delegate.beginningOffsets(collection, duration); + } + + @Override + public Map endOffsets(Collection collection) { + return this.delegate.endOffsets(collection); + } + + @Override + public Map endOffsets(Collection collection, Duration duration) { + return this.delegate.endOffsets(collection, duration); + } + + @Override + public ConsumerGroupMetadata groupMetadata() { + return this.delegate.groupMetadata(); + } + + @Override + public void enforceRebalance() { + this.delegate.enforceRebalance(); + } + + @Override + public void close() { + this.delegate.close(); + } + + @Override + @Deprecated + public void close(long l, TimeUnit timeUnit) { + this.delegate.close(l, timeUnit); + } + + @Override + public void close(Duration duration) { + this.delegate.close(duration); + } + + @Override + public void wakeup() { + this.delegate.wakeup(); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducer.java new file mode 100644 index 000000000..51d778076 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducer.java @@ -0,0 +1,147 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import java.time.Duration; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.kafka.clients.consumer.ConsumerGroupMetadata; +import org.apache.kafka.clients.consumer.OffsetAndMetadata; +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.Metric; +import org.apache.kafka.common.MetricName; +import org.apache.kafka.common.PartitionInfo; +import org.apache.kafka.common.TopicPartition; +import org.apache.kafka.common.errors.ProducerFencedException; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a Kafka {@link Producer} and creates a {@link Span.Kind#PRODUCER} span + * for each record sent. This span is also injected onto each record (via headers) so it + * becomes the parent when a consumer later receives the record. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaProducer implements Producer { + + private static final Log log = LogFactory.getLog(TracingKafkaProducer.class); + + private final Producer delegate; + + private final Tracer tracer; + + private final Propagator propagator; + + private final Propagator.Setter> injector; + + public TracingKafkaProducer(Producer producer, Tracer tracer, Propagator propagator, + Propagator.Setter> setter) { + this.delegate = producer; + this.tracer = tracer; + this.propagator = propagator; + this.injector = setter; + } + + @Override + public void initTransactions() { + this.delegate.initTransactions(); + } + + @Override + public void beginTransaction() throws ProducerFencedException { + this.delegate.beginTransaction(); + } + + @Override + public void sendOffsetsToTransaction(Map map, String s) + throws ProducerFencedException { + this.delegate.sendOffsetsToTransaction(map, s); + } + + @Override + public void sendOffsetsToTransaction(Map map, + ConsumerGroupMetadata consumerGroupMetadata) throws ProducerFencedException { + this.delegate.sendOffsetsToTransaction(map, consumerGroupMetadata); + } + + @Override + public void commitTransaction() throws ProducerFencedException { + this.delegate.commitTransaction(); + } + + @Override + public void abortTransaction() throws ProducerFencedException { + this.delegate.abortTransaction(); + } + + @Override + public Future send(ProducerRecord producerRecord) { + return send(producerRecord, null); + } + + @Override + public Future send(ProducerRecord producerRecord, Callback callback) { + Span.Builder spanBuilder = tracer.spanBuilder().kind(Span.Kind.PRODUCER).name("kafka.produce") + .tag("kafka.topic", producerRecord.topic()); + Span span = spanBuilder.start(); + this.propagator.inject(span.context(), producerRecord, this.injector); + try (Tracer.SpanInScope spanInScope = tracer.withSpan(span)) { + if (log.isDebugEnabled()) { + log.debug("Created producer span " + span); + } + return this.delegate.send(producerRecord, new KafkaTracingCallback(callback, tracer, span)); + } + } + + @Override + public void flush() { + this.delegate.flush(); + } + + @Override + public List partitionsFor(String s) { + return this.delegate.partitionsFor(s); + } + + @Override + public Map metrics() { + return this.delegate.metrics(); + } + + @Override + public void close() { + this.delegate.close(); + } + + @Override + public void close(Duration duration) { + this.delegate.close(duration); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerFactory.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerFactory.java new file mode 100644 index 000000000..184df69b7 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import org.apache.kafka.clients.producer.Producer; +import reactor.kafka.sender.KafkaSender; +import reactor.kafka.sender.SenderOptions; +import reactor.kafka.sender.internals.ProducerFactory; + +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a Reactor Kafka {@link ProducerFactory} to create decorated producers of + * type {@link TracingKafkaProducer}. This can be used by the {@link KafkaSender} factory + * methods to create instrumented senders. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaProducerFactory extends ProducerFactory { + + private final Tracer tracer; + + private final Propagator propagator; + + public TracingKafkaProducerFactory(Tracer tracer, Propagator propagator) { + super(); + this.tracer = tracer; + this.propagator = propagator; + } + + @Override + public Producer createProducer(SenderOptions senderOptions) { + return new TracingKafkaProducer<>(super.createProducer(senderOptions), tracer, propagator, + new TracingKafkaPropagatorSetter()); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorGetter.java new file mode 100644 index 000000000..e09988e5c --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorGetter.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import java.util.Iterator; +import java.util.Optional; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.common.header.Header; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Getter extracting the values from the {@link ConsumerRecord} headers for Kafka based + * communication. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaPropagatorGetter implements Propagator.Getter> { + + @Override + public String get(ConsumerRecord carrier, String key) { + return Optional.ofNullable(carrier).map(ConsumerRecord::headers).map(headers -> headers.headers(key)) + .map(Iterable::iterator).filter(Iterator::hasNext).map(Iterator::next).map(Header::value) + .map(String::new).orElse(null); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorSetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorSetter.java new file mode 100644 index 000000000..afdb9b955 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaPropagatorSetter.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import org.apache.kafka.clients.producer.ProducerRecord; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Setter injecting the values onto the {@link ProducerRecord} headers for Kafka based + * communication. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaPropagatorSetter implements Propagator.Setter> { + + @Override + public void set(ProducerRecord carrier, String key, String value) { + if (carrier != null) { + carrier.headers().add(key, value.getBytes()); + } + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiver.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiver.java new file mode 100644 index 000000000..f855b5595 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiver.java @@ -0,0 +1,112 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import java.util.function.Function; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverRecord; +import reactor.kafka.sender.TransactionManager; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * This decorates a reactive {@link KafkaReceiver} and creates and completes a + * {@link Span.Kind#CONSUMER} span for each record received. This span will be a child + * span of the one extracted from the record headers. + * + * @author Anders Clausen + * @author Flaviu Muresan + * @since 3.0.3 + */ +public class TracingKafkaReceiver implements KafkaReceiver { + + private final KafkaReceiver delegate; + + private final Propagator propagator; + + private final Propagator.Getter> extractor; + + public TracingKafkaReceiver(KafkaReceiver receiver, Propagator propagator, + Propagator.Getter> getter) { + this.delegate = receiver; + this.propagator = propagator; + this.extractor = getter; + } + + @Override + public Flux> receive(Integer integer) { + return buildAndFinishSpanOnNextReceiverRecord(this.delegate.receive(integer)); + } + + @Override + public Flux> receive() { + return buildAndFinishSpanOnNextReceiverRecord(this.delegate.receive()); + } + + @Override + public Flux>> receiveAutoAck(Integer integer) { + return this.delegate.receiveAutoAck(integer).map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Flux>> receiveAutoAck() { + return this.delegate.receiveAutoAck().map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Flux> receiveAtmostOnce(Integer integer) { + return this.buildAndFinishSpanOnNextConsumerRecord(this.delegate.receiveAtmostOnce(integer)); + } + + @Override + public Flux> receiveAtmostOnce() { + return this.buildAndFinishSpanOnNextConsumerRecord(this.delegate.receiveAtmostOnce()); + } + + @Override + public Flux>> receiveExactlyOnce(TransactionManager transactionManager) { + return this.delegate.receiveExactlyOnce(transactionManager).map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Flux>> receiveExactlyOnce(TransactionManager transactionManager, Integer integer) { + return this.delegate.receiveExactlyOnce(transactionManager, integer) + .map(this::buildAndFinishSpanOnNextConsumerRecord); + } + + @Override + public Mono doOnConsumer(Function, ? extends T> function) { + return this.delegate.doOnConsumer(function); + } + + private Flux> buildAndFinishSpanOnNextConsumerRecord(Flux> flux) { + return flux.doOnNext(consumerRecord -> KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, + this.extractor)); + } + + private Flux> buildAndFinishSpanOnNextReceiverRecord(Flux> flux) { + return flux.doOnNext(consumerRecord -> KafkaTracingUtils.buildAndFinishSpan(consumerRecord, this.propagator, + this.extractor)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallbackTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallbackTest.java new file mode 100644 index 000000000..44fc895c9 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaTracingCallbackTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; + +@ExtendWith(MockitoExtension.class) +public class KafkaTracingCallbackTest { + + @Mock + Tracer tracer; + + @Mock + Span span; + + @Mock + Callback callback; + + @Test + void should_call_on_completion_on_user_callback_success() { + KafkaTracingCallback tracingCallback = new KafkaTracingCallback(callback, tracer, span); + RecordMetadata recordMetadata = new RecordMetadata(null, 0, 0, 0, 0L, 0, 0); + + tracingCallback.onCompletion(recordMetadata, null); + + Mockito.verify(callback).onCompletion(eq(recordMetadata), isNull()); + } + + @Test + void should_call_on_completion_on_user_callback_error() { + KafkaTracingCallback tracingCallback = new KafkaTracingCallback(callback, tracer, span); + + tracingCallback.onCompletion(null, new RuntimeException()); + + Mockito.verify(callback).onCompletion(isNull(), any(RuntimeException.class)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumerTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumerTest.java new file mode 100644 index 000000000..c04c22d72 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaConsumerTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.TopicPartition; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +import static org.mockito.ArgumentMatchers.eq; + +@ExtendWith(MockitoExtension.class) +public class TracingKafkaConsumerTest { + + @Mock + KafkaConsumer kafkaConsumer; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + Propagator propagator; + + @Test + void should_delegate_poll_calls() { + Duration pollTimeout = Duration.of(5, ChronoUnit.SECONDS); + ConsumerRecord record = new ConsumerRecord<>("topic", 0, 1, "test-key", "test-value"); + Map>> map = new HashMap<>(); + map.put(new TopicPartition("topic", 0), Collections.singletonList(record)); + ConsumerRecords records = new ConsumerRecords<>(map); + BDDMockito.given(kafkaConsumer.poll(pollTimeout)).willReturn(records); + TracingKafkaConsumer tracingKafkaConsumer = new TracingKafkaConsumer<>(kafkaConsumer, + propagator, new TracingKafkaPropagatorGetter()); + + tracingKafkaConsumer.poll(pollTimeout); + + Mockito.verify(kafkaConsumer).poll(eq(pollTimeout)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerTest.java new file mode 100644 index 000000000..dcb3bab8b --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaProducerTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; + +@ExtendWith(MockitoExtension.class) +public class TracingKafkaProducerTest { + + @Mock + KafkaProducer kafkaProducer; + + @Mock + Propagator propagator; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + Tracer tracer; + + @Test + void should_delegate_send_calls() { + ProducerRecord testRecord = new ProducerRecord<>("test", "test"); + Callback callback = (record, ex) -> { + }; + TracingKafkaProducer tracingKafkaProducer = new TracingKafkaProducer<>(kafkaProducer, tracer, + propagator, new TracingKafkaPropagatorSetter()); + + tracingKafkaProducer.send(testRecord, callback); + + Mockito.verify(kafkaProducer).send(eq(testRecord), any()); + } + + @Test + void should_wrap_user_callback_on_send() { + ProducerRecord testRecord = new ProducerRecord<>("test", "test"); + Callback callback = (record, ex) -> { + }; + TracingKafkaProducer tracingKafkaProducer = new TracingKafkaProducer<>(kafkaProducer, tracer, + propagator, new TracingKafkaPropagatorSetter()); + + tracingKafkaProducer.send(testRecord, callback); + + ArgumentCaptor callbackArgument = ArgumentCaptor.forClass(KafkaTracingCallback.class); + Mockito.verify(kafkaProducer).send(any(), callbackArgument.capture()); + BDDAssertions.then(callbackArgument.getValue()).isNotNull(); + BDDAssertions.then(ReflectionTestUtils.getField(callbackArgument.getValue(), "callback")).isEqualTo(callback); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiverTest.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiverTest.java new file mode 100644 index 000000000..6707aeee6 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/kafka/TracingKafkaReceiverTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import java.util.function.Predicate; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import reactor.core.publisher.Flux; +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverOffset; +import reactor.kafka.receiver.ReceiverRecord; +import reactor.test.StepVerifier; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +@ExtendWith(MockitoExtension.class) +public class TracingKafkaReceiverTest { + + @Mock + KafkaReceiver kafkaReceiver; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + Propagator propagator; + + @Test + void should_delegate_receive_calls() { + ReceiverOffset receiverOffset = BDDMockito.mock(ReceiverOffset.class); + ConsumerRecord record = new ConsumerRecord<>("topic", 0, 1, "test-key", "test-value"); + ReceiverRecord receiverRecord = new ReceiverRecord<>(record, receiverOffset); + BDDMockito.given(kafkaReceiver.receive()).willReturn(Flux.just(receiverRecord)); + TracingKafkaReceiver tracingKafkaReceiver = new TracingKafkaReceiver<>(kafkaReceiver, + propagator, new TracingKafkaPropagatorGetter()); + + StepVerifier.create(tracingKafkaReceiver.receive()).expectNextMatches(Predicate.isEqual(receiverRecord)) + .verifyComplete(); + + Mockito.verify(kafkaReceiver).receive(); + } + +} diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index 2e21ae75f..621d49fe6 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -44,6 +44,7 @@ spring-cloud-sleuth-instrumentation-feign-tests spring-cloud-sleuth-instrumentation-gateway-tests spring-cloud-sleuth-instrumentation-grpc-tests + spring-cloud-sleuth-instrumentation-kafka-tests spring-cloud-sleuth-instrumentation-lettuce-tests spring-cloud-sleuth-instrumentation-messaging-tests spring-cloud-sleuth-instrumentation-mvc-tests diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/pom.xml new file mode 100644 index 000000000..6faff3f17 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/pom.xml @@ -0,0 +1,97 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-kafka-tests + jar + Spring Cloud Sleuth Brave Kafka Instrumentation Tests + Spring Cloud Sleuth Brave Kafka Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.projectreactor.kafka + reactor-kafka + true + + + org.testcontainers + testcontainers + + + org.testcontainers + junit-jupiter + + + org.testcontainers + kafka + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/kafka/KafkaProducerTest.java b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/kafka/KafkaProducerTest.java new file mode 100644 index 000000000..b19b6efc3 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-kafka-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/kafka/KafkaProducerTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.kafka; + +import org.springframework.cloud.sleuth.brave.BraveTestTracing; +import org.springframework.cloud.sleuth.test.TestTracingAware; + +public class KafkaProducerTest extends org.springframework.cloud.sleuth.instrument.kafka.KafkaProducerTest { + + BraveTestTracing testTracing; + + @Override + public TestTracingAware tracerTest() { + if (this.testTracing == null) { + this.testTracing = new BraveTestTracing(); + } + return this.testTracing; + } + +} diff --git a/tests/common/pom.xml b/tests/common/pom.xml index f405ccd78..16cb95b52 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -144,6 +144,26 @@ brave-tests true + + io.projectreactor.kafka + reactor-kafka + true + + + org.testcontainers + testcontainers + true + + + org.testcontainers + junit-jupiter + true + + + org.testcontainers + kafka + true + org.springframework.cloud spring-cloud-sleuth-zipkin diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaProducerTest.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaProducerTest.java new file mode 100644 index 000000000..c541eac73 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/kafka/KafkaProducerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.kafka; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.kafka.clients.producer.Callback; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.serialization.StringSerializer; +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.cloud.sleuth.test.TestTracingAwareSupplier; + +import static org.awaitility.Awaitility.await; + +@Testcontainers +public abstract class KafkaProducerTest implements TestTracingAwareSupplier { + + protected Tracer tracer = tracerTest().tracing().tracer(); + + protected Propagator propagator = tracerTest().tracing().propagator(); + + protected TestSpanHandler spans = tracerTest().handler(); + + protected TracingKafkaProducer kafkaProducer; + + @Container + protected final KafkaContainer kafkaContainer = new KafkaContainer( + DockerImageName.parse("confluentinc/cp-kafka:5.2.1")).withExposedPorts(9093) + .waitingFor(Wait.forListeningPort()); + + @BeforeEach + void setup() { + kafkaContainer.start(); + Map properties = new HashMap<>(); + properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaContainer.getBootstrapServers()); + properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + kafkaProducer = new TracingKafkaProducer<>(new KafkaProducer<>(properties), tracer, propagator, + new TracingKafkaPropagatorSetter()); + } + + @AfterEach + void destroy() { + kafkaContainer.stop(); + } + + @Test + public void should_create_and_finish_producer_span() { + AtomicBoolean acknowledged = new AtomicBoolean(false); + Callback callback = (metadata, ex) -> acknowledged.set(true); + ProducerRecord producerRecord = new ProducerRecord<>("spring-cloud-sleuth-otel-topic", "test", + "test"); + this.kafkaProducer.send(producerRecord, callback); + await().atMost(Duration.ofSeconds(5)).until(acknowledged::get); + + BDDAssertions.then(this.tracer.currentSpan()).isNull(); + BDDAssertions.then(this.spans).isNotEmpty(); + BDDAssertions.then(this.spans.get(0).getKind()).isEqualTo(Span.Kind.PRODUCER); + } + + @Override + public void cleanUpTracing() { + this.spans.clear(); + } + +} From 0f23f9d52fd7bf453debd8ff2846bc19f845f3bc Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 26 Apr 2021 15:19:51 +0200 Subject: [PATCH 73/78] Spring Cloud Deployer feature (#1925) * Spring Cloud Deployer; fixes gh-1905 * Polish --- pom.xml | 912 +++++++++--------- spring-cloud-sleuth-autoconfigure/pom.xml | 905 ++++++++--------- .../TraceDeployerAutoConfiguration.java | 52 + ...itional-spring-configuration-metadata.json | 306 +++--- .../main/resources/META-INF/spring.factories | 69 +- spring-cloud-sleuth-instrumentation/pom.xml | 443 ++++----- .../TraceReactiveCircuitBreaker.java | 69 +- .../instrument/deployer/TraceAppDeployer.java | 268 +++++ .../TraceAppDeployerBeanPostProcessor.java | 55 ++ .../reactor/ReactorHooksHelper.java | 9 +- .../instrument/reactor/ReactorSleuth.java | 134 ++- .../deployer/NoOpCurrentTraceContext.java | 71 ++ .../instrument/deployer/NoOpSpanInScope.java | 34 + .../instrument/deployer/NoOpTraceContext.java | 49 + .../instrument/deployer/SimpleSpan.java | 91 ++ .../instrument/deployer/SimpleTracer.java | 113 +++ .../deployer/TraceAppDeployerTests.java | 144 +++ 17 files changed, 2351 insertions(+), 1373 deletions(-) create mode 100644 spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/deployer/TraceDeployerAutoConfiguration.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerBeanPostProcessor.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpCurrentTraceContext.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpSpanInScope.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpTraceContext.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleSpan.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerTests.java diff --git a/pom.xml b/pom.xml index 7b1064f32..3da2a0c29 100644 --- a/pom.xml +++ b/pom.xml @@ -1,452 +1,460 @@ - - - - - 4.0.0 - - spring-cloud-sleuth - 3.1.0-SNAPSHOT - pom - Spring Cloud Sleuth - Spring Cloud Sleuth - - - org.springframework.cloud - spring-cloud-build - 3.0.3-SNAPSHOT - - - - - - https://github.com/spring-cloud/spring-cloud-sleuth - scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git - - - scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git - - HEAD - - - - spring-cloud-sleuth-dependencies - spring-cloud-sleuth-api - spring-cloud-sleuth-instrumentation - spring-cloud-sleuth-brave - spring-cloud-sleuth-autoconfigure - tests - spring-cloud-sleuth-zipkin - spring-cloud-starter-sleuth - spring-cloud-sleuth-samples - docs - - - - 1.8 - 1.8 - 1.8 - 1.8 - 3.0.3-SNAPSHOT - 3.0.3-SNAPSHOT - 3.0.3-SNAPSHOT - 3.0.3-SNAPSHOT - 2.0.2-SNAPSHOT - 3.1.3-SNAPSHOT - 3.1.3-SNAPSHOT - 3.0.3-SNAPSHOT - 3.0.3-SNAPSHOT - 2.3.2-SNAPSHOT - 5.13.2 - 0.32.0 - 2.3.4.RELEASE - false - 4.9.0 - 4.8.0 - 20.0 - 1.7.1 - 3.3.0 - 3.0.1 - 2.2.0.RELEASE - - - true - false - 3.8.1 - 2.2 - 4.0.3 - 0.21.3 - 0.14.1 - 1.15.3 - - - - - - - maven-compiler-plugin - 3.8.1 - - - default-compile - - true - true - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - default-testCompile - - true - true - - ${maven.compiler.testSource} - ${maven.compiler.testTarget} - - - - - - - maven-enforcer-plugin - 1.3.1 - - - enforce-java - - enforce - - - - - ${maven.compiler.testTarget} - - - - - - - - maven-deploy-plugin - 2.8.2 - - - - - - io.spring.javaformat - spring-javaformat-maven-plugin - - - maven-checkstyle-plugin - - - - - - - - maven-checkstyle-plugin - - - maven-surefire-report-plugin - - - - - - - - org.springframework.cloud - spring-cloud-sleuth-dependencies - ${project.version} - pom - import - - - org.springframework.cloud - spring-cloud-netflix-dependencies - ${spring-cloud-netflix.version} - pom - import - - - org.springframework.cloud - spring-cloud-commons-dependencies - ${spring-cloud-commons.version} - pom - import - - - org.springframework.cloud - spring-cloud-gateway-dependencies - ${spring-cloud-gateway.version} - pom - import - - - org.springframework.cloud - spring-cloud-circuitbreaker-dependencies - ${spring-cloud-circuitbreaker.version} - pom - import - - - org.springframework.cloud - spring-cloud-stream-dependencies - ${spring-cloud-stream.version} - pom - import - - - org.springframework.cloud - spring-cloud-function-dependencies - ${spring-cloud-function.version} - pom - import - - - org.springframework.cloud - spring-cloud-openfeign-dependencies - ${spring-cloud-openfeign.version} - pom - import - - - org.springframework.cloud - spring-cloud-config-dependencies - ${spring-cloud-config.version} - pom - import - - - org.springframework.cloud - spring-cloud-task-dependencies - ${spring-cloud-task.version} - pom - import - - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - ${spring-security-boot-autoconfigure.version} - true - - - cglib - cglib-nodep - ${cglib-nodep.version} - - - org.objenesis - objenesis - ${objenesis.version} - - - - com.squareup.okhttp3 - mockwebserver - ${mockwebserver.version} - - - org.springframework.security.oauth - spring-security-oauth2 - ${spring-security-oauth2.version} - - - io.zipkin.aws - brave-propagation-aws - ${brave-propagation-aws.version} - - - org.hamcrest - hamcrest-core - ${hamcrest-core.version} - test - - - org.awaitility - awaitility - ${awaitility.version} - test - - - com.tngtech.archunit - archunit-junit5 - ${archunit-junit5.version} - - - org.testcontainers - testcontainers-bom - ${testcontainers.version} - pom - import - - - - - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - - jfrog-snapshots - JFrog Snapshots - https://oss.jfrog.org/oss-snapshot-local/ - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - ide - - false - - - - - maven-compiler-plugin - - ${maven.compiler.testSource} - ${maven.compiler.testTarget} - - - - - - - benchmarks - - false - - - benchmarks - - - - sonar - - - - org.jacoco - jacoco-maven-plugin - - - pre-unit-test - - prepare-agent - - - surefireArgLine - ${project.build.directory}/jacoco.exec - - - - - post-unit-test - test - - report - - - - ${project.build.directory}/jacoco.exec - - - - - - - maven-surefire-plugin - - - ${surefireArgLine} - - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth + 3.1.0-SNAPSHOT + pom + Spring Cloud Sleuth + Spring Cloud Sleuth + + + org.springframework.cloud + spring-cloud-build + 3.0.3-SNAPSHOT + + + + + + https://github.com/spring-cloud/spring-cloud-sleuth + scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git + + + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git + + HEAD + + + + spring-cloud-sleuth-dependencies + spring-cloud-sleuth-api + spring-cloud-sleuth-instrumentation + spring-cloud-sleuth-brave + spring-cloud-sleuth-autoconfigure + tests + spring-cloud-sleuth-zipkin + spring-cloud-starter-sleuth + spring-cloud-sleuth-samples + docs + + + + 1.8 + 1.8 + 1.8 + 1.8 + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 2.0.2-SNAPSHOT + 3.1.3-SNAPSHOT + 3.1.3-SNAPSHOT + 3.0.3-SNAPSHOT + 3.0.3-SNAPSHOT + 2.3.2-SNAPSHOT + 2.5.1 + 5.13.2 + 0.32.0 + 2.3.4.RELEASE + false + 4.9.0 + 4.8.0 + 20.0 + 1.7.1 + 3.3.0 + 3.0.1 + 2.2.0.RELEASE + + + true + false + 3.8.1 + 2.2 + 4.0.3 + 0.21.3 + 0.14.1 + 1.15.3 + + + + + + + maven-compiler-plugin + 3.8.1 + + + default-compile + + true + true + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + default-testCompile + + true + true + + ${maven.compiler.testSource} + ${maven.compiler.testTarget} + + + + + + + maven-enforcer-plugin + 1.3.1 + + + enforce-java + + enforce + + + + + ${maven.compiler.testTarget} + + + + + + + + maven-deploy-plugin + 2.8.2 + + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + + + maven-checkstyle-plugin + + + + + + + + maven-checkstyle-plugin + + + maven-surefire-report-plugin + + + + + + + + org.springframework.cloud + spring-cloud-sleuth-dependencies + ${project.version} + pom + import + + + org.springframework.cloud + spring-cloud-netflix-dependencies + ${spring-cloud-netflix.version} + pom + import + + + org.springframework.cloud + spring-cloud-commons-dependencies + ${spring-cloud-commons.version} + pom + import + + + org.springframework.cloud + spring-cloud-gateway-dependencies + ${spring-cloud-gateway.version} + pom + import + + + org.springframework.cloud + spring-cloud-circuitbreaker-dependencies + ${spring-cloud-circuitbreaker.version} + pom + import + + + org.springframework.cloud + spring-cloud-stream-dependencies + ${spring-cloud-stream.version} + pom + import + + + org.springframework.cloud + spring-cloud-function-dependencies + ${spring-cloud-function.version} + pom + import + + + org.springframework.cloud + spring-cloud-openfeign-dependencies + ${spring-cloud-openfeign.version} + pom + import + + + org.springframework.cloud + spring-cloud-config-dependencies + ${spring-cloud-config.version} + pom + import + + + org.springframework.cloud + spring-cloud-task-dependencies + ${spring-cloud-task.version} + pom + import + + + org.springframework.cloud + spring-cloud-deployer-dependencies + ${spring-cloud-deployer.version} + import + pom + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${spring-security-boot-autoconfigure.version} + true + + + cglib + cglib-nodep + ${cglib-nodep.version} + + + org.objenesis + objenesis + ${objenesis.version} + + + + com.squareup.okhttp3 + mockwebserver + ${mockwebserver.version} + + + org.springframework.security.oauth + spring-security-oauth2 + ${spring-security-oauth2.version} + + + io.zipkin.aws + brave-propagation-aws + ${brave-propagation-aws.version} + + + org.hamcrest + hamcrest-core + ${hamcrest-core.version} + test + + + org.awaitility + awaitility + ${awaitility.version} + test + + + com.tngtech.archunit + archunit-junit5 + ${archunit-junit5.version} + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + + + + + spring + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + false + + + + + jfrog-snapshots + JFrog Snapshots + https://oss.jfrog.org/oss-snapshot-local/ + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + ide + + false + + + + + maven-compiler-plugin + + ${maven.compiler.testSource} + ${maven.compiler.testTarget} + + + + + + + benchmarks + + false + + + benchmarks + + + + sonar + + + + org.jacoco + jacoco-maven-plugin + + + pre-unit-test + + prepare-agent + + + surefireArgLine + ${project.build.directory}/jacoco.exec + + + + + post-unit-test + test + + report + + + + ${project.build.directory}/jacoco.exec + + + + + + + maven-surefire-plugin + + + ${surefireArgLine} + + + + + + + + diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index ac237bbf7..994f00cd4 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -1,450 +1,455 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-autoconfigure - jar - Spring Cloud Sleuth AutoConfigure - Spring Cloud Sleuth AutoConfigure - - - org.springframework.cloud - spring-cloud-sleuth - 3.1.0-SNAPSHOT - .. - - - - - - org.springframework.cloud - spring-cloud-sleuth-instrumentation - - - org.springframework.boot - spring-boot-starter-web - true - - - io.micrometer - micrometer-core - true - - - io.projectreactor - reactor-core - true - - - org.reactivestreams - reactive-streams - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.integration - spring-integration-core - true - - - org.springframework.cloud - spring-cloud-config-server - true - - - org.springframework.cloud - spring-cloud-starter-config - true - - - org.springframework.cloud - spring-cloud-function-context - true - - - org.springframework.boot - spring-boot-starter-websocket - true - - - org.springframework.cloud - spring-cloud-stream - - ${spring-cloud-stream.version} - true - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework - spring-context - - - org.springframework.cloud - spring-cloud-context - true - - - org.springframework.cloud - spring-cloud-starter-task - true - - - io.reactivex - rxjava - true - - - io.github.openfeign - feign-okhttp - true - - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - true - - - org.springframework.cloud - spring-cloud-starter-gateway - true - - - org.aspectj - aspectjrt - - - - org.springframework.boot - spring-boot-starter-quartz - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.security.oauth - spring-security-oauth2 - true - - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - true - - - - - org.springframework.cloud - spring-cloud-sleuth-brave - true - - - io.zipkin.brave - brave - - - io.zipkin.reporter2 - * - - - io.zipkin.zipkin2 - * - - - true - - - io.zipkin.brave - brave-context-slf4j - true - - - io.zipkin.brave - brave-instrumentation-messaging - true - - - io.zipkin.brave - brave-instrumentation-rpc - true - - - io.zipkin.brave - brave-instrumentation-spring-rabbit - true - - - io.zipkin.brave - brave-instrumentation-kafka-clients - true - - - io.zipkin.brave - brave-instrumentation-kafka-streams - true - - - io.zipkin.brave - brave-instrumentation-httpclient - true - - - io.zipkin.brave - brave-instrumentation-httpasyncclient - true - - - io.zipkin.brave - brave-instrumentation-jms - true - - - io.zipkin.brave - brave-instrumentation-mongodb - true - - - io.zipkin.aws - brave-propagation-aws - true - - - javax.jms - javax.jms-api - true - - - io.opentracing.brave - brave-opentracing - true - - - org.apache.httpcomponents - httpasyncclient - true - - - org.springframework - spring-jms - true - - - - io.github.lognet - grpc-spring-boot-starter - true - - - org.springframework.boot - spring-boot-starter - - - - - io.zipkin.brave - brave-instrumentation-grpc - true - - - io.zipkin.reporter2 - zipkin-reporter-metrics-micrometer - - - io.micrometer - micrometer-core - - - true - - - - io.lettuce - lettuce-core - true - - - org.springframework.kafka - spring-kafka - true - - - org.apache.kafka - kafka-streams - true - - - org.springframework.amqp - spring-rabbit - true - - - org.springframework.boot - spring-boot-starter-data-mongodb - true - - - - - org.springframework.cloud - spring-cloud-sleuth-zipkin - true - - - io.zipkin.zipkin2 - zipkin - true - - - io.zipkin.reporter2 - zipkin-reporter - true - - - io.zipkin.reporter2 - zipkin-reporter-brave - true - - - io.zipkin.reporter2 - zipkin-sender-kafka - true - - - - org.apache.kafka - kafka-clients - - - - - io.zipkin.reporter2 - zipkin-sender-activemq-client - true - - - org.apache.activemq - activemq-client - - - - - org.apache.activemq - activemq-client - true - - - io.zipkin.reporter2 - zipkin-sender-amqp-client - true - - - - com.rabbitmq - amqp-client - - - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.awaitility - awaitility - test - - - org.mongodb - mongodb-driver-reactivestreams - test - - - - - io.zipkin.brave - brave-instrumentation-http-tests - test - - - com.squareup.okhttp3 - mockwebserver - test - - - - - com.squareup.okhttp3 - okhttp - - 4.8.0 - test - - - com.tngtech.archunit - archunit-junit5 - test - - - - - - - fast - - false - - - - - maven-surefire-plugin - - 4 - true - -Xmx1024m -XX:MaxPermSize=256m - - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-autoconfigure + jar + Spring Cloud Sleuth AutoConfigure + Spring Cloud Sleuth AutoConfigure + + + org.springframework.cloud + spring-cloud-sleuth + 3.1.0-SNAPSHOT + .. + + + + + + org.springframework.cloud + spring-cloud-sleuth-instrumentation + + + org.springframework.boot + spring-boot-starter-web + true + + + io.micrometer + micrometer-core + true + + + io.projectreactor + reactor-core + true + + + org.reactivestreams + reactive-streams + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.integration + spring-integration-core + true + + + org.springframework.cloud + spring-cloud-config-server + true + + + org.springframework.cloud + spring-cloud-starter-config + true + + + org.springframework.cloud + spring-cloud-function-context + true + + + org.springframework.boot + spring-boot-starter-websocket + true + + + org.springframework.cloud + spring-cloud-stream + + ${spring-cloud-stream.version} + true + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework + spring-context + + + org.springframework.cloud + spring-cloud-context + true + + + org.springframework.cloud + spring-cloud-starter-task + true + + + org.springframework.cloud + spring-cloud-deployer-spi + true + + + io.reactivex + rxjava + true + + + io.github.openfeign + feign-okhttp + true + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + true + + + org.springframework.cloud + spring-cloud-starter-gateway + true + + + org.aspectj + aspectjrt + + + + org.springframework.boot + spring-boot-starter-quartz + true + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + org.springframework.security.oauth + spring-security-oauth2 + true + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + true + + + + + org.springframework.cloud + spring-cloud-sleuth-brave + true + + + io.zipkin.brave + brave + + + io.zipkin.reporter2 + * + + + io.zipkin.zipkin2 + * + + + true + + + io.zipkin.brave + brave-context-slf4j + true + + + io.zipkin.brave + brave-instrumentation-messaging + true + + + io.zipkin.brave + brave-instrumentation-rpc + true + + + io.zipkin.brave + brave-instrumentation-spring-rabbit + true + + + io.zipkin.brave + brave-instrumentation-kafka-clients + true + + + io.zipkin.brave + brave-instrumentation-kafka-streams + true + + + io.zipkin.brave + brave-instrumentation-httpclient + true + + + io.zipkin.brave + brave-instrumentation-httpasyncclient + true + + + io.zipkin.brave + brave-instrumentation-jms + true + + + io.zipkin.brave + brave-instrumentation-mongodb + true + + + io.zipkin.aws + brave-propagation-aws + true + + + javax.jms + javax.jms-api + true + + + io.opentracing.brave + brave-opentracing + true + + + org.apache.httpcomponents + httpasyncclient + true + + + org.springframework + spring-jms + true + + + + io.github.lognet + grpc-spring-boot-starter + true + + + org.springframework.boot + spring-boot-starter + + + + + io.zipkin.brave + brave-instrumentation-grpc + true + + + io.zipkin.reporter2 + zipkin-reporter-metrics-micrometer + + + io.micrometer + micrometer-core + + + true + + + + io.lettuce + lettuce-core + true + + + org.springframework.kafka + spring-kafka + true + + + org.apache.kafka + kafka-streams + true + + + org.springframework.amqp + spring-rabbit + true + + + org.springframework.boot + spring-boot-starter-data-mongodb + true + + + + + org.springframework.cloud + spring-cloud-sleuth-zipkin + true + + + io.zipkin.zipkin2 + zipkin + true + + + io.zipkin.reporter2 + zipkin-reporter + true + + + io.zipkin.reporter2 + zipkin-reporter-brave + true + + + io.zipkin.reporter2 + zipkin-sender-kafka + true + + + + org.apache.kafka + kafka-clients + + + + + io.zipkin.reporter2 + zipkin-sender-activemq-client + true + + + org.apache.activemq + activemq-client + + + + + org.apache.activemq + activemq-client + true + + + io.zipkin.reporter2 + zipkin-sender-amqp-client + true + + + + com.rabbitmq + amqp-client + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.awaitility + awaitility + test + + + org.mongodb + mongodb-driver-reactivestreams + test + + + + + io.zipkin.brave + brave-instrumentation-http-tests + test + + + com.squareup.okhttp3 + mockwebserver + test + + + + + com.squareup.okhttp3 + okhttp + + 4.8.0 + test + + + com.tngtech.archunit + archunit-junit5 + test + + + + + + + fast + + false + + + + + maven-surefire-plugin + + 4 + true + -Xmx1024m -XX:MaxPermSize=256m + + + + + + + + diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/deployer/TraceDeployerAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/deployer/TraceDeployerAutoConfiguration.java new file mode 100644 index 000000000..45b7b577c --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/deployer/TraceDeployerAutoConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.deployer; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.instrument.deployer.TraceAppDeployerBeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration + * Auto-configuration} that registers instrumentation for app deployers. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean(Tracer.class) +@ConditionalOnProperty(value = "spring.sleuth.deployer.enabled", matchIfMissing = true) +@ConditionalOnClass(AppDeployer.class) +@AutoConfigureAfter(BraveAutoConfiguration.class) +public class TraceDeployerAutoConfiguration { + + @Bean + static TraceAppDeployerBeanPostProcessor traceAppDeployerBeanPostProcessor(BeanFactory beanFactory, + Environment environment) { + return new TraceAppDeployerBeanPostProcessor(beanFactory, environment); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index b2ebb1d5a..ec3dadb1b 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,147 +1,159 @@ -{ - "properties": [ - { - "name": "spring.zipkin.kafka.topic", - "type": "java.lang.String", - "description": "Name of the Kafka topic where spans should be sent to Zipkin.", - "defaultValue": "zipkin" - }, - { - "name": "spring.zipkin.rabbitmq.queue", - "type": "java.lang.String", - "description": "Name of the RabbitMQ queue where spans should be sent to Zipkin.", - "defaultValue": "zipkin" - }, - { - "name": "spring.zipkin.rabbitmq.addresses", - "type": "java.lang.String", - "description": "Addresses of the RabbitMQ brokers used to send spans to Zipkin" - }, - { - "name": "spring.zipkin.activemq.queue", - "type": "java.lang.String", - "description": "Name of the ActiveMQ queue where spans should be sent to Zipkin.", - "defaultValue": "zipkin" - }, - { - "name": "spring.zipkin.activemq.message-max-bytes", - "type": "java.lang.String", - "description": "Maximum number of bytes for a given message with spans sent to Zipkin over ActiveMQ.", - "defaultValue": 100000 - }, - { - "name": "spring.sleuth.function.enabled", - "type": "java.lang.Boolean", - "description": "Enable instrumenting of Spring Cloud Function and Spring Cloud Function based projects (e.g. Spring Cloud Stream).", - "defaultValue": true - }, - { - "name": "spring.sleuth.integration.websockets.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing for WebSockets.", - "defaultValue": true - }, - { - "name": "spring.sleuth.async.enabled", - "type": "java.lang.Boolean", - "description": "Enable instrumenting async related components so that the tracing information is passed between threads.", - "defaultValue": true - }, - { - "name": "spring.sleuth.async.configurer.enabled", - "type": "java.lang.Boolean", - "description": "Enable default AsyncConfigurer.", - "defaultValue": true - }, - { - "name": "spring.sleuth.feign.enabled", - "type": "java.lang.Boolean", - "description": "Enable span information propagation when using Feign.", - "defaultValue": true - }, - { - "name": "spring.sleuth.feign.processor.enabled", - "type": "java.lang.Boolean", - "description": "Enable post processor that wraps Feign Context in its tracing representations.", - "defaultValue": true - }, - { - "name": "spring.sleuth.grpc.enabled", - "type": "java.lang.Boolean", - "description": "Enable span information propagation when using GRPC.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.jms.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of JMS.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.rabbit.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of RabbitMQ.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.kafka.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of Kafka.", - "defaultValue": true - }, - { - "name": "spring.sleuth.messaging.kafka.mapper.enabled", - "type": "java.lang.Boolean", - "description": "Enable DefaultKafkaHeaderMapper tracing for Kafka.", - "defaultValue": true - }, - { - "name": "spring.sleuth.quartz.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing for Quartz.", - "defaultValue": true - }, - { - "name": "spring.sleuth.mongodb.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing for MongoDb.", - "defaultValue": true - }, - { - "name": "spring.sleuth.rpc.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing of RPC.", - "defaultValue": true - }, - { - "name": "spring.sleuth.sampler.refresh.enabled", - "type": "java.lang.Boolean", - "description": "Enable refresh scope for sampler.", - "defaultValue": true - }, - { - "name": "spring.sleuth.web.webclient.enabled", - "type": "java.lang.Boolean", - "description": "Enable tracing instrumentation for WebClient.", - "defaultValue": true - }, - { - "name": "spring.sleuth.integration.enabled", - "type": "java.lang.Boolean", - "description": "Enable Spring Integration instrumentation.", - "defaultValue": true - }, - { - "name": "spring.sleuth.task.enabled", - "type": "java.lang.Boolean", - "description": "Enable Spring Cloud Task instrumentation.", - "defaultValue": true - }, - { - "name": "spring.sleuth.config.server.enabled", - "type": "java.lang.Boolean", - "description": "Enable Spring Cloud Config Server instrumentation.", - "defaultValue": true - } - ] -} +{ + "properties": [ + { + "name": "spring.zipkin.kafka.topic", + "type": "java.lang.String", + "description": "Name of the Kafka topic where spans should be sent to Zipkin.", + "defaultValue": "zipkin" + }, + { + "name": "spring.zipkin.rabbitmq.queue", + "type": "java.lang.String", + "description": "Name of the RabbitMQ queue where spans should be sent to Zipkin.", + "defaultValue": "zipkin" + }, + { + "name": "spring.zipkin.rabbitmq.addresses", + "type": "java.lang.String", + "description": "Addresses of the RabbitMQ brokers used to send spans to Zipkin" + }, + { + "name": "spring.zipkin.activemq.queue", + "type": "java.lang.String", + "description": "Name of the ActiveMQ queue where spans should be sent to Zipkin.", + "defaultValue": "zipkin" + }, + { + "name": "spring.zipkin.activemq.message-max-bytes", + "type": "java.lang.String", + "description": "Maximum number of bytes for a given message with spans sent to Zipkin over ActiveMQ.", + "defaultValue": 100000 + }, + { + "name": "spring.sleuth.function.enabled", + "type": "java.lang.Boolean", + "description": "Enable instrumenting of Spring Cloud Function and Spring Cloud Function based projects (e.g. Spring Cloud Stream).", + "defaultValue": true + }, + { + "name": "spring.sleuth.integration.websockets.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing for WebSockets.", + "defaultValue": true + }, + { + "name": "spring.sleuth.async.enabled", + "type": "java.lang.Boolean", + "description": "Enable instrumenting async related components so that the tracing information is passed between threads.", + "defaultValue": true + }, + { + "name": "spring.sleuth.async.configurer.enabled", + "type": "java.lang.Boolean", + "description": "Enable default AsyncConfigurer.", + "defaultValue": true + }, + { + "name": "spring.sleuth.feign.enabled", + "type": "java.lang.Boolean", + "description": "Enable span information propagation when using Feign.", + "defaultValue": true + }, + { + "name": "spring.sleuth.feign.processor.enabled", + "type": "java.lang.Boolean", + "description": "Enable post processor that wraps Feign Context in its tracing representations.", + "defaultValue": true + }, + { + "name": "spring.sleuth.grpc.enabled", + "type": "java.lang.Boolean", + "description": "Enable span information propagation when using GRPC.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.jms.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of JMS.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.rabbit.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of RabbitMQ.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.kafka.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of Kafka.", + "defaultValue": true + }, + { + "name": "spring.sleuth.messaging.kafka.mapper.enabled", + "type": "java.lang.Boolean", + "description": "Enable DefaultKafkaHeaderMapper tracing for Kafka.", + "defaultValue": true + }, + { + "name": "spring.sleuth.quartz.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing for Quartz.", + "defaultValue": true + }, + { + "name": "spring.sleuth.mongodb.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing for MongoDb.", + "defaultValue": true + }, + { + "name": "spring.sleuth.rpc.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing of RPC.", + "defaultValue": true + }, + { + "name": "spring.sleuth.sampler.refresh.enabled", + "type": "java.lang.Boolean", + "description": "Enable refresh scope for sampler.", + "defaultValue": true + }, + { + "name": "spring.sleuth.web.webclient.enabled", + "type": "java.lang.Boolean", + "description": "Enable tracing instrumentation for WebClient.", + "defaultValue": true + }, + { + "name": "spring.sleuth.integration.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Integration instrumentation.", + "defaultValue": true + }, + { + "name": "spring.sleuth.task.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Task instrumentation.", + "defaultValue": true + }, + { + "name": "spring.sleuth.deployer.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Deployer instrumentation.", + "defaultValue": true + }, + { + "name": "spring.sleuth.deployer.status-poll-delay", + "type": "java.lang.Long", + "description": "Default poll delay to retrieve the deployed application status.", + "defaultValue": 1000 + }, + { + "name": "spring.sleuth.config.server.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring Cloud Config Server instrumentation.", + "defaultValue": true + } + ] +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories index d2df0f518..d96b177e0 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,34 +1,35 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncCustomAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncDefaultAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.config.TraceSpringCloudConfigAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.circuitbreaker.TraceCircuitBreakerAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.rxjava.TraceRxJavaAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.quartz.TraceQuartzAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.task.TraceTaskAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.feign.TraceFeignClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebAsyncClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.scheduling.TraceSchedulingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceFunctionAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringMessagingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceWebSocketAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.client.BraveWebClientAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.rpc.BraveRpcAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.grpc.BraveGrpcAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveKafkaStreamsAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveMessagingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.opentracing.BraveOpentracingAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.redis.BraveRedisAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.brave.instrument.mongodb.BraveMongoDbAutoConfiguration,\ -org.springframework.cloud.sleuth.autoconfig.zipkin2.ZipkinAutoConfiguration -# Environment Post Processor -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.cloud.sleuth.autoconfig.TraceEnvironmentPostProcessor,\ -org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceGatewayEnvironmentPostProcessor \ No newline at end of file +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncCustomAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncDefaultAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.config.TraceSpringCloudConfigAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.circuitbreaker.TraceCircuitBreakerAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.deployer.TraceDeployerAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.rxjava.TraceRxJavaAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.quartz.TraceQuartzAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.task.TraceTaskAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.feign.TraceFeignClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebAsyncClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.scheduling.TraceSchedulingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceFunctionAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringMessagingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceWebSocketAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.client.BraveWebClientAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.rpc.BraveRpcAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.grpc.BraveGrpcAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveKafkaStreamsAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging.BraveMessagingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.opentracing.BraveOpentracingAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.redis.BraveRedisAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.brave.instrument.mongodb.BraveMongoDbAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.zipkin2.ZipkinAutoConfiguration +# Environment Post Processor +org.springframework.boot.env.EnvironmentPostProcessor=\ +org.springframework.cloud.sleuth.autoconfig.TraceEnvironmentPostProcessor,\ +org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceGatewayEnvironmentPostProcessor diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 4793fa853..0dfdf55a4 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -1,219 +1,224 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-instrumentation - jar - Spring Cloud Sleuth Instrumentation - Spring Cloud Sleuth Instrumentation - - - org.springframework.cloud - spring-cloud-sleuth - 3.1.0-SNAPSHOT - .. - - - - - org.springframework.cloud - spring-cloud-sleuth-api - - - org.springframework.boot - spring-boot-starter-web - true - - - io.micrometer - micrometer-core - true - - - io.projectreactor - reactor-core - true - - - io.projectreactor.kafka - reactor-kafka - true - - - org.reactivestreams - reactive-streams - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.integration - spring-integration-core - true - - - org.springframework.cloud - spring-cloud-config-server - true - - - org.springframework.cloud - spring-cloud-starter-config - true - - - org.springframework.cloud - spring-cloud-function-context - true - - - org.springframework.boot - spring-boot-starter-websocket - true - - - org.springframework.cloud - spring-cloud-stream - - ${spring-cloud-stream.version} - true - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework - spring-context - - - org.springframework.cloud - spring-cloud-context - true - - - io.reactivex - rxjava - true - - - io.github.openfeign - feign-okhttp - true - - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - true - - - org.springframework.cloud - spring-cloud-starter-gateway - true - - - org.springframework.cloud - spring-cloud-starter-task - true - - - org.aspectj - aspectjrt - - - - org.springframework.boot - spring-boot-starter-quartz - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.security.oauth - spring-security-oauth2 - true - - - org.springframework.security.oauth.boot - spring-security-oauth2-autoconfigure - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.awaitility - awaitility - test - - - com.tngtech.archunit - archunit-junit5 - test - - - io.projectreactor - reactor-test - test - - - - - - fast - - false - - - - - maven-surefire-plugin - - 4 - true - -Xmx1024m -XX:MaxPermSize=256m - - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation + jar + Spring Cloud Sleuth Instrumentation + Spring Cloud Sleuth Instrumentation + + + org.springframework.cloud + spring-cloud-sleuth + 3.1.0-SNAPSHOT + .. + + + + + org.springframework.cloud + spring-cloud-sleuth-api + + + org.springframework.boot + spring-boot-starter-web + true + + + io.micrometer + micrometer-core + true + + + io.projectreactor + reactor-core + true + + + io.projectreactor.kafka + reactor-kafka + true + + + org.reactivestreams + reactive-streams + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.integration + spring-integration-core + true + + + org.springframework.cloud + spring-cloud-config-server + true + + + org.springframework.cloud + spring-cloud-starter-config + true + + + org.springframework.cloud + spring-cloud-function-context + true + + + org.springframework.boot + spring-boot-starter-websocket + true + + + org.springframework.cloud + spring-cloud-stream + + ${spring-cloud-stream.version} + true + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework + spring-context + + + org.springframework.cloud + spring-cloud-context + true + + + io.reactivex + rxjava + true + + + io.github.openfeign + feign-okhttp + true + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + true + + + org.springframework.cloud + spring-cloud-starter-gateway + true + + + org.springframework.cloud + spring-cloud-starter-task + true + + + org.springframework.cloud + spring-cloud-deployer-spi + true + + + org.aspectj + aspectjrt + + + + org.springframework.boot + spring-boot-starter-quartz + true + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + org.springframework.security.oauth + spring-security-oauth2 + true + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.awaitility + awaitility + test + + + com.tngtech.archunit + archunit-junit5 + test + + + io.projectreactor + reactor-test + test + + + + + + fast + + false + + + + + maven-surefire-plugin + + 4 + true + -Xmx1024m -XX:MaxPermSize=256m + + + + + + + + diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java index b283db6e8..ecf8cce3c 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/TraceReactiveCircuitBreaker.java @@ -19,22 +19,16 @@ package org.springframework.cloud.sleuth.instrument.circuitbreaker; import java.util.function.Function; import java.util.function.Supplier; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import reactor.util.context.Context; import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; import org.springframework.cloud.sleuth.CurrentTraceContext; -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.TraceContext; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; class TraceReactiveCircuitBreaker implements ReactiveCircuitBreaker { - private static final Log log = LogFactory.getLog(TraceReactiveCircuitBreaker.class); - private final ReactiveCircuitBreaker delegate; private final Tracer tracer; @@ -71,68 +65,11 @@ class TraceReactiveCircuitBreaker implements ReactiveCircuitBreaker { } private Mono runAndTraceMono(Supplier> mono) { - return Mono.deferContextual(contextView -> { - Span span = contextView.get(Span.class); - Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); - return mono.get().doOnError(span::error).doFinally(signalType -> { - span.end(); - scope.close(); - }); - }).contextWrite(this::enhanceContext); + return ReactorSleuth.tracedMono(this.tracer, this.currentTraceContext, "function", mono); } private Flux runAndTraceFlux(Supplier> flux) { - return Flux.deferContextual(contextView -> { - Span span = contextView.get(Span.class); - Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); - return flux.get().doOnError(span::error).doFinally(signalType -> { - span.end(); - scope.close(); - }); - }).contextWrite(this::enhanceContext); - } - - private Span spanFromContext(reactor.util.context.Context context) { - TraceContext traceContext = context.getOrDefault(TraceContext.class, null); - Span span = null; - if (traceContext == null) { - span = context.getOrDefault(Span.class, null); - } - if (traceContext == null && span == null) { - span = this.tracer.nextSpan(); - if (log.isDebugEnabled()) { - log.debug("There was no previous span in reactor context, created a new one [" + span + "]"); - } - } - else if (traceContext != null) { - // there was a previous span - we create a child one - try (CurrentTraceContext.Scope scope = this.currentTraceContext.maybeScope(traceContext)) { - if (log.isDebugEnabled()) { - log.debug("Found a trace context in reactor context [" + traceContext + "]"); - } - span = this.tracer.nextSpan(); - if (log.isDebugEnabled()) { - log.debug("Created a child span [" + span + "]"); - } - } - } - else { - if (log.isDebugEnabled()) { - log.debug("Found a span in reactor context [" + span + "]"); - } - span = this.tracer.nextSpan(span); - if (log.isDebugEnabled()) { - log.debug("Created a child span [" + span + "]"); - } - } - // TODO: Better name? - return span.name("function"); - } - - private Context enhanceContext(Context context) { - Span span = spanFromContext(context); - return context.put(Span.class, span).put(TraceContext.class, span.context()).put(Tracer.SpanInScope.class, - this.tracer.withSpan(span)); + return ReactorSleuth.tracedFlux(this.tracer, this.currentTraceContext, "function", flux); } } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java new file mode 100644 index 000000000..4ea4de184 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java @@ -0,0 +1,268 @@ +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.deployer; + +import java.time.Duration; +import java.util.Arrays; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.deployer.spi.app.AppScaleRequest; +import org.springframework.cloud.deployer.spi.app.AppStatus; +import org.springframework.cloud.deployer.spi.app.DeploymentState; +import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; +import org.springframework.cloud.deployer.spi.core.RuntimeEnvironmentInfo; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; +import org.springframework.core.env.Environment; + +/** + * Trace representation of an {@link AppDeployer}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceAppDeployer implements AppDeployer { + + private static final Log log = LogFactory.getLog(TraceAppDeployer.class); + + private final AppDeployer delegate; + + private final BeanFactory beanFactory; + + private final Environment environment; + + private Tracer tracer; + + private CurrentTraceContext currentTraceContext; + + private Long pollDelay; + + public TraceAppDeployer(AppDeployer delegate, BeanFactory beanFactory, Environment environment) { + this.delegate = delegate; + this.beanFactory = beanFactory; + this.environment = environment; + } + + @Override + public String deploy(AppDeploymentRequest request) { + Span span = tracer().nextSpan().name("deploy"); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (!request.getCommandlineArguments().isEmpty()) { + // span.tag("commandlineArguments", request.getCommandlineArguments().toString()); + // } + // if (!request.getDeploymentProperties().isEmpty()) { + // span.tag("deploymentProperties", request.getDeploymentProperties().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + String id = this.delegate.deploy(request); + span.tag("id", id); + registerListener(span, id); + return id; + } + } + + private void registerListener(Span span, String id) { + PreviousAndCurrentStatus previousAndCurrentStatus = new PreviousAndCurrentStatus(span); + // @formatter:off + this.delegate.statusReactive(id) + .map(previousAndCurrentStatus::updateCurrent) + .repeatWhen(repeat -> repeat.flatMap(i -> Mono.delay(Duration.ofMillis(pollDelay())))) + .takeUntil(PreviousAndCurrentStatus::isFinished) + .last() + .doOnNext(PreviousAndCurrentStatus::annotateSpan) + .doOnError(span::error) + // we will close the span in the reactive part + .doFinally(signalType -> span.end()).subscribe(); + // @formatter:on + } + + @Override + public void undeploy(String id) { + Span span = tracer().nextSpan().name("undeploy"); + span.tag("id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + this.delegate.undeploy(id); + registerListener(span, id); + } + finally { + span.end(); + } + } + + @Override + public AppStatus status(String id) { + Span span = tracer().nextSpan().name("status"); + span.tag("id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.status(id); + } + finally { + span.end(); + } + } + + @Override + public Mono statusReactive(String id) { + return ReactorSleuth.tracedMono(tracer(), currentTraceContext(), "status", + () -> this.delegate.statusReactive(id), span -> span.tag("id", id)); + } + + @Override + public Flux statusesReactive(String... ids) { + return ReactorSleuth.tracedFlux(tracer(), currentTraceContext(), "statuses", + () -> this.delegate.statusesReactive(ids), span -> span.tag("ids", Arrays.toString(ids))); + } + + @Override + public RuntimeEnvironmentInfo environmentInfo() { + return this.delegate.environmentInfo(); + } + + @Override + public String getLog(String id) { + Span span = tracer().nextSpan().name("getLog"); + span.tag("id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.getLog(id); + } + finally { + span.end(); + } + } + + @Override + public void scale(AppScaleRequest appScaleRequest) { + Span span = tracer().nextSpan().name("scale"); + span.tag("deploymentId", appScaleRequest.getDeploymentId()); + span.tag("count", String.valueOf(appScaleRequest.getCount())); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (appScaleRequest.getProperties().isPresent() && + // !appScaleRequest.getProperties().get().isEmpty()) { + // span.tag("properties", appScaleRequest.getProperties().get().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.scale(appScaleRequest); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + + private CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.beanFactory.getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + + private long pollDelay() { + if (this.pollDelay == null) { + this.pollDelay = this.environment.getProperty("spring.sleuth.deployer.status-poll-delay", Long.class, 500L); + } + return this.pollDelay; + } + + private static final class PreviousAndCurrentStatus { + + private final Span span; + + private AppStatus current; + + private AppStatus previous; + + private PreviousAndCurrentStatus(Span span) { + this.span = span; + if (log.isDebugEnabled()) { + log.debug("Current span is [" + span + "]"); + } + } + + private PreviousAndCurrentStatus updateCurrent(AppStatus current) { + if (log.isTraceEnabled()) { + log.trace("State before change: current [" + this.current + "], previous [" + this.previous + "]"); + } + this.previous = this.current; + this.current = current; + if (log.isTraceEnabled()) { + log.trace("State after change: current [" + this.current + "], previous [" + this.previous + "]"); + } + if (statusChanged()) { + annotateSpan(); + } + else if (log.isTraceEnabled()) { + log.trace("State has not changed, will not annotate the span"); + } + return this; + } + + private void annotateSpan() { + String name = this.current.getState().name(); + if (log.isDebugEnabled()) { + log.debug("Will annotate its state with [" + name + "]"); + } + this.span.event(name); + } + + private boolean statusChanged() { + if (this.previous == null && this.current != null) { + if (log.isDebugEnabled()) { + log.debug("Previous is null, current is not null"); + } + return true; + } + else if (this.current == null) { + throw new IllegalStateException("Current state can't be null"); + } + DeploymentState currentState = this.current.getState(); + DeploymentState previousState = this.previous.getState(); + return currentState != previousState; + } + + private boolean isFinished() { + boolean finished = this.current.getState() == DeploymentState.deployed + || this.current.getState() == DeploymentState.undeployed + || this.current.getState() == DeploymentState.failed + || this.current.getState() == DeploymentState.error + || this.current.getState() == DeploymentState.unknown; + if (log.isTraceEnabled()) { + log.trace("Status is finished [" + finished + "]"); + } + return finished; + } + + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerBeanPostProcessor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerBeanPostProcessor.java new file mode 100644 index 000000000..616ba68df --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerBeanPostProcessor.java @@ -0,0 +1,55 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.deployer; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.core.env.Environment; + +/** + * {@link BeanPostProcessor} to wrap a {@link AppDeployer} instance into its trace + * representation. + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +public class TraceAppDeployerBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + + private final Environment environment; + + public TraceAppDeployerBeanPostProcessor(BeanFactory beanFactory, Environment environment) { + this.beanFactory = beanFactory; + this.environment = environment; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) { + if (bean instanceof AppDeployer && !(bean instanceof TraceAppDeployer)) { + return new TraceAppDeployer((AppDeployer) bean, this.beanFactory, this.environment); + } + return bean; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java index dd759fbbd..135a4be6d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorHooksHelper.java @@ -60,13 +60,13 @@ import org.springframework.util.Assert; * .scan((l, r) -> l + r) // (-) * .doOnNext(it -> { // (-) * //log - * }) + * }) * .doFirst(() -> { // (-) * //log - * }) + * }) * .doFinally(signalType -> { // (-) * //log - * }) + * }) * .subscribeOn(Schedulers.parallel()) //(+) * .subscribe();//(*) * (*) - captures tracing context if it differs from what was captured before at subscription and propagates it. @@ -84,7 +84,7 @@ import org.springframework.util.Assert; * .map(it -> ...) // (+) is SYNC but should add hook as previous Processor/operator does not use hooks * .doOnNext(it -> { // (-) is SYNC no need to wrap * //log - * }) + * }) * .subscribe(); *} */ @@ -93,6 +93,7 @@ final class ReactorHooksHelper { // need a way to determine SYNC sources to not add redundant scope passing decorator // most of reactor-core SYNC sources are marked with SourceProducer interface static final Class sourceProducerClass; + static { Class c; try { diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java index 82dd63265..dabadd1a3 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java @@ -17,8 +17,10 @@ package org.springframework.cloud.sleuth.instrument.reactor; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -28,16 +30,20 @@ import org.reactivestreams.Subscription; import reactor.core.CoreSubscriber; import reactor.core.Fuseable; import reactor.core.Scannable; +import reactor.core.publisher.Flux; import reactor.core.publisher.Hooks; +import reactor.core.publisher.Mono; import reactor.core.publisher.Operators; -import reactor.util.annotation.Nullable; import reactor.util.context.Context; import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceContext; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.internal.LazyBean; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; /** * Reactive Span pointcuts factories. @@ -314,6 +320,132 @@ public abstract class ReactorSleuth { }; } + /** + * Wraps the given Mono in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Mono} to be wrapped in tracing + * @param - type returned by the Mono + * @param spanCustomizer - customizer for the child span + * @return traced Mono + */ + public static Mono tracedMono(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier, + @NonNull Consumer spanCustomizer) { + return Mono.deferContextual(contextView -> { + Span span = contextView.get(Span.class); + spanCustomizer.accept(span); + Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); + return supplier.get().doOnError(span::error).doFinally(signalType -> { + span.end(); + scope.close(); + }); + }).contextWrite(context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + } + + /** + * Wraps the given Mono in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Mono} to be wrapped in tracing + * @param - type returned by the Mono + * @return traced Mono + */ + public static Mono tracedMono(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier) { + return tracedMono(tracer, currentTraceContext, childSpanName, supplier, span -> { + }); + } + + /** + * Wraps the given Flux in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Flux} to be wrapped in tracing + * @param - type returned by the Flux + * @param spanCustomizer - customizer for the child span + * @return traced Flux + */ + public static Flux tracedFlux(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier, + @NonNull Consumer spanCustomizer) { + return Flux.deferContextual(contextView -> { + Span span = contextView.get(Span.class); + spanCustomizer.accept(span); + Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); + return supplier.get().doOnError(span::error).doFinally(signalType -> { + span.end(); + scope.close(); + }); + }).contextWrite(context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + } + + /** + * Wraps the given Flux in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param currentTraceContext - CurrentTraceContext bean + * @param childSpanName - name of the created child span + * @param supplier - supplier of a {@link Flux} to be wrapped in tracing + * @param - type returned by the Flux + * @return traced Flux + */ + public static Flux tracedFlux(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, + @NonNull String childSpanName, @NonNull Supplier> supplier) { + return tracedFlux(tracer, currentTraceContext, childSpanName, supplier, span -> { + }); + } + + private static Span spanFromContext(Tracer tracer, CurrentTraceContext currentTraceContext, + reactor.util.context.Context context, String childSpanName) { + TraceContext traceContext = context.getOrDefault(TraceContext.class, null); + Span span = null; + if (traceContext == null) { + span = context.getOrDefault(Span.class, null); + } + if (traceContext == null && span == null) { + span = tracer.nextSpan(); + if (log.isDebugEnabled()) { + log.debug("There was no previous span in reactor context, created a new one [" + span + "]"); + } + } + else if (traceContext != null) { + // there was a previous span - we create a child one + try (CurrentTraceContext.Scope scope = currentTraceContext.maybeScope(traceContext)) { + if (log.isDebugEnabled()) { + log.debug("Found a trace context in reactor context [" + traceContext + "]"); + } + span = tracer.nextSpan(); + if (log.isDebugEnabled()) { + log.debug("Created a child span [" + span + "]"); + } + } + } + else { + if (log.isDebugEnabled()) { + log.debug("Found a span in reactor context [" + span + "]"); + } + span = tracer.nextSpan(span); + if (log.isDebugEnabled()) { + log.debug("Created a child span [" + span + "]"); + } + } + return span.name(childSpanName).start(); + } + + private static Context enhanceContext(Tracer tracer, CurrentTraceContext currentTraceContext, + reactor.util.context.Context context, String childSpanName) { + Span span = spanFromContext(tracer, currentTraceContext, context, childSpanName); + return context.put(Span.class, span).put(TraceContext.class, span.context()).put(Tracer.SpanInScope.class, + tracer.withSpan(span)); + } + } class SleuthContextOperator implements Subscription, CoreSubscriber, Scannable { diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpCurrentTraceContext.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpCurrentTraceContext.java new file mode 100644 index 000000000..394c3eefb --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpCurrentTraceContext.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.deployer; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; + +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class NoOpCurrentTraceContext implements CurrentTraceContext { + + @Override + public TraceContext context() { + return null; + } + + @Override + public Scope newScope(TraceContext context) { + return () -> { + }; + } + + @Override + public Scope maybeScope(TraceContext context) { + return () -> { + }; + } + + @Override + public Callable wrap(Callable task) { + return task; + } + + @Override + public Runnable wrap(Runnable task) { + return task; + } + + @Override + public Executor wrap(Executor delegate) { + return delegate; + } + + @Override + public ExecutorService wrap(ExecutorService delegate) { + return delegate; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpSpanInScope.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpSpanInScope.java new file mode 100644 index 000000000..d2339918a --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpSpanInScope.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.deployer; + +import org.springframework.cloud.sleuth.Tracer; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class NoOpSpanInScope implements Tracer.SpanInScope { + + @Override + public void close() { + + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpTraceContext.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpTraceContext.java new file mode 100644 index 000000000..057b4b41f --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/NoOpTraceContext.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.deployer; + +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class NoOpTraceContext implements TraceContext { + + @Override + public String traceId() { + return ""; + } + + @Override + public String parentId() { + return ""; + } + + @Override + public String spanId() { + return ""; + } + + @Override + public Boolean sampled() { + return false; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleSpan.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleSpan.java new file mode 100644 index 000000000..86cdfd169 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleSpan.java @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.deployer; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class SimpleSpan implements Span { + + Map tags = new HashMap<>(); + + boolean started; + + boolean ended; + + @Override + public boolean isNoop() { + return true; + } + + @Override + public TraceContext context() { + return new NoOpTraceContext(); + } + + @Override + public Span start() { + this.started = true; + return this; + } + + @Override + public Span name(String name) { + return this; + } + + @Override + public Span event(String value) { + return this; + } + + @Override + public Span tag(String key, String value) { + this.tags.put(key, value); + return this; + } + + @Override + public Span error(Throwable throwable) { + return this; + } + + @Override + public void end() { + this.ended = true; + } + + @Override + public void abandon() { + + } + + @Override + public Span remoteServiceName(String remoteServiceName) { + return this; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java new file mode 100644 index 000000000..295d2288d --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java @@ -0,0 +1,113 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.deployer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.assertj.core.api.BDDAssertions; + +import org.springframework.cloud.sleuth.BaggageInScope; +import org.springframework.cloud.sleuth.ScopedSpan; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanCustomizer; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.0.0 + */ +class SimpleTracer implements Tracer { + + List spans = new ArrayList<>(); + + @Override + public Span nextSpan(Span parent) { + return new SimpleSpan(); + } + + SimpleSpan getOnlySpan() { + BDDAssertions.then(this.spans).hasSize(1); + SimpleSpan span = this.spans.get(0); + BDDAssertions.then(span.started).as("Span must be started").isTrue(); + BDDAssertions.then(span.ended).as("Span must be finished").isTrue(); + return span; + } + + @Override + public SpanInScope withSpan(Span span) { + return new NoOpSpanInScope(); + } + + @Override + public SpanCustomizer currentSpanCustomizer() { + return null; + } + + @Override + public Span currentSpan() { + return new SimpleSpan(); + } + + @Override + public Span nextSpan() { + final SimpleSpan span = new SimpleSpan(); + this.spans.add(span); + return span; + } + + @Override + public ScopedSpan startScopedSpan(String name) { + return null; + } + + @Override + public Span.Builder spanBuilder() { + return null; + } + + @Override + public Map getAllBaggage() { + return new HashMap<>(); + } + + @Override + public BaggageInScope getBaggage(String name) { + return null; + } + + @Override + public BaggageInScope getBaggage(TraceContext traceContext, String name) { + return null; + } + + @Override + public BaggageInScope createBaggage(String name) { + return null; + } + + @Override + public BaggageInScope createBaggage(String name, String value) { + return null; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerTests.java new file mode 100644 index 000000000..c6b50b62e --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployerTests.java @@ -0,0 +1,144 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.deployer; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.support.StaticListableBeanFactory; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.deployer.spi.app.AppScaleRequest; +import org.springframework.cloud.deployer.spi.app.AppStatus; +import org.springframework.cloud.deployer.spi.core.AppDefinition; +import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; +import org.springframework.core.env.Environment; +import org.springframework.core.io.PathResource; +import org.springframework.mock.env.MockEnvironment; + +class TraceAppDeployerTests { + + SimpleTracer simpleTracer = new SimpleTracer(); + + AppDeployer delegate = BDDMockito.mock(AppDeployer.class); + + TraceAppDeployer traceAppDeployer = new TraceAppDeployer(this.delegate, beanFactory(), environment()); + + @Test + void should_trace_deploy() { + BDDMockito.given(this.delegate.statusReactive(BDDMockito.any())) + .willReturn(Mono.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.deploy(deploymentRequest()); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().deploy(BDDMockito.any()); + } + + @Test + void should_trace_undeploy() { + BDDMockito.given(this.delegate.statusReactive(BDDMockito.any())) + .willReturn(Mono.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.undeploy("asd"); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().undeploy(BDDMockito.any()); + } + + @Test + void should_trace_status() { + this.traceAppDeployer.status("asd"); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().status(BDDMockito.any()); + } + + @Test + void should_trace_status_reactive() { + BDDMockito.given(this.delegate.statusReactive(BDDMockito.any())) + .willReturn(Mono.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.statusReactive("asd").block(); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().statusReactive(BDDMockito.any()); + } + + @Test + void should_trace_statuses_reactive() { + BDDMockito.given(this.delegate.statusesReactive(BDDMockito.any())) + .willReturn(Flux.just(AppStatus.of("asd").build())); + + this.traceAppDeployer.statusesReactive("asd").blockFirst(); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().statusesReactive(BDDMockito.any()); + } + + @Test + void should_trace_log() { + this.traceAppDeployer.getLog("id"); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().getLog(BDDMockito.any()); + } + + @Test + void should_trace_scale() { + this.traceAppDeployer.scale(new AppScaleRequest("asd", 2)); + + BDDAssertions.then(this.simpleTracer.getOnlySpan().tags).isNotEmpty(); + BDDMockito.then(this.delegate).should().scale(BDDMockito.any()); + } + + private AppDeploymentRequest deploymentRequest() { + return new AppDeploymentRequest(new AppDefinition("foo", new HashMap<>()), new PathResource("/"), + deploymentProps(), commandLineArgs()); + } + + private List commandLineArgs() { + return Arrays.asList("foo=bar1", "baz=bar2"); + } + + private Map deploymentProps() { + Map map = new HashMap<>(); + map.put("deployment1", "prop1"); + map.put("deployment2", "prop2"); + return map; + } + + private BeanFactory beanFactory() { + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("tracer", this.simpleTracer); + beanFactory.addBean("currentTraceContext", new NoOpCurrentTraceContext()); + return beanFactory; + } + + private Environment environment() { + return new MockEnvironment(); + } + +} From 793c1b675283e7f246859d4d6586c45426e0d505 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 26 Apr 2021 15:29:18 +0200 Subject: [PATCH 74/78] Polished the docs --- docs/src/main/asciidoc/_configprops.adoc | 6 +- docs/src/main/asciidoc/integrations.adoc | 1162 +++++++++-------- ...itional-spring-configuration-metadata.json | 2 +- 3 files changed, 591 insertions(+), 579 deletions(-) diff --git a/docs/src/main/asciidoc/_configprops.adoc b/docs/src/main/asciidoc/_configprops.adoc index 48122995d..e2c13e903 100644 --- a/docs/src/main/asciidoc/_configprops.adoc +++ b/docs/src/main/asciidoc/_configprops.adoc @@ -10,13 +10,16 @@ |spring.sleuth.baggage.remote-fields | | List of fields that are referenced the same in-process as it is on the wire. For example, the field "x-vcap-request-id" would be set as-is including the prefix. |spring.sleuth.baggage.tag-fields | | |spring.sleuth.circuitbreaker.enabled | `true` | Enable Spring Cloud CircuitBreaker instrumentation. +|spring.sleuth.config.server.enabled | `true` | Enable Spring Cloud Config Server instrumentation. +|spring.sleuth.deployer.enabled | `true` | Enable Spring Cloud Deployer instrumentation. +|spring.sleuth.deployer.status-poll-delay | `1000` | Default poll delay to retrieve the deployed application status. |spring.sleuth.enabled | `true` | |spring.sleuth.feign.enabled | `true` | Enable span information propagation when using Feign. |spring.sleuth.feign.processor.enabled | `true` | Enable post processor that wraps Feign Context in its tracing representations. |spring.sleuth.function.enabled | `true` | Enable instrumenting of Spring Cloud Function and Spring Cloud Function based projects (e.g. Spring Cloud Stream). |spring.sleuth.grpc.enabled | `true` | Enable span information propagation when using GRPC. |spring.sleuth.http.enabled | `true` | Enables HTTP support. -|spring.sleuth.integration.enabled | `true` | Enable Spring Integration sleuth instrumentation. +|spring.sleuth.integration.enabled | `true` | Enable Spring Integration instrumentation. |spring.sleuth.integration.patterns | `[!hystrixStreamOutput*, *, !channel*]` | An array of patterns against which channel names will be matched. @see org.springframework.integration.config.GlobalChannelInterceptor#patterns() Defaults to any channel name not matching the Hystrix Stream and functional Stream channel names. |spring.sleuth.integration.websockets.enabled | `true` | Enable tracing for WebSockets. |spring.sleuth.messaging.enabled | `false` | Should messaging be turned on. @@ -49,6 +52,7 @@ |spring.sleuth.span-filter.enabled | `false` | Will turn on the default Sleuth handler mechanism. Might ignore exporting of certain spans; |spring.sleuth.span-filter.span-name-patterns-to-skip | `^catalogWatchTaskScheduler$` | List of span names to ignore. They will not be sent to external systems. |spring.sleuth.supports-join | `true` | True means the tracing system supports sharing a span ID between a client and server. +|spring.sleuth.task.enabled | `true` | Enable Spring Cloud Task instrumentation. |spring.sleuth.trace-id128 | `false` | When true, generate 128-bit trace IDs instead of 64-bit ones. |spring.sleuth.tracer.mode | | Set which tracer implementation should be picked. |spring.sleuth.web.additional-skip-pattern | | Additional pattern for URLs that should be skipped in tracing. This will be appended to the {@link SleuthWebProperties#skipPattern}. diff --git a/docs/src/main/asciidoc/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc index a05b772c4..9d8530d57 100644 --- a/docs/src/main/asciidoc/integrations.adoc +++ b/docs/src/main/asciidoc/integrations.adoc @@ -1,577 +1,585 @@ -[[sleuth-integration]] -= Spring Cloud Sleuth customization - -include::_attributes.adoc[] - -In this section, we describe how to customize various parts of Spring Cloud Sleuth. - -[[sleuth-async-integration]] -== Asynchronous Communication - -In this section, we describe how to customize asynchronous communication with Spring Cloud Sleuth. - -[[sleuth-async-annotation-integration]] -=== `@Async` Annotated methods - -This feature is available for all tracer implementations. - -In Spring Cloud Sleuth, we instrument async-related components so that the tracing information is passed between threads. -You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. - -If you annotate your method with `@Async`, we automatically modify the existing Span as follows: - -* If the method is annotated with `@SpanName`, the value of the annotation is the Span's name. -* If the method is not annotated with `@SpanName`, the Span name is the annotated method name. -* The span is tagged with the method's class name and method name. - -Since we're modifying the existing span, if you want to maintain its original name (e.g. a span created by receiving an HTTP request) -you should wrap your `@Async` annotated method with a `@NewSpan` annotation or create a new span manually. - -[[sleuth-async-scheduled-integration]] -=== `@Scheduled` Annotated Methods - -This feature is available for all tracer implementations. - -In Spring Cloud Sleuth, we instrument scheduled method execution so that the tracing information is passed between threads. -You can disable this behavior by setting the value of `spring.sleuth.scheduled.enabled` to `false`. - -If you annotate your method with `@Scheduled`, we automatically create a new span with the following characteristics: - -* The span name is the annotated method name. -* The span is tagged with the method's class name and method name. - -If you want to skip span creation for some `@Scheduled` annotated classes, you can set the `spring.sleuth.scheduled.skipPattern` with a regular expression that matches the fully qualified name of the `@Scheduled` annotated class. - -[[sleuth-async-executor-service-integration]] -=== Executor, ExecutorService, and ScheduledExecutorService - -This feature is available for all tracer implementations. - -We provide `LazyTraceExecutor`, `TraceableExecutorService`, and `TraceableScheduledExecutorService`. -Those implementations create spans each time a new task is submitted, invoked, or scheduled. - -The following example shows how to pass tracing information with `TraceableExecutorService` when working with `CompletableFuture`: - -[source,java,indent=0] ----- - -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java[tags=completablefuture,indent=0] ----- - -IMPORTANT: Sleuth does not work with `parallelStream()` out of the box. -If you want to have the tracing information propagated through the stream, you have to use the approach with `supplyAsync(...)`, as shown earlier. - -If there are beans that implement the `Executor` interface that you would like to exclude from span creation, you can use the `spring.sleuth.async.ignored-beans` -property where you can provide a list of bean names. - -You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. - -[[sleuth-async-executor-integration]] -==== Customization of Executors - -Sometimes, you need to set up a custom instance of the `AsyncExecutor`. -The following example shows how to set up such a custom `Executor`: - -[source,java,indent=0] ----- -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_executor,indent=0] ----- - -TIP: To ensure that your configuration gets post processed, remember to add the `@Role(BeanDefinition.ROLE_INFRASTRUCTURE)` on your -`@Configuration` class - -[[sleuth-http-client-integration]] -== HTTP Client Integration - -Features from this section can be disabled by setting the `spring.sleuth.web.client.enabled` property with value equal to `false`. - -[[sleuth-http-client-rest-template-integration]] -=== Synchronous Rest Template - -This feature is available for all tracer implementations. - -We inject a `RestTemplate` interceptor to ensure that all the tracing information is passed to the requests. -Each time a call is made, a new Span is created. -It gets closed upon receiving the response. -To block the synchronous `RestTemplate` features, set `spring.sleuth.web.client.enabled` to `false`. - -IMPORTANT: You have to register `RestTemplate` as a bean so that the interceptors get injected. -If you create a `RestTemplate` instance with a `new` keyword, the instrumentation does NOT work. - -[[sleuth-http-client-async-rest-template-integration]] -=== Asynchronous Rest Template - -This feature is available for all tracer implementations. - -IMPORTANT: Starting with Sleuth `2.0.0`, we no longer register a bean of `AsyncRestTemplate` type. -It is up to you to create such a bean. -Then we instrument it. - -To block the `AsyncRestTemplate` features, set `spring.sleuth.web.async.client.enabled` to `false`. -To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper`, set `spring.sleuth.web.async.client.factory.enabled` -to `false`. -If you do not want to create `AsyncRestClient` at all, set `spring.sleuth.web.async.client.template.enabled` to `false`. - -[[sleuth-http-client-multiple-async-rest-template-integration]] -==== Multiple Asynchronous Rest Templates - -Sometimes you need to use multiple implementations of the Asynchronous Rest Template. -In the following snippet, you can see an example of how to set up such a custom `AsyncRestTemplate`: - -[source,java,indent=0] ----- -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_async_rest_template,indent=0] ----- - -[[sleuth-http-client-webclient-integration]] -==== `WebClient` - -This feature is available for all tracer implementations. - -We inject a `ExchangeFilterFunction` implementation that creates a span and, through on-success and on-error callbacks, takes care of closing client-side spans. - -To block this feature, set `spring.sleuth.web.client.enabled` to `false`. - -IMPORTANT: You have to register `WebClient` as a bean so that the tracing instrumentation gets applied. -If you create a `WebClient` instance with a `new` keyword, the instrumentation does NOT work. - -[[sleuth-http-client-traverson-integration]] -==== Traverson - -This feature is available for all tracer implementations. - -If you use the https://docs.spring.io/spring-hateoas/docs/current/reference/html/#client.traverson[Traverson] library, you can inject a `RestTemplate` as a bean into your Traverson object. -Since `RestTemplate` is already intercepted, you get full support for tracing in your client. -The following pseudo code shows how to do that: - -[source,java,indent=0] ----- -@Autowired RestTemplate restTemplate; - -Traverson traverson = new Traverson(URI.create("https://some/address"), - MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate); -// use Traverson ----- - -[[sleuth-http-client-apache-integration]] -==== Apache `HttpClientBuilder` and `HttpAsyncClientBuilder` - -This feature is available for Brave tracer implementation. - -We instrument the `HttpClientBuilder` and `HttpAsyncClientBuilder` so that tracing context gets injected to the sent requests. - -To block these features, set `spring.sleuth.web.client.enabled` to `false`. - -[[sleuth-http-client-netty-integration]] -==== Netty `HttpClient` - -This feature is available for all tracer implementations. - -We instrument the Netty's `HttpClient`. - -To block this feature, set `spring.sleuth.web.client.enabled` to `false`. - -IMPORTANT: You have to register `HttpClient` as a bean so that the instrumentation happens. -If you create a `HttpClient` instance with a `new` keyword, the instrumentation does NOT work. - -[[sleuth-http-client-userinfo-integration]] -==== `UserInfoRestTemplateCustomizer` - -This feature is available for all tracer implementations. - -We instrument the Spring Security's `UserInfoRestTemplateCustomizer`. - -To block this feature, set `spring.sleuth.web.client.enabled` to `false`. - -[[sleuth-http-server-integration]] -== HTTP Server Integration - -Features from this section can be disabled by setting the `spring.sleuth.web.enabled` property with value equal to `false`. - -[[sleuth-http-server-http-filter-integration]] -=== HTTP Filter - -This feature is available for all tracer implementations. - -Through the `TracingFilter`, all sampled incoming requests result in creation of a Span. -You can configure which URIs you would like to skip by setting the `spring.sleuth.web.skipPattern` property. -If you have `ManagementServerProperties` on classpath, its value of `contextPath` gets appended to the provided skip pattern. -If you want to reuse the Sleuth's default skip patterns and just append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. - -By default, all the spring boot actuator endpoints are automatically added to the skip pattern. -If you want to disable this behaviour set `spring.sleuth.web.ignore-auto-configured-skip-patterns` -to `true`. - -To change the order of tracing filter registration, please set the -`spring.sleuth.web.filter-order` property. - -To disable the filter that logs uncaught exceptions you can disable the -`spring.sleuth.web.exception-throwing-filter-enabled` property. - -[[sleuth-http-server-handler-interceptor-integration]] -=== HandlerInterceptor - -This feature is available for all tracer implementations. - -Since we want the span names to be precise, we use a `TraceHandlerInterceptor` that either wraps an existing `HandlerInterceptor` or is added directly to the list of existing `HandlerInterceptors`. -The `TraceHandlerInterceptor` adds a special request attribute to the given `HttpServletRequest`. -If the the `TracingFilter` does not see this attribute, it creates a "`fallback`" span, which is an additional span created on the server side so that the trace is presented properly in the UI. -If that happens, there is probably missing instrumentation. -In that case, please file an issue in Spring Cloud Sleuth. - -[[sleuth-http-server-async-integration]] -=== Async Servlet support - -This feature is available for all tracer implementations. - -If your controller returns a `Callable` or a `WebAsyncTask`, Spring Cloud Sleuth continues the existing span instead of creating a new one. - -[[sleuth-http-server-webflux-integration]] -=== WebFlux support - -This feature is available for all tracer implementations. - -Through `TraceWebFilter`, all sampled incoming requests result in creation of a Span. -That Span's name is `http:` + the path to which the request was sent. -For example, if the request was sent to `/this/that`, the name is `http:/this/that`. -You can configure which URIs you would like to skip by using the `spring.sleuth.web.skipPattern` property. -If you have `ManagementServerProperties` on the classpath, its value of `contextPath` gets appended to the provided skip pattern. -If you want to reuse Sleuth's default skip patterns and append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. - -In order to achieve best results in terms of performance and context propagation we suggest that you switch the `spring.sleuth.reactor.instrumentation-type` to `MANUAL`. -In order to execute code with the span in scope you can call `WebFluxSleuthOperators.withSpanInScope`. -Example: - -[source,java,indent=0] ------ -include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] ------ - -To change the order of tracing filter registration, please set the -`spring.sleuth.web.filter-order` property. - -[[sleuth-messaging-integration]] -== Messaging - -Features from this section can be disabled by setting the `spring.sleuth.messaging.enabled` property with value equal to `false`. - -[[sleuth-messaging-spring-integration-integration]] -=== Spring Integration - -This feature is available for all tracer implementations. - -Spring Cloud Sleuth integrates with https://projects.spring.io/spring-integration/[Spring Integration]. -It creates spans for publish and subscribe events. -To disable Spring Integration instrumentation, set `spring.sleuth.integration.enabled` to `false`. - -You can provide the `spring.sleuth.integration.patterns` pattern to explicitly provide the names of channels that you want to include for tracing. -By default, all channels but `hystrixStreamOutput` channel are included. - -IMPORTANT: When using the `Executor` to build a Spring Integration `IntegrationFlow`, you must use the untraced version of the `Executor`. -Decorating the Spring Integration Executor Channel with `TraceableExecutorService` causes the spans to be improperly closed. - -If you want to customize the way tracing context is read from and written to message headers, it's enough for you to register beans of types: - -* `Propagator.Setter` - for writing headers to the message -* `Propagator.Getter` - for reading headers from the message - -[[sleuth-messaging-spring-integration-customization]] -==== Spring Integration Customization - -==== Customizing messaging spans - -In order to change the default span names and tags, just register a bean of type `MessageSpanCustomizer`. You can also -override the existing `DefaultMessageSpanCustomizer` to extend the existing behaviour. - -[source,java] ----- -@Component -include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java[tags=message_span_customizer,indent=2] ----- - -[[sleuth-messaging-spring-cloud-function-integration]] -=== Spring Cloud Function and Spring Cloud Stream - -This feature is available for all tracer implementations. - -Spring Cloud Sleuth can instrument Spring Cloud Function. -The way to achieve it is to provide a `Function` or `Consumer` or `Supplier` that takes in a `Message` as a parameter e.g. `Function, Message>`. -If the type is not `Message` then instrumentation will not take place. -Out of the box instrumentation will not take place when dealing with Reactor based streams - e.g. `Function>, Flux>>`. - -Since Spring Cloud Stream reuses Spring Cloud Function, you'll get the instrumentation out of the box. - -You can disable this behavior by setting the value of `spring.sleuth.function.enabled` to `false`. - -In order to work with reactive Stream functions you can leverage the `MessagingSleuthOperators` utility class that allows you to manipulate the input and output messages in order to continue the tracing context and to execute custom code within the tracing context. - -[source,java,indent=0] ------ -include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java[tags=simple_reactive,indent=0] ------ - -[[sleuth-messaging-spring-rabbitmq-integration]] -=== Spring RabbitMq - -This feature is available for Brave tracer implementation. - -We instrument the `RabbitTemplate` so that tracing headers get injected into the message. - -To block this feature, set `spring.sleuth.messaging.rabbit.enabled` to `false`. - -[[sleuth-messaging-spring-kafka-integration]] -=== Spring Kafka - -This feature is available for Brave tracer implementation. - -We instrument the Spring Kafka's `ProducerFactory` and `ConsumerFactory` -so that tracing headers get injected into the created Spring Kafka's -`Producer` and `Consumer`. - -To block this feature, set `spring.sleuth.messaging.kafka.enabled` to `false`. - -[[sleuth-messaging-spring-kafka-streams-integration]] -=== Spring Kafka Streams - -This feature is available for Brave tracer implementation. - -We instrument the `KafkaStreams` `KafkaClientSupplier` so that tracing headers get injected into the `Producer` and `Consumer`s. A `KafkaStreamsTracing` bean allows for further instrumentation through additional `TransformerSupplier` and -`ProcessorSupplier` methods. - -To block this feature, set `spring.sleuth.messaging.kafka.streams.enabled` to `false`. - -[[sleuth-messaging-spring-jms-integration]] -=== Spring JMS - -This feature is available for Brave tracer implementation. - -We instrument the `JmsTemplate` so that tracing headers get injected into the message. -We also support `@JmsListener` annotated methods on the consumer side. - -To block this feature, set `spring.sleuth.messaging.jms.enabled` to `false`. - -IMPORTANT: We don't support baggage propagation for JMS - -[[sleuth-openfeign-integration]] -== OpenFeign - -This feature is available for all tracer implementations. - -By default, Spring Cloud Sleuth provides integration with Feign through `TraceFeignClientAutoConfiguration`. -You can disable it entirely by setting `spring.sleuth.feign.enabled` to `false`. -If you do so, no Feign-related instrumentation take place. - -Part of Feign instrumentation is done through a `FeignBeanPostProcessor`. -You can disable it by setting `spring.sleuth.feign.processor.enabled` to `false`. -If you set it to `false`, Spring Cloud Sleuth does not instrument any of your custom Feign components. -However, all the default instrumentation is still there. - -[[sleuth-opentracing-integration]] -== OpenTracing - -This feature is available for all tracer implementations. - -Spring Cloud Sleuth is compatible with https://opentracing.io/[OpenTracing]. -If you have OpenTracing on the classpath, we automatically register the OpenTracing `Tracer` bean. -If you wish to disable this, set `spring.sleuth.opentracing.enabled` to `false` - -[[sleuth-quartz-integration]] -== Quartz - -This feature is available for all tracer implementations. - -We instrument quartz jobs by adding Job/Trigger listeners to the Quartz Scheduler. - -To turn off this feature, set the `spring.sleuth.quartz.enabled` property to `false`. - -[[sleuth-reactor-integration]] -== Reactor - -This feature is available for all tracer implementations. - -We have the following modes of instrumenting reactor based applications that can be set via `spring.sleuth.reactor.instrumentation-type` property: - -* `DECORATE_QUEUES` - With the new Reactor https://github.com/reactor/reactor-core/pull/2566[queue wrapping mechanism] (Reactor 3.4.3) we're instrumenting the way threads are switched by Reactor. This should lead to feature parity with `ON_EACH` with low performance impact. -* `DECORATE_ON_EACH` - wraps every Reactor operator in a trace representation. -Passes the tracing context in most cases. -This mode might lead to drastic performance degradation. -* `DECORATE_ON_LAST` - wraps last Reactor operator in a trace representation. -Passes the tracing context in some cases thus accessing MDC context might not work. -This mode might lead to medium performance degradation. -* `MANUAL` - wraps every Reactor in the least invasive way without passing of tracing context. -It's up to the user to do it. - -Current default is `ON_EACH` for backward compatibility reasons, however we encourage the users to migrate to the `MANUAL` instrumentation and profit from `WebFluxSleuthOperators` and `MessagingSleuthOperators`. -The performance improvement can be substantial. -Example: - -[source,java,indent=0] ------ -include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] ------ - -[[sleuth-redis-integration]] -== Redis - -This feature is available for Brave tracer implementation. - -We set `tracing` property to Lettuce `ClientResources` instance to enable Brave tracing built in Lettuce . -To disable Redis support, set the `spring.sleuth.redis.enabled` property to `false`. - -[[sleuth-runnablecallable-integration]] -== Runnable and Callable - -This feature is available for all tracer implementations. - -If you wrap your logic in `Runnable` or `Callable`, you can wrap those classes in their Sleuth representative, as shown in the following example for `Runnable`: - -[source,java,indent=0] ----- -include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_runnable,indent=0] ----- - -The following example shows how to do so for `Callable`: - -[source,java,indent=0] ----- -include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_callable,indent=0] ----- - -That way, you ensure that a new span is created and closed for each execution. - -[[sleuth-rpc-integration]] -== RPC - -This feature is available for Brave tracer implementation. - -Sleuth automatically configures the `RpcTracing` bean which serves as a foundation for RPC instrumentation such as gRPC or Dubbo. - -If a customization of client / server sampling of the RPC traces is required, just register a bean of type `brave.sampler.SamplerFunction` and name the bean `sleuthRpcClientSampler` for client sampler and -`sleuthRpcServerSampler` for server sampler. - -For your convenience the `@RpcClientSampler` and `@RpcServerSampler` -annotations can be used to inject the proper beans or to reference the bean names via their static String `NAME` fields. - -Ex. -Here's a sampler that traces 100 "GetUserToken" server requests per second. -This doesn't start new traces for requests to the health check service. -Other requests will use the global sampling configuration. - -[source,java,indent=0] ----- -@Configuration(proxyBeanMethods = false) - class Config { -include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java[tags=custom_rpc_server_sampler,indent=2] -} ----- - -For more, see https://github.com/openzipkin/brave/tree/master/instrumentation/rpc#sampling-policy - -[[sleuth-rpc-dubbo-integration]] -=== Dubbo RPC support - -Via the integration with Brave, Spring Cloud Sleuth supports https://dubbo.apache.org/[Dubbo]. -It's enough to add the `brave-instrumentation-dubbo` dependency: - -[source,xml,indent=0] ----- - - io.zipkin.brave - brave-instrumentation-dubbo - ----- - -You need to also set a `dubbo.properties` file with the following contents: - -```properties -dubbo.provider.filter=tracing -dubbo.consumer.filter=tracing -``` - -You can read more about Brave - Dubbo integration https://github.com/openzipkin/brave/tree/master/instrumentation/dubbo-rpc[here]. -An example of Spring Cloud Sleuth and Dubbo can be found https://github.com/openzipkin/sleuth-webmvc-example/compare/add-dubbo-tracing[here]. - -[[sleuth-rpc-grpc-integration]] -=== gRPC - -Spring Cloud Sleuth provides instrumentation for https://grpc.io/[gRPC] via the Brave tracer. -You can disable it entirely by setting `spring.sleuth.grpc.enabled` to `false`. - -[[sleuth-rpc-grpc-variant1-integration]] -==== Variant 1 - -[[sleuth-rpc-grpc-variant1-dependencies-integration]] -===== Dependencies - -IMPORTANT: The gRPC integration relies on two external libraries to instrument clients and servers and both of those libraries must be on the class path to enable the instrumentation. - -Maven: - -``` - - io.github.lognet - grpc-spring-boot-starter - - - io.zipkin.brave - brave-instrumentation-grpc - -``` - -Gradle: - -``` - compile("io.github.lognet:grpc-spring-boot-starter") - compile("io.zipkin.brave:brave-instrumentation-grpc") -``` - -[[sleuth-rpc-grpc-variant1-server-integration]] -===== Server Instrumentation - -Spring Cloud Sleuth leverages grpc-spring-boot-starter to register Brave's gRPC server interceptor with all services annotated with `@GRpcService`. - -[[sleuth-rpc-grpc-variant1-client-integration]] -===== Client Instrumentation - -gRPC clients leverage a `ManagedChannelBuilder` to construct a `ManagedChannel` used to communicate to the gRPC server. -The native `ManagedChannelBuilder` provides static methods as entry points for construction of `ManagedChannel` instances, however, this mechanism is outside the influence of the Spring application context. - -IMPORTANT: Spring Cloud Sleuth provides a `SpringAwareManagedChannelBuilder` that can be customized through the Spring application context and injected by gRPC clients. -*This builder must be used when creating `ManagedChannel` instances.* - -Sleuth creates a `TracingManagedChannelBuilderCustomizer` which inject Brave's client interceptor into the `SpringAwareManagedChannelBuilder`. - -[[sleuth-rpc-grpc-variant2-integration]] -==== Variant 2 - -https://github.com/yidongnan/grpc-spring-boot-starter[Grpc Spring Boot Starter] automatically detects the presence of Spring Cloud Sleuth and Brave's instrumentation for gRPC and registers the necessary client and/or server tooling. - -[[sleuth-rxjava-integration]] -== RxJava - -This feature is available for all tracer implementations. - -We registering a custom https://github.com/ReactiveX/RxJava/wiki/Plugins#rxjavaschedulershook[`RxJavaSchedulersHook`] that wraps all `Action0` instances in their Sleuth representative, which is called `TraceAction`. -The hook either starts or continues a span, depending on whether tracing was already going on before the Action was scheduled. -To disable the custom `RxJavaSchedulersHook`, set the `spring.sleuth.rxjava.schedulers.hook.enabled` to `false`. - -You can define a list of regular expressions for thread names for which you do not want spans to be created. -To do so, provide a comma-separated list of regular expressions in the `spring.sleuth.rxjava.schedulers.ignoredthreads` property. - -IMPORTANT: The suggested approach to reactive programming and Sleuth is to use the Reactor support. - -[[sleuth-circuitbreaker-integration]] -== Spring Cloud CircuitBreaker - -This feature is available for all tracer implementations. - -If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. We will also instrument the reactive implementation of the CircuitBreaker. -In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`. - -[[sleuth-config-server-integration]] -== Spring Cloud Config Server - -This feature is available for all tracer implementations. - -If you have Spring Cloud Config Server running on the classpath, we will wrap the `EnvironmentRepository` in a span. -In order to disable this instrumentation set `spring.sleuth.config.server.enabled` to `false`. \ No newline at end of file +[[sleuth-integration]] += Spring Cloud Sleuth customization + +include::_attributes.adoc[] + +In this section, we describe how to customize various parts of Spring Cloud Sleuth. + +[[sleuth-async-integration]] +== Asynchronous Communication + +In this section, we describe how to customize asynchronous communication with Spring Cloud Sleuth. + +[[sleuth-async-annotation-integration]] +=== `@Async` Annotated methods + +This feature is available for all tracer implementations. + +In Spring Cloud Sleuth, we instrument async-related components so that the tracing information is passed between threads. +You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. + +If you annotate your method with `@Async`, we automatically modify the existing Span as follows: + +* If the method is annotated with `@SpanName`, the value of the annotation is the Span's name. +* If the method is not annotated with `@SpanName`, the Span name is the annotated method name. +* The span is tagged with the method's class name and method name. + +Since we're modifying the existing span, if you want to maintain its original name (e.g. a span created by receiving an HTTP request) +you should wrap your `@Async` annotated method with a `@NewSpan` annotation or create a new span manually. + +[[sleuth-async-scheduled-integration]] +=== `@Scheduled` Annotated Methods + +This feature is available for all tracer implementations. + +In Spring Cloud Sleuth, we instrument scheduled method execution so that the tracing information is passed between threads. +You can disable this behavior by setting the value of `spring.sleuth.scheduled.enabled` to `false`. + +If you annotate your method with `@Scheduled`, we automatically create a new span with the following characteristics: + +* The span name is the annotated method name. +* The span is tagged with the method's class name and method name. + +If you want to skip span creation for some `@Scheduled` annotated classes, you can set the `spring.sleuth.scheduled.skipPattern` with a regular expression that matches the fully qualified name of the `@Scheduled` annotated class. + +[[sleuth-async-executor-service-integration]] +=== Executor, ExecutorService, and ScheduledExecutorService + +This feature is available for all tracer implementations. + +We provide `LazyTraceExecutor`, `TraceableExecutorService`, and `TraceableScheduledExecutorService`. +Those implementations create spans each time a new task is submitted, invoked, or scheduled. + +The following example shows how to pass tracing information with `TraceableExecutorService` when working with `CompletableFuture`: + +[source,java,indent=0] +---- + +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java[tags=completablefuture,indent=0] +---- + +IMPORTANT: Sleuth does not work with `parallelStream()` out of the box. +If you want to have the tracing information propagated through the stream, you have to use the approach with `supplyAsync(...)`, as shown earlier. + +If there are beans that implement the `Executor` interface that you would like to exclude from span creation, you can use the `spring.sleuth.async.ignored-beans` +property where you can provide a list of bean names. + +You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`. + +[[sleuth-async-executor-integration]] +==== Customization of Executors + +Sometimes, you need to set up a custom instance of the `AsyncExecutor`. +The following example shows how to set up such a custom `Executor`: + +[source,java,indent=0] +---- +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_executor,indent=0] +---- + +TIP: To ensure that your configuration gets post processed, remember to add the `@Role(BeanDefinition.ROLE_INFRASTRUCTURE)` on your +`@Configuration` class + +[[sleuth-http-client-integration]] +== HTTP Client Integration + +Features from this section can be disabled by setting the `spring.sleuth.web.client.enabled` property with value equal to `false`. + +[[sleuth-http-client-rest-template-integration]] +=== Synchronous Rest Template + +This feature is available for all tracer implementations. + +We inject a `RestTemplate` interceptor to ensure that all the tracing information is passed to the requests. +Each time a call is made, a new Span is created. +It gets closed upon receiving the response. +To block the synchronous `RestTemplate` features, set `spring.sleuth.web.client.enabled` to `false`. + +IMPORTANT: You have to register `RestTemplate` as a bean so that the interceptors get injected. +If you create a `RestTemplate` instance with a `new` keyword, the instrumentation does NOT work. + +[[sleuth-http-client-async-rest-template-integration]] +=== Asynchronous Rest Template + +This feature is available for all tracer implementations. + +IMPORTANT: Starting with Sleuth `2.0.0`, we no longer register a bean of `AsyncRestTemplate` type. +It is up to you to create such a bean. +Then we instrument it. + +To block the `AsyncRestTemplate` features, set `spring.sleuth.web.async.client.enabled` to `false`. +To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper`, set `spring.sleuth.web.async.client.factory.enabled` +to `false`. +If you do not want to create `AsyncRestClient` at all, set `spring.sleuth.web.async.client.template.enabled` to `false`. + +[[sleuth-http-client-multiple-async-rest-template-integration]] +==== Multiple Asynchronous Rest Templates + +Sometimes you need to use multiple implementations of the Asynchronous Rest Template. +In the following snippet, you can see an example of how to set up such a custom `AsyncRestTemplate`: + +[source,java,indent=0] +---- +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_async_rest_template,indent=0] +---- + +[[sleuth-http-client-webclient-integration]] +==== `WebClient` + +This feature is available for all tracer implementations. + +We inject a `ExchangeFilterFunction` implementation that creates a span and, through on-success and on-error callbacks, takes care of closing client-side spans. + +To block this feature, set `spring.sleuth.web.client.enabled` to `false`. + +IMPORTANT: You have to register `WebClient` as a bean so that the tracing instrumentation gets applied. +If you create a `WebClient` instance with a `new` keyword, the instrumentation does NOT work. + +[[sleuth-http-client-traverson-integration]] +==== Traverson + +This feature is available for all tracer implementations. + +If you use the https://docs.spring.io/spring-hateoas/docs/current/reference/html/#client.traverson[Traverson] library, you can inject a `RestTemplate` as a bean into your Traverson object. +Since `RestTemplate` is already intercepted, you get full support for tracing in your client. +The following pseudo code shows how to do that: + +[source,java,indent=0] +---- +@Autowired RestTemplate restTemplate; + +Traverson traverson = new Traverson(URI.create("https://some/address"), + MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate); +// use Traverson +---- + +[[sleuth-http-client-apache-integration]] +==== Apache `HttpClientBuilder` and `HttpAsyncClientBuilder` + +This feature is available for Brave tracer implementation. + +We instrument the `HttpClientBuilder` and `HttpAsyncClientBuilder` so that tracing context gets injected to the sent requests. + +To block these features, set `spring.sleuth.web.client.enabled` to `false`. + +[[sleuth-http-client-netty-integration]] +==== Netty `HttpClient` + +This feature is available for all tracer implementations. + +We instrument the Netty's `HttpClient`. + +To block this feature, set `spring.sleuth.web.client.enabled` to `false`. + +IMPORTANT: You have to register `HttpClient` as a bean so that the instrumentation happens. +If you create a `HttpClient` instance with a `new` keyword, the instrumentation does NOT work. + +[[sleuth-http-client-userinfo-integration]] +==== `UserInfoRestTemplateCustomizer` + +This feature is available for all tracer implementations. + +We instrument the Spring Security's `UserInfoRestTemplateCustomizer`. + +To block this feature, set `spring.sleuth.web.client.enabled` to `false`. + +[[sleuth-http-server-integration]] +== HTTP Server Integration + +Features from this section can be disabled by setting the `spring.sleuth.web.enabled` property with value equal to `false`. + +[[sleuth-http-server-http-filter-integration]] +=== HTTP Filter + +This feature is available for all tracer implementations. + +Through the `TracingFilter`, all sampled incoming requests result in creation of a Span. +You can configure which URIs you would like to skip by setting the `spring.sleuth.web.skipPattern` property. +If you have `ManagementServerProperties` on classpath, its value of `contextPath` gets appended to the provided skip pattern. +If you want to reuse the Sleuth's default skip patterns and just append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. + +By default, all the spring boot actuator endpoints are automatically added to the skip pattern. +If you want to disable this behaviour set `spring.sleuth.web.ignore-auto-configured-skip-patterns` +to `true`. + +To change the order of tracing filter registration, please set the +`spring.sleuth.web.filter-order` property. + +To disable the filter that logs uncaught exceptions you can disable the +`spring.sleuth.web.exception-throwing-filter-enabled` property. + +[[sleuth-http-server-handler-interceptor-integration]] +=== HandlerInterceptor + +This feature is available for all tracer implementations. + +Since we want the span names to be precise, we use a `TraceHandlerInterceptor` that either wraps an existing `HandlerInterceptor` or is added directly to the list of existing `HandlerInterceptors`. +The `TraceHandlerInterceptor` adds a special request attribute to the given `HttpServletRequest`. +If the the `TracingFilter` does not see this attribute, it creates a "`fallback`" span, which is an additional span created on the server side so that the trace is presented properly in the UI. +If that happens, there is probably missing instrumentation. +In that case, please file an issue in Spring Cloud Sleuth. + +[[sleuth-http-server-async-integration]] +=== Async Servlet support + +This feature is available for all tracer implementations. + +If your controller returns a `Callable` or a `WebAsyncTask`, Spring Cloud Sleuth continues the existing span instead of creating a new one. + +[[sleuth-http-server-webflux-integration]] +=== WebFlux support + +This feature is available for all tracer implementations. + +Through `TraceWebFilter`, all sampled incoming requests result in creation of a Span. +That Span's name is `http:` + the path to which the request was sent. +For example, if the request was sent to `/this/that`, the name is `http:/this/that`. +You can configure which URIs you would like to skip by using the `spring.sleuth.web.skipPattern` property. +If you have `ManagementServerProperties` on the classpath, its value of `contextPath` gets appended to the provided skip pattern. +If you want to reuse Sleuth's default skip patterns and append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`. + +In order to achieve best results in terms of performance and context propagation we suggest that you switch the `spring.sleuth.reactor.instrumentation-type` to `MANUAL`. +In order to execute code with the span in scope you can call `WebFluxSleuthOperators.withSpanInScope`. +Example: + +[source,java,indent=0] +----- +include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] +----- + +To change the order of tracing filter registration, please set the +`spring.sleuth.web.filter-order` property. + +[[sleuth-messaging-integration]] +== Messaging + +Features from this section can be disabled by setting the `spring.sleuth.messaging.enabled` property with value equal to `false`. + +[[sleuth-messaging-spring-integration-integration]] +=== Spring Integration + +This feature is available for all tracer implementations. + +Spring Cloud Sleuth integrates with https://projects.spring.io/spring-integration/[Spring Integration]. +It creates spans for publish and subscribe events. +To disable Spring Integration instrumentation, set `spring.sleuth.integration.enabled` to `false`. + +You can provide the `spring.sleuth.integration.patterns` pattern to explicitly provide the names of channels that you want to include for tracing. +By default, all channels but `hystrixStreamOutput` channel are included. + +IMPORTANT: When using the `Executor` to build a Spring Integration `IntegrationFlow`, you must use the untraced version of the `Executor`. +Decorating the Spring Integration Executor Channel with `TraceableExecutorService` causes the spans to be improperly closed. + +If you want to customize the way tracing context is read from and written to message headers, it's enough for you to register beans of types: + +* `Propagator.Setter` - for writing headers to the message +* `Propagator.Getter` - for reading headers from the message + +[[sleuth-messaging-spring-integration-customization]] +==== Spring Integration Customization + +==== Customizing messaging spans + +In order to change the default span names and tags, just register a bean of type `MessageSpanCustomizer`. You can also +override the existing `DefaultMessageSpanCustomizer` to extend the existing behaviour. + +[source,java] +---- +@Component +include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java[tags=message_span_customizer,indent=2] +---- + +[[sleuth-messaging-spring-cloud-function-integration]] +=== Spring Cloud Function and Spring Cloud Stream + +This feature is available for all tracer implementations. + +Spring Cloud Sleuth can instrument Spring Cloud Function. +The way to achieve it is to provide a `Function` or `Consumer` or `Supplier` that takes in a `Message` as a parameter e.g. `Function, Message>`. +If the type is not `Message` then instrumentation will not take place. +Out of the box instrumentation will not take place when dealing with Reactor based streams - e.g. `Function>, Flux>>`. + +Since Spring Cloud Stream reuses Spring Cloud Function, you'll get the instrumentation out of the box. + +You can disable this behavior by setting the value of `spring.sleuth.function.enabled` to `false`. + +In order to work with reactive Stream functions you can leverage the `MessagingSleuthOperators` utility class that allows you to manipulate the input and output messages in order to continue the tracing context and to execute custom code within the tracing context. + +[source,java,indent=0] +----- +include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/stream/SleuthBenchmarkingStreamApplication.java[tags=simple_reactive,indent=0] +----- + +[[sleuth-messaging-spring-rabbitmq-integration]] +=== Spring RabbitMq + +This feature is available for Brave tracer implementation. + +We instrument the `RabbitTemplate` so that tracing headers get injected into the message. + +To block this feature, set `spring.sleuth.messaging.rabbit.enabled` to `false`. + +[[sleuth-messaging-spring-kafka-integration]] +=== Spring Kafka + +This feature is available for Brave tracer implementation. + +We instrument the Spring Kafka's `ProducerFactory` and `ConsumerFactory` +so that tracing headers get injected into the created Spring Kafka's +`Producer` and `Consumer`. + +To block this feature, set `spring.sleuth.messaging.kafka.enabled` to `false`. + +[[sleuth-messaging-spring-kafka-streams-integration]] +=== Spring Kafka Streams + +This feature is available for Brave tracer implementation. + +We instrument the `KafkaStreams` `KafkaClientSupplier` so that tracing headers get injected into the `Producer` and `Consumer`s. A `KafkaStreamsTracing` bean allows for further instrumentation through additional `TransformerSupplier` and +`ProcessorSupplier` methods. + +To block this feature, set `spring.sleuth.messaging.kafka.streams.enabled` to `false`. + +[[sleuth-messaging-spring-jms-integration]] +=== Spring JMS + +This feature is available for Brave tracer implementation. + +We instrument the `JmsTemplate` so that tracing headers get injected into the message. +We also support `@JmsListener` annotated methods on the consumer side. + +To block this feature, set `spring.sleuth.messaging.jms.enabled` to `false`. + +IMPORTANT: We don't support baggage propagation for JMS + +[[sleuth-openfeign-integration]] +== OpenFeign + +This feature is available for all tracer implementations. + +By default, Spring Cloud Sleuth provides integration with Feign through `TraceFeignClientAutoConfiguration`. +You can disable it entirely by setting `spring.sleuth.feign.enabled` to `false`. +If you do so, no Feign-related instrumentation take place. + +Part of Feign instrumentation is done through a `FeignBeanPostProcessor`. +You can disable it by setting `spring.sleuth.feign.processor.enabled` to `false`. +If you set it to `false`, Spring Cloud Sleuth does not instrument any of your custom Feign components. +However, all the default instrumentation is still there. + +[[sleuth-opentracing-integration]] +== OpenTracing + +This feature is available for all tracer implementations. + +Spring Cloud Sleuth is compatible with https://opentracing.io/[OpenTracing]. +If you have OpenTracing on the classpath, we automatically register the OpenTracing `Tracer` bean. +If you wish to disable this, set `spring.sleuth.opentracing.enabled` to `false` + +[[sleuth-quartz-integration]] +== Quartz + +This feature is available for all tracer implementations. + +We instrument quartz jobs by adding Job/Trigger listeners to the Quartz Scheduler. + +To turn off this feature, set the `spring.sleuth.quartz.enabled` property to `false`. + +[[sleuth-reactor-integration]] +== Reactor + +This feature is available for all tracer implementations. + +We have the following modes of instrumenting reactor based applications that can be set via `spring.sleuth.reactor.instrumentation-type` property: + +* `DECORATE_QUEUES` - With the new Reactor https://github.com/reactor/reactor-core/pull/2566[queue wrapping mechanism] (Reactor 3.4.3) we're instrumenting the way threads are switched by Reactor. This should lead to feature parity with `ON_EACH` with low performance impact. +* `DECORATE_ON_EACH` - wraps every Reactor operator in a trace representation. +Passes the tracing context in most cases. +This mode might lead to drastic performance degradation. +* `DECORATE_ON_LAST` - wraps last Reactor operator in a trace representation. +Passes the tracing context in some cases thus accessing MDC context might not work. +This mode might lead to medium performance degradation. +* `MANUAL` - wraps every Reactor in the least invasive way without passing of tracing context. +It's up to the user to do it. + +Current default is `ON_EACH` for backward compatibility reasons, however we encourage the users to migrate to the `MANUAL` instrumentation and profit from `WebFluxSleuthOperators` and `MessagingSleuthOperators`. +The performance improvement can be substantial. +Example: + +[source,java,indent=0] +----- +include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java[tags=simple_manual,indent=0] +----- + +[[sleuth-redis-integration]] +== Redis + +This feature is available for Brave tracer implementation. + +We set `tracing` property to Lettuce `ClientResources` instance to enable Brave tracing built in Lettuce . +To disable Redis support, set the `spring.sleuth.redis.enabled` property to `false`. + +[[sleuth-runnablecallable-integration]] +== Runnable and Callable + +This feature is available for all tracer implementations. + +If you wrap your logic in `Runnable` or `Callable`, you can wrap those classes in their Sleuth representative, as shown in the following example for `Runnable`: + +[source,java,indent=0] +---- +include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_runnable,indent=0] +---- + +The following example shows how to do so for `Callable`: + +[source,java,indent=0] +---- +include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_callable,indent=0] +---- + +That way, you ensure that a new span is created and closed for each execution. + +[[sleuth-rpc-integration]] +== RPC + +This feature is available for Brave tracer implementation. + +Sleuth automatically configures the `RpcTracing` bean which serves as a foundation for RPC instrumentation such as gRPC or Dubbo. + +If a customization of client / server sampling of the RPC traces is required, just register a bean of type `brave.sampler.SamplerFunction` and name the bean `sleuthRpcClientSampler` for client sampler and +`sleuthRpcServerSampler` for server sampler. + +For your convenience the `@RpcClientSampler` and `@RpcServerSampler` +annotations can be used to inject the proper beans or to reference the bean names via their static String `NAME` fields. + +Ex. +Here's a sampler that traces 100 "GetUserToken" server requests per second. +This doesn't start new traces for requests to the health check service. +Other requests will use the global sampling configuration. + +[source,java,indent=0] +---- +@Configuration(proxyBeanMethods = false) + class Config { +include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java[tags=custom_rpc_server_sampler,indent=2] +} +---- + +For more, see https://github.com/openzipkin/brave/tree/master/instrumentation/rpc#sampling-policy + +[[sleuth-rpc-dubbo-integration]] +=== Dubbo RPC support + +Via the integration with Brave, Spring Cloud Sleuth supports https://dubbo.apache.org/[Dubbo]. +It's enough to add the `brave-instrumentation-dubbo` dependency: + +[source,xml,indent=0] +---- + + io.zipkin.brave + brave-instrumentation-dubbo + +---- + +You need to also set a `dubbo.properties` file with the following contents: + +```properties +dubbo.provider.filter=tracing +dubbo.consumer.filter=tracing +``` + +You can read more about Brave - Dubbo integration https://github.com/openzipkin/brave/tree/master/instrumentation/dubbo-rpc[here]. +An example of Spring Cloud Sleuth and Dubbo can be found https://github.com/openzipkin/sleuth-webmvc-example/compare/add-dubbo-tracing[here]. + +[[sleuth-rpc-grpc-integration]] +=== gRPC + +Spring Cloud Sleuth provides instrumentation for https://grpc.io/[gRPC] via the Brave tracer. +You can disable it entirely by setting `spring.sleuth.grpc.enabled` to `false`. + +[[sleuth-rpc-grpc-variant1-integration]] +==== Variant 1 + +[[sleuth-rpc-grpc-variant1-dependencies-integration]] +===== Dependencies + +IMPORTANT: The gRPC integration relies on two external libraries to instrument clients and servers and both of those libraries must be on the class path to enable the instrumentation. + +Maven: + +``` + + io.github.lognet + grpc-spring-boot-starter + + + io.zipkin.brave + brave-instrumentation-grpc + +``` + +Gradle: + +``` + compile("io.github.lognet:grpc-spring-boot-starter") + compile("io.zipkin.brave:brave-instrumentation-grpc") +``` + +[[sleuth-rpc-grpc-variant1-server-integration]] +===== Server Instrumentation + +Spring Cloud Sleuth leverages grpc-spring-boot-starter to register Brave's gRPC server interceptor with all services annotated with `@GRpcService`. + +[[sleuth-rpc-grpc-variant1-client-integration]] +===== Client Instrumentation + +gRPC clients leverage a `ManagedChannelBuilder` to construct a `ManagedChannel` used to communicate to the gRPC server. +The native `ManagedChannelBuilder` provides static methods as entry points for construction of `ManagedChannel` instances, however, this mechanism is outside the influence of the Spring application context. + +IMPORTANT: Spring Cloud Sleuth provides a `SpringAwareManagedChannelBuilder` that can be customized through the Spring application context and injected by gRPC clients. +*This builder must be used when creating `ManagedChannel` instances.* + +Sleuth creates a `TracingManagedChannelBuilderCustomizer` which inject Brave's client interceptor into the `SpringAwareManagedChannelBuilder`. + +[[sleuth-rpc-grpc-variant2-integration]] +==== Variant 2 + +https://github.com/yidongnan/grpc-spring-boot-starter[Grpc Spring Boot Starter] automatically detects the presence of Spring Cloud Sleuth and Brave's instrumentation for gRPC and registers the necessary client and/or server tooling. + +[[sleuth-rxjava-integration]] +== RxJava + +This feature is available for all tracer implementations. + +We registering a custom https://github.com/ReactiveX/RxJava/wiki/Plugins#rxjavaschedulershook[`RxJavaSchedulersHook`] that wraps all `Action0` instances in their Sleuth representative, which is called `TraceAction`. +The hook either starts or continues a span, depending on whether tracing was already going on before the Action was scheduled. +To disable the custom `RxJavaSchedulersHook`, set the `spring.sleuth.rxjava.schedulers.hook.enabled` to `false`. + +You can define a list of regular expressions for thread names for which you do not want spans to be created. +To do so, provide a comma-separated list of regular expressions in the `spring.sleuth.rxjava.schedulers.ignoredthreads` property. + +IMPORTANT: The suggested approach to reactive programming and Sleuth is to use the Reactor support. + +[[sleuth-circuitbreaker-integration]] +== Spring Cloud CircuitBreaker + +This feature is available for all tracer implementations. + +If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. We will also instrument the reactive implementation of the CircuitBreaker. +In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`. + +[[sleuth-config-server-integration]] +== Spring Cloud Config Server + +This feature is available for all tracer implementations. + +If you have Spring Cloud Config Server running on the classpath, we will wrap the `EnvironmentRepository` in a span. +In order to disable this instrumentation set `spring.sleuth.config.server.enabled` to `false`. + +[[sleuth-deployer-integration]] +== Spring Cloud Deployer + +This feature is available for all tracer implementations. + +If you have Spring Cloud Deployer running on the classpath, we wrap the `AppDeployer` in a trace representation. We are polling the application for its status at a default interval. You can change that default by setting the `spring.sleuth.deployer.status-poll-delay` property. +In order to disable this instrumentation set `spring.sleuth.deployer.enabled` to `false`. diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index ec3dadb1b..ef1e667b5 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -147,7 +147,7 @@ "name": "spring.sleuth.deployer.status-poll-delay", "type": "java.lang.Long", "description": "Default poll delay to retrieve the deployed application status.", - "defaultValue": 1000 + "defaultValue": 500 }, { "name": "spring.sleuth.config.server.enabled", From 085f29e7bfac9694f505e74faf31a6c158296bd6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 26 Apr 2021 19:07:32 +0200 Subject: [PATCH 75/78] Master to main --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8b5ff26b1..f8ee2091f 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -2,9 +2,9 @@ name: Build on: push: - branches: [ master ] + branches: [ main ] pull_request: - branches: [ master ] + branches: [ main ] jobs: build: From ba8da46e2030735359f9f351e5277807540e3341 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 26 Apr 2021 22:58:28 +0200 Subject: [PATCH 76/78] Update TraceAppDeployer.java --- .../instrument/deployer/TraceAppDeployer.java | 516 +++++++++--------- 1 file changed, 258 insertions(+), 258 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java index 4ea4de184..b236a6057 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java @@ -1,92 +1,92 @@ -/* - * Copyright 2018-2021 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 - * - * https://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.instrument.deployer; - -import java.time.Duration; -import java.util.Arrays; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.cloud.deployer.spi.app.AppDeployer; -import org.springframework.cloud.deployer.spi.app.AppScaleRequest; -import org.springframework.cloud.deployer.spi.app.AppStatus; -import org.springframework.cloud.deployer.spi.app.DeploymentState; -import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; -import org.springframework.cloud.deployer.spi.core.RuntimeEnvironmentInfo; -import org.springframework.cloud.sleuth.CurrentTraceContext; -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; -import org.springframework.core.env.Environment; - -/** - * Trace representation of an {@link AppDeployer}. - * - * @author Marcin Grzejszczak - * @since 3.1.0 - */ -public class TraceAppDeployer implements AppDeployer { - - private static final Log log = LogFactory.getLog(TraceAppDeployer.class); - - private final AppDeployer delegate; - - private final BeanFactory beanFactory; - - private final Environment environment; - - private Tracer tracer; - - private CurrentTraceContext currentTraceContext; - - private Long pollDelay; - - public TraceAppDeployer(AppDeployer delegate, BeanFactory beanFactory, Environment environment) { - this.delegate = delegate; - this.beanFactory = beanFactory; - this.environment = environment; - } - - @Override - public String deploy(AppDeploymentRequest request) { - Span span = tracer().nextSpan().name("deploy"); - // TODO: Is this secure to pass? - // TODO: Does it make sense? - // if (!request.getCommandlineArguments().isEmpty()) { - // span.tag("commandlineArguments", request.getCommandlineArguments().toString()); - // } - // if (!request.getDeploymentProperties().isEmpty()) { - // span.tag("deploymentProperties", request.getDeploymentProperties().toString()); - // } - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - span.event("start"); - String id = this.delegate.deploy(request); - span.tag("id", id); - registerListener(span, id); - return id; - } - } - - private void registerListener(Span span, String id) { - PreviousAndCurrentStatus previousAndCurrentStatus = new PreviousAndCurrentStatus(span); +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.deployer; + +import java.time.Duration; +import java.util.Arrays; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.deployer.spi.app.AppScaleRequest; +import org.springframework.cloud.deployer.spi.app.AppStatus; +import org.springframework.cloud.deployer.spi.app.DeploymentState; +import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; +import org.springframework.cloud.deployer.spi.core.RuntimeEnvironmentInfo; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; +import org.springframework.core.env.Environment; + +/** + * Trace representation of an {@link AppDeployer}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceAppDeployer implements AppDeployer { + + private static final Log log = LogFactory.getLog(TraceAppDeployer.class); + + private final AppDeployer delegate; + + private final BeanFactory beanFactory; + + private final Environment environment; + + private Tracer tracer; + + private CurrentTraceContext currentTraceContext; + + private Long pollDelay; + + public TraceAppDeployer(AppDeployer delegate, BeanFactory beanFactory, Environment environment) { + this.delegate = delegate; + this.beanFactory = beanFactory; + this.environment = environment; + } + + @Override + public String deploy(AppDeploymentRequest request) { + Span span = tracer().nextSpan().name("deploy"); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (!request.getCommandlineArguments().isEmpty()) { + // span.tag("commandlineArguments", request.getCommandlineArguments().toString()); + // } + // if (!request.getDeploymentProperties().isEmpty()) { + // span.tag("deploymentProperties", request.getDeploymentProperties().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + String id = this.delegate.deploy(request); + span.tag("deployer.app.id", id); + registerListener(span, id); + return id; + } + } + + private void registerListener(Span span, String id) { + PreviousAndCurrentStatus previousAndCurrentStatus = new PreviousAndCurrentStatus(span); // @formatter:off this.delegate.statusReactive(id) .map(previousAndCurrentStatus::updateCurrent) @@ -97,172 +97,172 @@ public class TraceAppDeployer implements AppDeployer { .doOnError(span::error) // we will close the span in the reactive part .doFinally(signalType -> span.end()).subscribe(); - // @formatter:on - } - - @Override - public void undeploy(String id) { - Span span = tracer().nextSpan().name("undeploy"); - span.tag("id", id); - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - span.event("start"); - this.delegate.undeploy(id); - registerListener(span, id); - } - finally { - span.end(); - } - } - - @Override - public AppStatus status(String id) { - Span span = tracer().nextSpan().name("status"); - span.tag("id", id); - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - return this.delegate.status(id); - } - finally { - span.end(); - } - } - - @Override - public Mono statusReactive(String id) { - return ReactorSleuth.tracedMono(tracer(), currentTraceContext(), "status", - () -> this.delegate.statusReactive(id), span -> span.tag("id", id)); - } - - @Override - public Flux statusesReactive(String... ids) { - return ReactorSleuth.tracedFlux(tracer(), currentTraceContext(), "statuses", - () -> this.delegate.statusesReactive(ids), span -> span.tag("ids", Arrays.toString(ids))); - } - - @Override - public RuntimeEnvironmentInfo environmentInfo() { - return this.delegate.environmentInfo(); - } - - @Override - public String getLog(String id) { - Span span = tracer().nextSpan().name("getLog"); - span.tag("id", id); - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - return this.delegate.getLog(id); - } - finally { - span.end(); - } - } - - @Override - public void scale(AppScaleRequest appScaleRequest) { - Span span = tracer().nextSpan().name("scale"); - span.tag("deploymentId", appScaleRequest.getDeploymentId()); - span.tag("count", String.valueOf(appScaleRequest.getCount())); - // TODO: Is this secure to pass? - // TODO: Does it make sense? - // if (appScaleRequest.getProperties().isPresent() && - // !appScaleRequest.getProperties().get().isEmpty()) { - // span.tag("properties", appScaleRequest.getProperties().get().toString()); - // } - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - this.delegate.scale(appScaleRequest); - } - finally { - span.end(); - } - } - - private Tracer tracer() { - if (this.tracer == null) { - this.tracer = this.beanFactory.getBean(Tracer.class); - } - return this.tracer; - } - - private CurrentTraceContext currentTraceContext() { - if (this.currentTraceContext == null) { - this.currentTraceContext = this.beanFactory.getBean(CurrentTraceContext.class); - } - return this.currentTraceContext; - } - - private long pollDelay() { - if (this.pollDelay == null) { - this.pollDelay = this.environment.getProperty("spring.sleuth.deployer.status-poll-delay", Long.class, 500L); - } - return this.pollDelay; - } - - private static final class PreviousAndCurrentStatus { - - private final Span span; - - private AppStatus current; - - private AppStatus previous; - - private PreviousAndCurrentStatus(Span span) { - this.span = span; - if (log.isDebugEnabled()) { - log.debug("Current span is [" + span + "]"); - } - } - - private PreviousAndCurrentStatus updateCurrent(AppStatus current) { - if (log.isTraceEnabled()) { - log.trace("State before change: current [" + this.current + "], previous [" + this.previous + "]"); - } - this.previous = this.current; - this.current = current; - if (log.isTraceEnabled()) { - log.trace("State after change: current [" + this.current + "], previous [" + this.previous + "]"); - } - if (statusChanged()) { - annotateSpan(); - } - else if (log.isTraceEnabled()) { - log.trace("State has not changed, will not annotate the span"); - } - return this; - } - - private void annotateSpan() { - String name = this.current.getState().name(); - if (log.isDebugEnabled()) { - log.debug("Will annotate its state with [" + name + "]"); - } - this.span.event(name); - } - - private boolean statusChanged() { - if (this.previous == null && this.current != null) { - if (log.isDebugEnabled()) { - log.debug("Previous is null, current is not null"); - } - return true; - } - else if (this.current == null) { - throw new IllegalStateException("Current state can't be null"); - } - DeploymentState currentState = this.current.getState(); - DeploymentState previousState = this.previous.getState(); - return currentState != previousState; - } - - private boolean isFinished() { - boolean finished = this.current.getState() == DeploymentState.deployed - || this.current.getState() == DeploymentState.undeployed - || this.current.getState() == DeploymentState.failed - || this.current.getState() == DeploymentState.error - || this.current.getState() == DeploymentState.unknown; - if (log.isTraceEnabled()) { - log.trace("Status is finished [" + finished + "]"); - } - return finished; - } - - } - -} + // @formatter:on + } + + @Override + public void undeploy(String id) { + Span span = tracer().nextSpan().name("undeploy"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + this.delegate.undeploy(id); + registerListener(span, id); + } + finally { + span.end(); + } + } + + @Override + public AppStatus status(String id) { + Span span = tracer().nextSpan().name("status"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.status(id); + } + finally { + span.end(); + } + } + + @Override + public Mono statusReactive(String id) { + return ReactorSleuth.tracedMono(tracer(), currentTraceContext(), "status", + () -> this.delegate.statusReactive(id), span -> span.tag("deployer.app.id", id)); + } + + @Override + public Flux statusesReactive(String... ids) { + return ReactorSleuth.tracedFlux(tracer(), currentTraceContext(), "statuses", + () -> this.delegate.statusesReactive(ids), span -> span.tag("deployer.app.ids", Arrays.toString(ids))); + } + + @Override + public RuntimeEnvironmentInfo environmentInfo() { + return this.delegate.environmentInfo(); + } + + @Override + public String getLog(String id) { + Span span = tracer().nextSpan().name("getLog"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.getLog(id); + } + finally { + span.end(); + } + } + + @Override + public void scale(AppScaleRequest appScaleRequest) { + Span span = tracer().nextSpan().name("scale"); + span.tag("deployer.scale.deploymentId", appScaleRequest.getDeploymentId()); + span.tag("deployer.scale.count", String.valueOf(appScaleRequest.getCount())); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (appScaleRequest.getProperties().isPresent() && + // !appScaleRequest.getProperties().get().isEmpty()) { + // span.tag("properties", appScaleRequest.getProperties().get().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.scale(appScaleRequest); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + + private CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.beanFactory.getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + + private long pollDelay() { + if (this.pollDelay == null) { + this.pollDelay = this.environment.getProperty("spring.sleuth.deployer.status-poll-delay", Long.class, 500L); + } + return this.pollDelay; + } + + private static final class PreviousAndCurrentStatus { + + private final Span span; + + private AppStatus current; + + private AppStatus previous; + + private PreviousAndCurrentStatus(Span span) { + this.span = span; + if (log.isDebugEnabled()) { + log.debug("Current span is [" + span + "]"); + } + } + + private PreviousAndCurrentStatus updateCurrent(AppStatus current) { + if (log.isTraceEnabled()) { + log.trace("State before change: current [" + this.current + "], previous [" + this.previous + "]"); + } + this.previous = this.current; + this.current = current; + if (log.isTraceEnabled()) { + log.trace("State after change: current [" + this.current + "], previous [" + this.previous + "]"); + } + if (statusChanged()) { + annotateSpan(); + } + else if (log.isTraceEnabled()) { + log.trace("State has not changed, will not annotate the span"); + } + return this; + } + + private void annotateSpan() { + String name = this.current.getState().name(); + if (log.isDebugEnabled()) { + log.debug("Will annotate its state with [" + name + "]"); + } + this.span.event(name); + } + + private boolean statusChanged() { + if (this.previous == null && this.current != null) { + if (log.isDebugEnabled()) { + log.debug("Previous is null, current is not null"); + } + return true; + } + else if (this.current == null) { + throw new IllegalStateException("Current state can't be null"); + } + DeploymentState currentState = this.current.getState(); + DeploymentState previousState = this.previous.getState(); + return currentState != previousState; + } + + private boolean isFinished() { + boolean finished = this.current.getState() == DeploymentState.deployed + || this.current.getState() == DeploymentState.undeployed + || this.current.getState() == DeploymentState.failed + || this.current.getState() == DeploymentState.error + || this.current.getState() == DeploymentState.unknown; + if (log.isTraceEnabled()) { + log.trace("Status is finished [" + finished + "]"); + } + return finished; + } + + } + +} From 216d681b04a2fc228ca5628e4f5c4593d9b33171 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 29 Apr 2021 13:32:58 +0200 Subject: [PATCH 77/78] Adds RSocket instrumentation coauthor @olegdokuka fixes gh-1677 --- docs/src/main/asciidoc/integrations.adoc | 9 + .../cloud/sleuth/SpanAndScope.java | 5 + .../cloud/sleuth/TraceContext.java | 43 ++ .../springframework/cloud/sleuth/Tracer.java | 6 + .../cloud/sleuth/WithThreadLocalSpan.java | 91 ++++ spring-cloud-sleuth-autoconfigure/pom.xml | 5 + .../messaging/SleuthMessagingProperties.java | 34 ++ ...TraceSpringMessagingAutoConfiguration.java | 11 + .../rsocket/SleuthRSocketProperties.java | 43 ++ .../TraceRSocketAutoConfiguration.java | 89 ++++ .../main/resources/META-INF/spring.factories | 1 + .../autoconfig/NoOpTraceContextBuilder.java | 54 ++ .../cloud/sleuth/autoconfig/NoOpTracer.java | 5 + .../bridge/BraveTraceContextBuilder.java | 71 +++ .../sleuth/brave/bridge/BraveTracer.java | 5 + .../sleuth/brave/bridge/W3CPropagation.java | 174 +------ .../bridge/BraveTraceContextBuilderTests.java | 54 ++ .../brave/bridge/W3CPropagationTest.java | 8 +- spring-cloud-sleuth-instrumentation/pom.xml | 10 + .../instrument/async/TraceAsyncAspect.java | 1 + .../messaging/TraceMessageHandler.java | 6 - .../messaging/TraceMessagingAspect.java | 100 ++++ .../messaging/TracingChannelInterceptor.java | 49 +- .../instrument/reactor/ReactorSleuth.java | 75 ++- .../instrument/rsocket/ByteBufGetter.java | 38 ++ .../instrument/rsocket/ByteBufSetter.java | 35 ++ .../rsocket/CompositeMetadataUtils.java | 42 ++ .../instrument/rsocket/PayloadUtils.java | 68 +++ .../TracingRSocketConnectorConfigurer.java | 49 ++ .../TracingRSocketServerCustomizer.java | 49 ++ .../rsocket/TracingRequesterRSocketProxy.java | 168 +++++++ .../rsocket/TracingResponderRSocketProxy.java | 170 +++++++ .../cloud/sleuth/internal/EncodingUtils.java | 322 ++++++++++++ .../instrument/deployer/SimpleTracer.java | 5 + .../sleuth/internal/EncodingUtilsTests.java | 43 ++ tests/brave/pom.xml | 1 + .../pom.xml | 100 ++++ .../instrument/rsocket/TraceRSocketTests.java | 53 ++ .../src/test/resources/logback.xml | 32 ++ tests/common/pom.xml | 465 +++++++++--------- .../config/ConfigServerIntegrationTests.java | 2 +- .../instrument/rsocket/TraceRSocketTests.java | 363 ++++++++++++++ 42 files changed, 2494 insertions(+), 460 deletions(-) create mode 100644 spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/WithThreadLocalSpan.java create mode 100644 spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/SleuthRSocketProperties.java create mode 100644 spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/TraceRSocketAutoConfiguration.java create mode 100644 spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContextBuilder.java create mode 100644 spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilder.java create mode 100644 spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilderTests.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufGetter.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufSetter.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/CompositeMetadataUtils.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/PayloadUtils.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketConnectorConfigurer.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketServerCustomizer.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRequesterRSocketProxy.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingResponderRSocketProxy.java create mode 100644 spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/EncodingUtils.java create mode 100644 spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/EncodingUtilsTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/pom.xml create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rsocket/TraceRSocketTests.java create mode 100644 tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/resources/logback.xml create mode 100644 tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java diff --git a/docs/src/main/asciidoc/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc index 9d8530d57..322c2ff23 100644 --- a/docs/src/main/asciidoc/integrations.adoc +++ b/docs/src/main/asciidoc/integrations.adoc @@ -583,3 +583,12 @@ This feature is available for all tracer implementations. If you have Spring Cloud Deployer running on the classpath, we wrap the `AppDeployer` in a trace representation. We are polling the application for its status at a default interval. You can change that default by setting the `spring.sleuth.deployer.status-poll-delay` property. In order to disable this instrumentation set `spring.sleuth.deployer.enabled` to `false`. + + +[[sleuth-deployer-integration]] +== Spring RSocket + +This feature is available for all tracer implementations. + +If you have Spring RSocket running on the classpath, we wrap the inbound and outbound communication to propagate the tracing context via the metadata. +In order to disable this instrumentation set `spring.sleuth.rsocket.enabled` to `false`. diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java index e18e028d7..807e871c6 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.java @@ -41,4 +41,9 @@ public class SpanAndScope { return this.scope; } + @Override + public String toString() { + return "SpanAndScope{" + "span=" + this.span + '}'; + } + } diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java index d9e564bbd..15cb7231e 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/TraceContext.java @@ -51,4 +51,47 @@ public interface TraceContext { */ Boolean sampled(); + /** + * Builder for {@link TraceContext}. + * + * @since 3.1.0 + */ + interface Builder { + + /** + * Sets trace id on the trace context. + * @param traceId trace id + * @return this + */ + TraceContext.Builder traceId(String traceId); + + /** + * Sets parent id on the trace context. + * @param parentId parent trace id + * @return this + */ + TraceContext.Builder parentId(String parentId); + + /** + * Sets span id on the trace context. + * @param spanId span id + * @return this + */ + TraceContext.Builder spanId(String spanId); + + /** + * Sets sampled on the trace context. + * @param sampled if span is sampled + * @return this + */ + TraceContext.Builder sampled(Boolean sampled); + + /** + * Builds the trace context. + * @return trace context + */ + TraceContext build(); + + } + } diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java index bf05dea69..b5a06b5b9 100644 --- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/Tracer.java @@ -134,6 +134,12 @@ public interface Tracer extends BaggageManager { */ Span.Builder spanBuilder(); + /** + * Builder for {@link TraceContext}. + * @return a trace context builder + */ + TraceContext.Builder traceContextBuilder(); + /** * Allows to customize the current span in scope. * @return current span customizer diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/WithThreadLocalSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/WithThreadLocalSpan.java new file mode 100644 index 000000000..89aec40f8 --- /dev/null +++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/WithThreadLocalSpan.java @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2021 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 + * + * https://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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.lang.Nullable; + +/** + * Represents a {@link Span} stored in thread local. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public interface WithThreadLocalSpan { + + /** + * Logger. + */ + Log log = LogFactory.getLog(WithThreadLocalSpan.class); + + /** + * Sets the span in thread local scope. + * @param span span to put in thread local + */ + default void setSpanInScope(Span span) { + getThreadLocalSpan().set(span); + if (log.isDebugEnabled()) { + log.debug("Put span in scope " + span); + } + } + + /** + * Finishes the thread local span. + * @param error potential error to be stored in span + */ + default void finishSpan(@Nullable Throwable error) { + SpanAndScope spanAndScope = takeSpanFromThreadLocal(); + if (spanAndScope == null) { + return; + } + Span span = spanAndScope.getSpan(); + Tracer.SpanInScope scope = spanAndScope.getScope(); + if (span.isNoop()) { + if (log.isDebugEnabled()) { + log.debug("Span " + span + " is noop - will stope the scope"); + } + scope.close(); + return; + } + if (error != null) { // an error occurred, adding error to span + span.error(error); + } + if (log.isDebugEnabled()) { + log.debug("Will finish the span and its corresponding scope " + span); + } + span.end(); + scope.close(); + } + + /** + * Takes a span from thread local and restores the previous one if present. + * @return span from a thread local span + */ + default SpanAndScope takeSpanFromThreadLocal() { + SpanAndScope span = getThreadLocalSpan().get(); + if (log.isDebugEnabled()) { + log.debug("Took span [" + span + "] from thread local"); + } + getThreadLocalSpan().remove(); + return span; + } + + ThreadLocalSpan getThreadLocalSpan(); + +} diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml index 994f00cd4..7f314a3b0 100644 --- a/spring-cloud-sleuth-autoconfigure/pom.xml +++ b/spring-cloud-sleuth-autoconfigure/pom.xml @@ -324,6 +324,11 @@ spring-boot-starter-data-mongodb true + + org.springframework.boot + spring-boot-starter-rsocket + true + diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java index 4a4d88c4a..3175d87ee 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthMessagingProperties.java @@ -17,6 +17,7 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.messaging; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.messaging.handler.annotation.MessageMapping; /** * Properties for messaging. @@ -32,6 +33,11 @@ public class SleuthMessagingProperties { */ private boolean enabled; + /** + * Aspect related properties. + */ + private Aspect aspect = new Aspect(); + /** * Rabbit related properties. */ @@ -55,6 +61,14 @@ public class SleuthMessagingProperties { this.enabled = enabled; } + public Aspect getAspect() { + return this.aspect; + } + + public void setAspect(Aspect aspect) { + this.aspect = aspect; + } + public Rabbit getRabbit() { return this.rabbit; } @@ -79,6 +93,26 @@ public class SleuthMessagingProperties { this.jms = jms; } + /** + * Aspect configuration. + */ + public static class Aspect { + + /** + * Should {@link MessageMapping} wrapping be enabled. + */ + private boolean enabled; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + /** * RabbitMQ configuration. */ diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java index fa596a866..a143bdb75 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringMessagingAutoConfiguration.java @@ -16,12 +16,16 @@ package org.springframework.cloud.sleuth.autoconfig.instrument.messaging; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 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.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.messaging.MessageHeaderPropagatorGetter; import org.springframework.cloud.sleuth.instrument.messaging.MessageHeaderPropagatorSetter; +import org.springframework.cloud.sleuth.instrument.messaging.TraceMessagingAspect; import org.springframework.cloud.sleuth.propagation.Propagator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -29,10 +33,17 @@ import org.springframework.messaging.support.MessageHeaderAccessor; @Configuration(proxyBeanMethods = false) @ConditionalOnClass(MessageHeaderAccessor.class) +@ConditionalOnBean(Tracer.class) @ConditionalOnProperty(value = "spring.sleuth.messaging.enabled", matchIfMissing = true) @EnableConfigurationProperties({ SleuthIntegrationMessagingProperties.class, SleuthMessagingProperties.class }) class TraceSpringMessagingAutoConfiguration { + @Bean + @ConditionalOnProperty(value = "spring.sleuth.messaging.aspect.enabled", matchIfMissing = true) + TraceMessagingAspect traceMessagingAspect(Tracer tracer, SpanNamer spanNamer) { + return new TraceMessagingAspect(tracer, spanNamer); + } + @Bean @ConditionalOnMissingBean Propagator.Setter traceMessagePropagationSetter() { diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/SleuthRSocketProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/SleuthRSocketProperties.java new file mode 100644 index 000000000..7dd0b0776 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/SleuthRSocketProperties.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.rsocket; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Sleuth RSocket settings. + * + * @author Oleh Dokuka + * @since 3.1.0 + */ +@ConfigurationProperties("spring.sleuth.rsocket") +public class SleuthRSocketProperties { + + /** + * When true enables instrumentation for rsocket. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/TraceRSocketAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/TraceRSocketAutoConfiguration.java new file mode 100644 index 000000000..584f76199 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/rsocket/TraceRSocketAutoConfiguration.java @@ -0,0 +1,89 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig.instrument.rsocket; + +import java.util.List; + +import io.rsocket.RSocket; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +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.autoconfigure.rsocket.RSocketRequesterAutoConfiguration; +import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration; +import org.springframework.cloud.sleuth.brave.propagation.PropagationType; +import org.springframework.cloud.sleuth.instrument.rsocket.TracingRSocketConnectorConfigurer; +import org.springframework.cloud.sleuth.instrument.rsocket.TracingRSocketServerCustomizer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.messaging.rsocket.RSocketConnectorConfigurer; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketRequester.Builder; +import org.springframework.messaging.rsocket.RSocketStrategies; + +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean(Tracer.class) +@ConditionalOnProperty(value = "spring.sleuth.rsocket.enabled", matchIfMissing = true) +@ConditionalOnClass({ RSocket.class, RSocketStrategies.class }) +@AutoConfigureAfter(BraveAutoConfiguration.class) +@AutoConfigureBefore({ RSocketRequesterAutoConfiguration.class, RSocketServerAutoConfiguration.class }) +@EnableConfigurationProperties(SleuthRSocketProperties.class) +public class TraceRSocketAutoConfiguration { + + // We're using text instead of objects cause we can have same properties from Brave / + // OTel + @Bean + @Scope("prototype") + @ConditionalOnMissingBean + Builder rSocketRequesterBuilder(RSocketStrategies strategies, + ObjectProvider connectorConfigurerProvider) { + // TODO: should be in spring boot + final Builder builder = RSocketRequester.builder().rsocketStrategies(strategies); + connectorConfigurerProvider.forEach(builder::rsocketConnector); + return builder; + } + + private boolean containsZipkinPropagationType(List types) { + return types.contains(PropagationType.B3); + } + + @Bean + RSocketConnectorConfigurer tracingRSocketConnectorConfigurer(Propagator propagator, Tracer tracer, + @Value("${spring.sleuth.propagation.type:B3}") List types) { + return new TracingRSocketConnectorConfigurer(propagator, tracer, containsZipkinPropagationType(types)); + } + + // We're using text instead of objects cause we can have same properties from Brave / + // OTel + @Bean + RSocketServerCustomizer tracingRSocketServerCustomizer(Propagator propagator, Tracer tracer, + @Value("${spring.sleuth.propagation.type:B3}") List types) { + return new TracingRSocketServerCustomizer(propagator, tracer, containsZipkinPropagationType(types)); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories index d96b177e0..91d031660 100644 --- a/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-sleuth-autoconfigure/src/main/resources/META-INF/spring.factories @@ -19,6 +19,7 @@ org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceFunctionAu org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringMessagingAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceWebSocketAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.instrument.rsocket.TraceRSocketAutoConfiguration, \ org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.client.BraveWebClientAutoConfiguration,\ org.springframework.cloud.sleuth.autoconfig.brave.instrument.rpc.BraveRpcAutoConfiguration,\ diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContextBuilder.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContextBuilder.java new file mode 100644 index 000000000..c0b17da52 --- /dev/null +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTraceContextBuilder.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.autoconfig; + +import org.springframework.cloud.sleuth.TraceContext; + +/** + * A noop implementation. Does nothing. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +class NoOpTraceContextBuilder implements TraceContext.Builder { + + @Override + public TraceContext.Builder traceId(String traceId) { + return this; + } + + @Override + public TraceContext.Builder parentId(String traceId) { + return this; + } + + @Override + public TraceContext.Builder spanId(String spanId) { + return null; + } + + @Override + public TraceContext.Builder sampled(Boolean sampled) { + return this; + } + + @Override + public TraceContext build() { + return new NoOpTraceContext(); + } + +} diff --git a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java index 95a8f281e..08d4d99ea 100644 --- a/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java +++ b/spring-cloud-sleuth-autoconfigure/src/test/java/org/springframework/cloud/sleuth/autoconfig/NoOpTracer.java @@ -69,6 +69,11 @@ class NoOpTracer implements Tracer { return new NoOpSpanBuilder(); } + @Override + public TraceContext.Builder traceContextBuilder() { + return new NoOpTraceContextBuilder(); + } + @Override public Map getAllBaggage() { return new HashMap<>(); diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilder.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilder.java new file mode 100644 index 000000000..0c19ac5b8 --- /dev/null +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilder.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.bridge; + +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.internal.EncodingUtils; + +/** + * Brave implementation of a {@link TraceContext.Builder}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +class BraveTraceContextBuilder implements TraceContext.Builder { + + brave.propagation.TraceContext.Builder delegate = brave.propagation.TraceContext.newBuilder(); + + @Override + public TraceContext.Builder traceId(String traceId) { + long[] fromString = EncodingUtils.fromString(traceId); + if (fromString.length == 2) { + this.delegate.traceIdHigh(fromString[0]); + this.delegate.traceId(fromString[1]); + } + else { + this.delegate.traceId(fromString[0]); + } + return this; + } + + @Override + public TraceContext.Builder parentId(String traceId) { + long[] fromString = EncodingUtils.fromString(traceId); + this.delegate.parentId(fromString[fromString.length == 2 ? 1 : 0]); + return this; + } + + @Override + public TraceContext.Builder spanId(String spanId) { + long[] fromString = EncodingUtils.fromString(spanId); + this.delegate.spanId(fromString[fromString.length == 2 ? 1 : 0]); + return this; + } + + @Override + public TraceContext.Builder sampled(Boolean sampled) { + this.delegate.sampled(sampled); + return this; + } + + @Override + public TraceContext build() { + brave.propagation.TraceContext context = this.delegate.build(); + return BraveTraceContext.fromBrave(context); + } + +} diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java index 5eaa63958..258a5c53b 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/BraveTracer.java @@ -90,6 +90,11 @@ public class BraveTracer implements Tracer { return new BraveSpanBuilder(this.tracer); } + @Override + public TraceContext.Builder traceContextBuilder() { + return new BraveTraceContextBuilder(); + } + @Override public Map getAllBaggage() { return this.braveBaggageManager.getAllBaggage(); diff --git a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java index 0931b52e2..4f8a87207 100644 --- a/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java +++ b/spring-cloud-sleuth-brave/src/main/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagation.java @@ -37,6 +37,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.sleuth.BaggageInScope; +import org.springframework.cloud.sleuth.internal.EncodingUtils; import static java.util.Collections.singletonList; @@ -219,12 +220,12 @@ class W3CPropagation extends Propagation.Factory implements Propagation private static boolean isTraceIdValid(CharSequence traceId) { return (traceId.length() == TRACE_ID_HEX_SIZE) && !INVALID_TRACE_ID.contentEquals(traceId) - && BigendianEncoding.isValidBase16String(traceId); + && EncodingUtils.isValidBase16String(traceId); } private static boolean isSpanIdValid(String spanId) { return (spanId.length() == SPAN_ID_HEX_SIZE) && !INVALID_SPAN_ID.equals(spanId) - && BigendianEncoding.isValidBase16String(spanId); + && EncodingUtils.isValidBase16String(spanId); } private static TraceContext extractContextFromTraceParent(String traceparent) { @@ -257,10 +258,10 @@ class W3CPropagation extends Propagation.Factory implements Propagation String traceIdLow = traceId.substring(traceId.length() / 2); byte isSampled = TraceFlags.byteFromHex(traceparent, TRACE_OPTION_OFFSET); return TraceContext.newBuilder().shared(true) - .traceIdHigh(BigendianEncoding.longFromBase16String(traceIdHigh)) - .traceId(BigendianEncoding.longFromBase16String(traceIdLow)) - .spanId(BigendianEncoding.longFromBase16String(spanId)) - .sampled(isSampled == TraceFlags.IS_SAMPLED).build(); + .traceIdHigh(EncodingUtils.longFromBase16String(traceIdHigh)) + .traceId(EncodingUtils.longFromBase16String(traceIdLow)) + .spanId(EncodingUtils.longFromBase16String(spanId)).sampled(isSampled == TraceFlags.IS_SAMPLED) + .build(); } return null; } @@ -421,41 +422,6 @@ final class TemporaryBuffers { } -/** - * Taken from OpenTelemetry API. - */ -final class Utils { - - private Utils() { - - } - - /** - * Throws an {@link IllegalArgumentException} if the argument is false. This method is - * similar to {@code Preconditions.checkArgument(boolean, Object)} from Guava. - * @param isValid whether the argument check passed. - * @param errorMessage the message to use for the exception. - */ - static void checkArgument(boolean isValid, String errorMessage) { - if (!isValid) { - throw new IllegalArgumentException(errorMessage); - } - } - - /** - * Throws an {@link IllegalStateException} if the argument is false. This method is - * similar to {@code Preconditions.checkState(boolean, Object)} from Guava. - * @param isValid whether the state check passed. - * @param errorMessage the message to use for the exception. - */ - static void checkState(boolean isValid, String errorMessage) { - if (!isValid) { - throw new IllegalStateException(String.valueOf(errorMessage)); - } - } - -} - /** * Taken from OpenTelemetry API. */ @@ -469,131 +435,7 @@ final class TraceFlags { /** Extract the byte representation of the flags from a hex-representation. */ static byte byteFromHex(CharSequence src, int srcOffset) { - return BigendianEncoding.byteFromBase16String(src, srcOffset); - } - -} - -/** - * Taken from OpenTelemetry API. - */ -final class BigendianEncoding { - - private BigendianEncoding() { - } - - static final int LONG_BYTES = Long.SIZE / Byte.SIZE; - - static final int BYTE_BASE16 = 2; - - static final int LONG_BASE16 = BYTE_BASE16 * LONG_BYTES; - - private static final String ALPHABET = "0123456789abcdef"; - - private static final int ASCII_CHARACTERS = 128; - - private static final char[] ENCODING = buildEncodingArray(); - - private static final byte[] DECODING = buildDecodingArray(); - - private static char[] buildEncodingArray() { - char[] encoding = new char[512]; - for (int i = 0; i < 256; ++i) { - encoding[i] = ALPHABET.charAt(i >>> 4); - encoding[i | 0x100] = ALPHABET.charAt(i & 0xF); - } - return encoding; - } - - private static byte[] buildDecodingArray() { - byte[] decoding = new byte[ASCII_CHARACTERS]; - Arrays.fill(decoding, (byte) -1); - for (int i = 0; i < ALPHABET.length(); i++) { - char c = ALPHABET.charAt(i); - decoding[c] = (byte) i; - } - return decoding; - } - - /** - * Returns the {@code long} value whose base16 representation is stored in the first - * 16 chars of {@code chars} starting from the {@code offset}. - * @param chars the base16 representation of the {@code long}. - */ - static long longFromBase16String(CharSequence chars) { - return longFromBase16String(chars, 0); - } - - /** - * Returns the {@code long} value whose base16 representation is stored in the first - * 16 chars of {@code chars} starting from the {@code offset}. - * @param chars the base16 representation of the {@code long}. - */ - static long longFromBase16String(CharSequence chars, int offset) { - Utils.checkArgument(chars.length() >= offset + LONG_BASE16, "chars too small"); - return (decodeByte(chars.charAt(offset), chars.charAt(offset + 1)) & 0xFFL) << 56 - | (decodeByte(chars.charAt(offset + 2), chars.charAt(offset + 3)) & 0xFFL) << 48 - | (decodeByte(chars.charAt(offset + 4), chars.charAt(offset + 5)) & 0xFFL) << 40 - | (decodeByte(chars.charAt(offset + 6), chars.charAt(offset + 7)) & 0xFFL) << 32 - | (decodeByte(chars.charAt(offset + 8), chars.charAt(offset + 9)) & 0xFFL) << 24 - | (decodeByte(chars.charAt(offset + 10), chars.charAt(offset + 11)) & 0xFFL) << 16 - | (decodeByte(chars.charAt(offset + 12), chars.charAt(offset + 13)) & 0xFFL) << 8 - | (decodeByte(chars.charAt(offset + 14), chars.charAt(offset + 15)) & 0xFFL); - } - - /** - * Decodes the specified two character sequence, and returns the resulting - * {@code byte}. - * @param chars the character sequence to be decoded. - * @param offset the starting offset in the {@code CharSequence}. - * @return the resulting {@code byte} - * @throws IllegalArgumentException if the input is not a valid encoded string - * according to this encoding. - */ - static byte byteFromBase16String(CharSequence chars, int offset) { - Utils.checkArgument(chars.length() >= offset + 2, "chars too small"); - return decodeByte(chars.charAt(offset), chars.charAt(offset + 1)); - } - - private static byte decodeByte(char hi, char lo) { - Utils.checkArgument(lo < ASCII_CHARACTERS && DECODING[lo] != -1, "invalid character " + lo); - Utils.checkArgument(hi < ASCII_CHARACTERS && DECODING[hi] != -1, "invalid character " + hi); - int decoded = DECODING[hi] << 4 | DECODING[lo]; - return (byte) decoded; - } - - /** - * Returns the {@code long} value whose big-endian representation is stored in the - * first 8 bytes of {@code bytes} starting from the {@code offset}. - * @param bytes the byte array representation of the {@code long}. - * @param offset the starting offset in the byte array. - * @return the {@code long} value whose big-endian representation is given. - * @throws IllegalArgumentException if {@code bytes} has fewer than 8 elements. - */ - static long longFromByteArray(byte[] bytes, int offset) { - Utils.checkArgument(bytes.length >= offset + LONG_BYTES, "array too small"); - return (bytes[offset] & 0xFFL) << 56 | (bytes[offset + 1] & 0xFFL) << 48 | (bytes[offset + 2] & 0xFFL) << 40 - | (bytes[offset + 3] & 0xFFL) << 32 | (bytes[offset + 4] & 0xFFL) << 24 - | (bytes[offset + 5] & 0xFFL) << 16 | (bytes[offset + 6] & 0xFFL) << 8 | (bytes[offset + 7] & 0xFFL); - } - - static boolean isValidBase16String(CharSequence value) { - for (int i = 0; i < value.length(); i++) { - char b = value.charAt(i); - // 48..57 && 97..102 are valid - if (!isDigit(b) && !isLowercaseHexCharacter(b)) { - return false; - } - } - return true; - } - - private static boolean isLowercaseHexCharacter(char b) { - return 97 <= b && b <= 102; - } - - private static boolean isDigit(char b) { - return 48 <= b && b <= 57; + return EncodingUtils.byteFromBase16String(src, srcOffset); } } diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilderTests.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilderTests.java new file mode 100644 index 000000000..570d6e70a --- /dev/null +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/BraveTraceContextBuilderTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.bridge; + +import org.junit.jupiter.api.Test; + +import org.springframework.cloud.sleuth.TraceContext; + +import static org.assertj.core.api.BDDAssertions.then; + +class BraveTraceContextBuilderTests { + + @Test + void should_set_trace_context_for_64_bit() { + BraveTraceContextBuilder builder = new BraveTraceContextBuilder(); + + TraceContext traceContext = builder.parentId("7c6239a5ad0a4287").spanId("caff89f7f0f229dd") + .traceId("596e1787feb11040").sampled(true).build(); + + then(traceContext.parentId()).isEqualTo("7c6239a5ad0a4287"); + then(traceContext.spanId()).isEqualTo("caff89f7f0f229dd"); + then(traceContext.traceId()).isEqualTo("596e1787feb11040"); + then(traceContext.sampled()).isTrue(); + } + + @Test + void should_set_trace_context_for_128_bit() { + BraveTraceContextBuilder builder = new BraveTraceContextBuilder(); + + TraceContext traceContext = builder.parentId("00000000000000007c6239a5ad0a4287") + .spanId("0000000000000000caff89f7f0f229dd").traceId("596e1787feb11040caff89f7f0f229dd").sampled(true) + .build(); + + then(traceContext.parentId()).isEqualTo("7c6239a5ad0a4287"); + then(traceContext.spanId()).isEqualTo("caff89f7f0f229dd"); + then(traceContext.traceId()).isEqualTo("596e1787feb11040caff89f7f0f229dd"); + then(traceContext.sampled()).isTrue(); + } + +} diff --git a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java index 265e0e76b..7d56613da 100644 --- a/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java +++ b/spring-cloud-sleuth-brave/src/test/java/org/springframework/cloud/sleuth/brave/bridge/W3CPropagationTest.java @@ -27,6 +27,8 @@ import brave.propagation.TraceContext; import brave.propagation.TraceContextOrSamplingFlags; import org.junit.jupiter.api.Test; +import org.springframework.cloud.sleuth.internal.EncodingUtils; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.springframework.cloud.sleuth.brave.bridge.W3CPropagation.TRACE_PARENT; @@ -68,9 +70,9 @@ class W3CPropagationTest { private TraceContext.Builder sampledTraceContext(String traceIdHigh, String traceId, String spanId) { return TraceContext.newBuilder().sampled(SAMPLED_TRACE_OPTIONS) - .traceIdHigh(BigendianEncoding.longFromBase16String(traceIdHigh)) - .traceId(BigendianEncoding.longFromBase16String(traceId)) - .spanId(BigendianEncoding.longFromBase16String(spanId)); + .traceIdHigh(EncodingUtils.longFromBase16String(traceIdHigh)) + .traceId(EncodingUtils.longFromBase16String(traceId)) + .spanId(EncodingUtils.longFromBase16String(spanId)); } @Test diff --git a/spring-cloud-sleuth-instrumentation/pom.xml b/spring-cloud-sleuth-instrumentation/pom.xml index 0dfdf55a4..3b2d48a01 100644 --- a/spring-cloud-sleuth-instrumentation/pom.xml +++ b/spring-cloud-sleuth-instrumentation/pom.xml @@ -42,6 +42,11 @@ spring-boot-starter-web true + + org.springframework.boot + spring-boot-starter-rsocket + true + io.micrometer micrometer-core @@ -52,6 +57,11 @@ reactor-core true + + io.rsocket + rsocket-core + true + io.projectreactor.kafka reactor-kafka diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java index 0d11b88f9..6be996c8d 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspect.java @@ -62,6 +62,7 @@ public class TraceAsyncAspect { } span = span.name(spanName); try (Tracer.SpanInScope ws = this.tracer.withSpan(span.start())) { + // TODO: Make this less generic span.tag(CLASS_KEY, pjp.getTarget().getClass().getSimpleName()); span.tag(METHOD_KEY, pjp.getSignature().getName()); return pjp.proceed(); diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java index 9c3a0cc91..52d02ffb3 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessageHandler.java @@ -191,12 +191,6 @@ class TraceMessageHandler { } } - private void addTags(Span result, String destinationName) { - if (StringUtils.hasText(destinationName)) { - result.tag("channel", SpanNameUtil.shorten(destinationName)); - } - } - /** * Called either when message got received and processed or message got sent. * @param span - span that corresponds to the given operation diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java new file mode 100644 index 000000000..fda6d71bd --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java @@ -0,0 +1,100 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.messaging; + +import java.lang.reflect.Method; + +import org.apache.commons.logging.Log; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.SpanNameUtil; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.util.ReflectionUtils; + +/** + * Aspect that wraps {@link MessageMapping} annotated methods in a tracing representation. + * + * TODO: Document that for client side responders declare them as beans + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +@SuppressWarnings("ArgNamesWarningsInspection") +@Aspect +public class TraceMessagingAspect { + + private static final Log log = org.apache.commons.logging.LogFactory.getLog(TraceMessagingAspect.class); + + static final String MESSAGING_CONTROLLER_CLASS_KEY = "messaging.controller.class"; + + static final String MESSAGING_CONTROLLER_METHOD_KEY = "messaging.controller.method"; + + private final Tracer tracer; + + private final SpanNamer spanNamer; + + public TraceMessagingAspect(Tracer tracer, SpanNamer spanNamer) { + this.tracer = tracer; + this.spanNamer = spanNamer; + } + + @Pointcut("@within(org.springframework.messaging.handler.annotation.MessageMapping)") + private void anyMessageMappingAnnotated() { + } // NOSONAR + + @Around("anyMessageMappingAnnotated()") + @SuppressWarnings("unchecked") + public Object addTags(ProceedingJoinPoint pjp) throws Throwable { + Object object = pjp.proceed(); + String methodName = pjp.getSignature().getName(); + String className = pjp.getTarget().getClass().getName(); + Span currentSpan = currentSpan(pjp); + currentSpan.tag(MESSAGING_CONTROLLER_CLASS_KEY, className); + currentSpan.tag(MESSAGING_CONTROLLER_METHOD_KEY, methodName); + return object; + } + + private Span currentSpan(ProceedingJoinPoint pjp) { + Span currentSpan = this.tracer.currentSpan(); + if (currentSpan == null) { + if (log.isDebugEnabled()) { + log.debug("No span found - will create a new one"); + } + currentSpan = this.tracer.nextSpan().name(name(pjp)).start(); + } + return currentSpan; + } + + private String name(ProceedingJoinPoint pjp) { + return this.spanNamer.name(getMethod(pjp, pjp.getTarget()), + SpanNameUtil.toLowerHyphen(pjp.getSignature().getName())); + } + + private Method getMethod(ProceedingJoinPoint pjp, Object object) { + MethodSignature signature = (MethodSignature) pjp.getSignature(); + Method method = signature.getMethod(); + return ReflectionUtils.findMethod(object.getClass(), method.getName(), method.getParameterTypes()); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java index ed9d3780d..9ee309081 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java @@ -26,9 +26,9 @@ import org.apache.commons.logging.LogFactory; import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.SpanAndScope; import org.springframework.cloud.sleuth.ThreadLocalSpan; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.WithThreadLocalSpan; import org.springframework.cloud.sleuth.propagation.Propagator; import org.springframework.cloud.stream.binder.BinderType; import org.springframework.cloud.stream.binder.BinderTypeRegistry; @@ -58,7 +58,7 @@ import org.springframework.util.StringUtils; * @since 3.0.0 */ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter - implements ExecutorChannelInterceptor, ApplicationContextAware { + implements ExecutorChannelInterceptor, ApplicationContextAware, WithThreadLocalSpan { /** * Name of the class in Spring Cloud Stream that is a direct channel. @@ -163,13 +163,6 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter return outputMessage; } - private void setSpanInScope(Span span) { - this.threadLocalSpan.set(span); - if (log.isDebugEnabled()) { - log.debug("Put span in scope " + span); - } - } - private String toRemoteServiceName(MessageHeaderAccessor headers) { for (String key : headers.getMessageHeaders().keySet()) { String remoteServiceName = this.remoteServiceNameMapper.apply(key); @@ -357,41 +350,9 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter finishSpan(ex); } - void finishSpan(Exception error) { - SpanAndScope spanAndScope = getSpanFromThreadLocal(); - if (spanAndScope == null) { - return; - } - Span span = spanAndScope.getSpan(); - Tracer.SpanInScope scope = spanAndScope.getScope(); - if (span.isNoop()) { - if (log.isDebugEnabled()) { - log.debug("Span " + span + " is noop - will stope the scope"); - } - scope.close(); - return; - } - if (error != null) { // an error occurred, adding error to span - String message = error.getMessage(); - if (message == null) { - message = error.getClass().getSimpleName(); - } - span.tag("error", message); - } - if (log.isDebugEnabled()) { - log.debug("Will finish the and its corresponding scope " + span); - } - span.end(); - scope.close(); - } - - private SpanAndScope getSpanFromThreadLocal() { - SpanAndScope span = this.threadLocalSpan.get(); - if (log.isDebugEnabled()) { - log.debug("Took span [" + span + "] from thread local"); - } - this.threadLocalSpan.remove(); - return span; + @Override + public ThreadLocalSpan getThreadLocalSpan() { + return this.threadLocalSpan; } private MessageHeaderAccessor mutableHeaderAccessor(Message message) { diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java index dabadd1a3..02d870027 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/reactor/ReactorSleuth.java @@ -334,15 +334,26 @@ public abstract class ReactorSleuth { public static Mono tracedMono(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, @NonNull String childSpanName, @NonNull Supplier> supplier, @NonNull Consumer spanCustomizer) { + return runMonoSupplierInScope(supplier, spanCustomizer).contextWrite( + context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + } + + private static Mono runMonoSupplierInScope(Supplier> supplier, Consumer spanCustomizer) { return Mono.deferContextual(contextView -> { Span span = contextView.get(Span.class); spanCustomizer.accept(span); Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); - return supplier.get().doOnError(span::error).doFinally(signalType -> { - span.end(); - scope.close(); - }); - }).contextWrite(context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + // @formatter:off + return supplier.get() + // TODO: Fix me when this is resolved in Reactor +// .doOnSubscribe(__ -> scope.close()) + .doOnError(span::error) + .doFinally(signalType -> { + span.end(); + scope.close(); + }); + // @formatter:on + }); } /** @@ -361,6 +372,20 @@ public abstract class ReactorSleuth { }); } + /** + * Wraps the given Mono in a trace representation. Puts the provided span to context. + * @param tracer - Tracer bean + * @param span - span to put in context + * @param supplier - supplier of a {@link Mono} to be wrapped in tracing + * @param - type returned by the Mono + * @return traced Mono + */ + public static Mono tracedMono(@NonNull Tracer tracer, @NonNull Span span, + @NonNull Supplier> supplier) { + return runMonoSupplierInScope(supplier, span1 -> { + }).contextWrite(context -> ReactorSleuth.putSpanInScope(tracer, context, span)); + } + /** * Wraps the given Flux in a trace representation. Retrieves the span from context, * creates a child span with the given name. @@ -375,15 +400,41 @@ public abstract class ReactorSleuth { public static Flux tracedFlux(@NonNull Tracer tracer, @NonNull CurrentTraceContext currentTraceContext, @NonNull String childSpanName, @NonNull Supplier> supplier, @NonNull Consumer spanCustomizer) { + return runFluxSupplierInScope(supplier, spanCustomizer).contextWrite( + context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + } + + /** + * Wraps the given Flux in a trace representation. Retrieves the span from context, + * creates a child span with the given name. + * @param tracer - Tracer bean + * @param span - span to put in context + * @param supplier - supplier of a {@link Flux} to be wrapped in tracing + * @param - type returned by the Flux + * @return traced Flux + */ + public static Flux tracedFlux(@NonNull Tracer tracer, @NonNull Span span, + @NonNull Supplier> supplier) { + return runFluxSupplierInScope(supplier, span1 -> { + }).contextWrite(context -> ReactorSleuth.putSpanInScope(tracer, context, span)); + } + + private static Flux runFluxSupplierInScope(Supplier> supplier, Consumer spanCustomizer) { return Flux.deferContextual(contextView -> { Span span = contextView.get(Span.class); spanCustomizer.accept(span); Tracer.SpanInScope scope = contextView.get(Tracer.SpanInScope.class); - return supplier.get().doOnError(span::error).doFinally(signalType -> { - span.end(); - scope.close(); - }); - }).contextWrite(context -> ReactorSleuth.enhanceContext(tracer, currentTraceContext, context, childSpanName)); + // @formatter:off + return supplier.get() + // TODO: Fix me when this is resolved in Reactor +// .doOnSubscribe(__ -> scope.close()) + .doOnError(span::error) + .doFinally(signalType -> { + span.end(); + scope.close(); + }); + // @formatter:on + }); } /** @@ -442,6 +493,10 @@ public abstract class ReactorSleuth { private static Context enhanceContext(Tracer tracer, CurrentTraceContext currentTraceContext, reactor.util.context.Context context, String childSpanName) { Span span = spanFromContext(tracer, currentTraceContext, context, childSpanName); + return putSpanInScope(tracer, context, span); + } + + private static Context putSpanInScope(Tracer tracer, Context context, Span span) { return context.put(Span.class, span).put(TraceContext.class, span.context()).put(Tracer.SpanInScope.class, tracer.withSpan(span)); } diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufGetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufGetter.java new file mode 100644 index 000000000..167af1865 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufGetter.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import io.netty.buffer.ByteBuf; +import io.netty.util.CharsetUtil; +import io.rsocket.metadata.CompositeMetadata; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +class ByteBufGetter implements Propagator.Getter { + + @Override + public String get(ByteBuf carrier, String key) { + final CompositeMetadata compositeMetadata = new CompositeMetadata(carrier, false); + for (CompositeMetadata.Entry entry : compositeMetadata) { + if (key.equals(entry.getMimeType())) { + return entry.getContent().toString(CharsetUtil.UTF_8); + } + } + return null; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufSetter.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufSetter.java new file mode 100644 index 000000000..e44a77de7 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/ByteBufSetter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.CompositeByteBuf; +import io.rsocket.metadata.CompositeMetadataCodec; + +import org.springframework.cloud.sleuth.propagation.Propagator; + +class ByteBufSetter implements Propagator.Setter { + + @Override + public void set(CompositeByteBuf carrier, String key, String value) { + final ByteBufAllocator alloc = carrier.alloc(); + CompositeMetadataCodec.encodeAndAddMetadataWithCompression(carrier, alloc, key, + ByteBufUtil.writeUtf8(alloc, value)); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/CompositeMetadataUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/CompositeMetadataUtils.java new file mode 100644 index 000000000..5bc960a3e --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/CompositeMetadataUtils.java @@ -0,0 +1,42 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import io.netty.buffer.ByteBuf; +import io.rsocket.metadata.CompositeMetadata; + +import org.springframework.lang.Nullable; + +final class CompositeMetadataUtils { + + private CompositeMetadataUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + @Nullable + static ByteBuf extract(ByteBuf metadata, String key) { + final CompositeMetadata compositeMetadata = new CompositeMetadata(metadata, false); + for (CompositeMetadata.Entry entry : compositeMetadata) { + final String entryKey = entry.getMimeType(); + if (key.equals(entryKey)) { + return entry.getContent(); + } + } + return null; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/PayloadUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/PayloadUtils.java new file mode 100644 index 000000000..17363acc4 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/PayloadUtils.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import java.util.HashSet; +import java.util.Set; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.CompositeByteBuf; +import io.rsocket.Payload; +import io.rsocket.metadata.CompositeMetadata; +import io.rsocket.metadata.CompositeMetadata.Entry; +import io.rsocket.metadata.CompositeMetadataCodec; +import io.rsocket.metadata.WellKnownMimeType; +import io.rsocket.util.ByteBufPayload; +import io.rsocket.util.DefaultPayload; + +final class PayloadUtils { + + private PayloadUtils() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + static Payload cleanTracingMetadata(Payload payload, Set fields) { + Set fieldsWithDefaultZipkin = new HashSet<>(fields); + fieldsWithDefaultZipkin.add(WellKnownMimeType.MESSAGE_RSOCKET_TRACING_ZIPKIN.getString()); + final CompositeMetadata entries = new CompositeMetadata(payload.metadata(), true); + final CompositeByteBuf metadata = ByteBufAllocator.DEFAULT.compositeBuffer(); + for (Entry entry : entries) { + if (!fieldsWithDefaultZipkin.contains(entry.getMimeType())) { + CompositeMetadataCodec.encodeAndAddMetadataWithCompression(metadata, ByteBufAllocator.DEFAULT, + entry.getMimeType(), entry.getContent()); + } + } + return payload(payload, metadata); + } + + private static Payload payload(Payload payload, CompositeByteBuf metadata) { + final Payload newPayload; + try { + if (payload instanceof ByteBufPayload) { + newPayload = ByteBufPayload.create(payload.data().retain(), metadata.retain()); + } + else { + newPayload = DefaultPayload.create(payload.data().retain(), metadata.retain()); + } + } + finally { + payload.release(); + } + return newPayload; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketConnectorConfigurer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketConnectorConfigurer.java new file mode 100644 index 000000000..b172c0640 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketConnectorConfigurer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import io.rsocket.core.RSocketConnector; +import io.rsocket.plugins.RSocketInterceptor; + +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; +import org.springframework.messaging.rsocket.RSocketConnectorConfigurer; + +public class TracingRSocketConnectorConfigurer implements RSocketConnectorConfigurer { + + private final Propagator propagator; + + private final Tracer tracer; + + private final boolean isZipkinPropagationEnabled; + + public TracingRSocketConnectorConfigurer(Propagator propagator, Tracer tracer, boolean isZipkinPropagationEnabled) { + this.propagator = propagator; + this.tracer = tracer; + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public void configure(RSocketConnector rSocketConnector) { + rSocketConnector.interceptors(ir -> ir + .forResponder((RSocketInterceptor) rSocket -> new TracingResponderRSocketProxy(rSocket, this.propagator, + new ByteBufGetter(), this.tracer, this.isZipkinPropagationEnabled)) + .forRequester((RSocketInterceptor) rSocket -> new TracingRequesterRSocketProxy(rSocket, this.propagator, + new ByteBufSetter(), this.tracer, this.isZipkinPropagationEnabled))); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketServerCustomizer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketServerCustomizer.java new file mode 100644 index 000000000..809671eec --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRSocketServerCustomizer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import io.rsocket.core.RSocketServer; +import io.rsocket.plugins.RSocketInterceptor; + +import org.springframework.boot.rsocket.server.RSocketServerCustomizer; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.propagation.Propagator; + +public class TracingRSocketServerCustomizer implements RSocketServerCustomizer { + + private final Propagator propagator; + + private final Tracer tracer; + + private final boolean isZipkinPropagationEnabled; + + public TracingRSocketServerCustomizer(Propagator propagator, Tracer tracer, boolean isZipkinPropagationEnabled) { + this.propagator = propagator; + this.tracer = tracer; + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public void customize(RSocketServer rSocketServer) { + rSocketServer.interceptors(ir -> ir + .forResponder((RSocketInterceptor) rSocket -> new TracingResponderRSocketProxy(rSocket, propagator, + new ByteBufGetter(), this.tracer, this.isZipkinPropagationEnabled)) + .forRequester((RSocketInterceptor) rSocket -> new TracingRequesterRSocketProxy(rSocket, propagator, + new ByteBufSetter(), tracer, isZipkinPropagationEnabled))); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRequesterRSocketProxy.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRequesterRSocketProxy.java new file mode 100644 index 000000000..31d0b9a96 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingRequesterRSocketProxy.java @@ -0,0 +1,168 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.function.Function; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.CompositeByteBuf; +import io.rsocket.Payload; +import io.rsocket.RSocket; +import io.rsocket.frame.FrameType; +import io.rsocket.metadata.RoutingMetadata; +import io.rsocket.metadata.TracingMetadataCodec; +import io.rsocket.metadata.WellKnownMimeType; +import io.rsocket.util.RSocketProxy; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.internal.EncodingUtils; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Tracing representation of a {@link RSocketProxy} for the requester. + * + * @author Marcin Grzejszczak + * @author Oleh Dokuka + * @since 3.1.0 + */ +public class TracingRequesterRSocketProxy extends RSocketProxy { + + private static final Log log = LogFactory.getLog(TracingRequesterRSocketProxy.class); + + private final Propagator propagator; + + private final Propagator.Setter setter; + + private final Tracer tracer; + + private final boolean isZipkinPropagationEnabled; + + public TracingRequesterRSocketProxy(RSocket source, Propagator propagator, + Propagator.Setter setter, Tracer tracer, boolean isZipkinPropagationEnabled) { + super(source); + this.propagator = propagator; + this.setter = setter; + this.tracer = tracer; + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public Mono fireAndForget(Payload payload) { + return setSpan(super::fireAndForget, payload, FrameType.REQUEST_FNF); + } + + @Override + public Mono requestResponse(Payload payload) { + return setSpan(super::requestResponse, payload, FrameType.REQUEST_RESPONSE); + } + + Mono setSpan(Function> input, Payload payload, FrameType frameType) { + return Mono.deferContextual(contextView -> { + Span.Builder spanBuilder = spanBuilder(contextView); + ByteBuf extracted = CompositeMetadataUtils.extract(payload.sliceMetadata(), + WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString()); + // TODO: do sth about extracted == null, log that tracing can't be used or sth + final RoutingMetadata routingMetadata = new RoutingMetadata(extracted); + final Iterator iterator = routingMetadata.iterator(); + String route = iterator.next(); + Span span = spanBuilder.kind(Span.Kind.PRODUCER).name(frameType.name() + " " + route).start(); + span.tag("rsocket.route", route); + span.tag("rsocket.request-type", frameType.name()); + if (log.isDebugEnabled()) { + log.debug("Extracted result from context or thread local " + span); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + TraceContext traceContext = span.context(); + if (this.isZipkinPropagationEnabled) { + injectDefaultZipkinRSocketHeaders(newPayload, traceContext); + } + this.propagator.inject(traceContext, (CompositeByteBuf) newPayload.metadata(), this.setter); + return input.apply(newPayload).doOnError(span::error).doFinally(signalType -> span.end()); + }); + } + + private void injectDefaultZipkinRSocketHeaders(Payload newPayload, TraceContext traceContext) { + TracingMetadataCodec.Flags flags = traceContext.sampled() == null ? TracingMetadataCodec.Flags.UNDECIDED + : traceContext.sampled() ? TracingMetadataCodec.Flags.SAMPLE : TracingMetadataCodec.Flags.NOT_SAMPLE; + String traceId = traceContext.traceId(); + long[] traceIds = EncodingUtils.fromString(traceId); + long[] spanId = EncodingUtils.fromString(traceContext.spanId()); + long[] parentSpanId = EncodingUtils.fromString(traceContext.parentId()); + boolean isTraceId128Bit = traceIds.length == 2; + if (isTraceId128Bit) { + TracingMetadataCodec.encode128(newPayload.metadata().alloc(), traceIds[0], traceIds[1], spanId[0], + EncodingUtils.fromString(traceContext.parentId())[0], flags); + } + else { + TracingMetadataCodec.encode64(newPayload.metadata().alloc(), traceIds[0], spanId[0], parentSpanId[0], + flags); + } + } + + private Span.Builder spanBuilder(ContextView contextView) { + Span.Builder spanBuilder = this.tracer.spanBuilder(); + if (contextView.hasKey(TraceContext.class)) { + spanBuilder = spanBuilder.setParent(contextView.get(TraceContext.class)); + } + else if (this.tracer.currentSpan() != null) { + spanBuilder = spanBuilder.setParent(this.tracer.currentSpan().context()); + } + return spanBuilder; + } + + @Override + public Flux requestStream(Payload payload) { + return Flux.deferContextual(contextView -> setSpan(super::requestStream, payload, contextView)); + } + + @Override + public Flux requestChannel(Publisher inbound) { + return Flux.from(inbound).switchOnFirst((firstSignal, flux) -> { + final Payload firstPayload = firstSignal.get(); + if (firstPayload != null) { + return setSpan(p -> super.requestChannel(flux.skip(1).startWith(p)), firstPayload, + firstSignal.getContextView()); + } + return flux; + }); + } + + Flux setSpan(Function> input, Payload payload, ContextView contextView) { + Span.Builder spanBuilder = spanBuilder(contextView); + final RoutingMetadata routingMetadata = new RoutingMetadata(CompositeMetadataUtils + .extract(payload.sliceMetadata(), WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString())); + final Iterator iterator = routingMetadata.iterator(); + Span span = spanBuilder.kind(Span.Kind.PRODUCER).name(iterator.next()).start(); + if (log.isDebugEnabled()) { + log.debug("Extracted result from context or thread local " + span); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + this.propagator.inject(span.context(), (CompositeByteBuf) newPayload.metadata(), this.setter); + return input.apply(newPayload).doOnError(span::error).doFinally(signalType -> span.end()); + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingResponderRSocketProxy.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingResponderRSocketProxy.java new file mode 100644 index 000000000..b75a4aff9 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TracingResponderRSocketProxy.java @@ -0,0 +1,170 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import java.util.HashSet; +import java.util.Iterator; + +import io.netty.buffer.ByteBuf; +import io.rsocket.Payload; +import io.rsocket.RSocket; +import io.rsocket.frame.FrameType; +import io.rsocket.metadata.RoutingMetadata; +import io.rsocket.metadata.TracingMetadata; +import io.rsocket.metadata.TracingMetadataCodec; +import io.rsocket.metadata.WellKnownMimeType; +import io.rsocket.util.RSocketProxy; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.ThreadLocalSpan; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.WithThreadLocalSpan; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; +import org.springframework.cloud.sleuth.internal.EncodingUtils; +import org.springframework.cloud.sleuth.propagation.Propagator; + +/** + * Tracing representation of a {@link RSocketProxy} for the responder. + * + * @author Marcin Grzejszczak + * @author Oleh Dokuka + * @since 3.1.0 + */ +public class TracingResponderRSocketProxy extends RSocketProxy implements WithThreadLocalSpan { + + private static final Log log = LogFactory.getLog(TracingResponderRSocketProxy.class); + + private final Propagator propagator; + + private final Propagator.Getter getter; + + private final Tracer tracer; + + private final ThreadLocalSpan threadLocalSpan; + + private final boolean isZipkinPropagationEnabled; + + public TracingResponderRSocketProxy(RSocket source, Propagator propagator, Propagator.Getter getter, + Tracer tracer, boolean isZipkinPropagationEnabled) { + super(source); + this.propagator = propagator; + this.getter = getter; + this.tracer = tracer; + this.threadLocalSpan = new ThreadLocalSpan(tracer); + this.isZipkinPropagationEnabled = isZipkinPropagationEnabled; + } + + @Override + public Mono fireAndForget(Payload payload) { + // called on Netty EventLoop + // there can't be trace context in thread local here + Span handle = consumerSpanBuilder(payload.sliceMetadata(), FrameType.REQUEST_FNF); + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedMono(this.tracer, handle, () -> super.fireAndForget(newPayload)); + } + + @Override + public Mono requestResponse(Payload payload) { + Span handle = consumerSpanBuilder(payload.sliceMetadata(), FrameType.REQUEST_RESPONSE); + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedMono(this.tracer, handle, () -> super.requestResponse(newPayload)); + } + + @Override + public Flux requestStream(Payload payload) { + Span handle = consumerSpanBuilder(payload.sliceMetadata(), FrameType.REQUEST_STREAM); + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(payload, new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedFlux(this.tracer, handle, () -> super.requestStream(newPayload)); + } + + @Override + public Flux requestChannel(Publisher payloads) { + return Flux.from(payloads).switchOnFirst((firstSignal, flux) -> { + final Payload firstPayload = firstSignal.get(); + if (firstPayload != null) { + Span handle = consumerSpanBuilder(firstPayload.sliceMetadata(), FrameType.REQUEST_CHANNEL); + if (handle == null) { + return super.requestChannel(flux); + } + if (log.isDebugEnabled()) { + log.debug("Created consumer span " + handle); + } + final Payload newPayload = PayloadUtils.cleanTracingMetadata(firstPayload, + new HashSet<>(propagator.fields())); + return ReactorSleuth.tracedFlux(this.tracer, handle, + () -> super.requestChannel(flux.skip(1).startWith(newPayload))); + } + return flux; + }); + } + + private Span consumerSpanBuilder(ByteBuf headers, FrameType requestType) { + Span.Builder consumerSpanBuilder = consumerSpanBuilder(headers); + if (log.isDebugEnabled()) { + log.debug("Extracted result from headers " + consumerSpanBuilder); + } + final ByteBuf extract = CompositeMetadataUtils.extract(headers, + WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString()); + String name = "handle"; + if (extract != null) { + final RoutingMetadata routingMetadata = new RoutingMetadata(extract); + final Iterator iterator = routingMetadata.iterator(); + name = requestType.name() + " " + iterator.next(); + } + return consumerSpanBuilder.kind(Span.Kind.CONSUMER).name(name).start(); + } + + private Span.Builder consumerSpanBuilder(ByteBuf headers) { + if (this.isZipkinPropagationEnabled) { + ByteBuf extract = CompositeMetadataUtils.extract(headers, + WellKnownMimeType.MESSAGE_RSOCKET_TRACING_ZIPKIN.getString()); + if (extract != null) { + TracingMetadata tracingMetadata = TracingMetadataCodec.decode(extract); + Span.Builder builder = this.tracer.spanBuilder(); + TraceContext.Builder parentBuilder = this.tracer.traceContextBuilder() + .sampled(tracingMetadata.isSampled()).traceId(EncodingUtils.fromLong(tracingMetadata.traceId())) + .parentId(EncodingUtils.fromLong(tracingMetadata.parentId())); + return builder.setParent(parentBuilder.build()); + } + else { + return this.propagator.extract(headers, this.getter); + } + } + return this.propagator.extract(headers, this.getter); + } + + @Override + public ThreadLocalSpan getThreadLocalSpan() { + return this.threadLocalSpan; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/EncodingUtils.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/EncodingUtils.java new file mode 100644 index 000000000..f1fcf6f82 --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/internal/EncodingUtils.java @@ -0,0 +1,322 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.internal; + +import java.util.Arrays; + +import org.springframework.util.Assert; + +/** + * Adopted from OpenTelemetry API. + * + * @since 3.1.0 + */ +public final class EncodingUtils { + + private static final ThreadLocal charBuffer = new ThreadLocal(); + + private EncodingUtils() { + } + + static final int LONG_BYTES = Long.SIZE / Byte.SIZE; + + static final int BYTE_BASE16 = 2; + + static final int LONG_BASE16 = BYTE_BASE16 * LONG_BYTES; + + private static final String ALPHABET = "0123456789abcdef"; + + private static final int ASCII_CHARACTERS = 128; + + private static final char[] ENCODING = buildEncodingArray(); + + private static final byte[] DECODING = buildDecodingArray(); + + private static char[] buildEncodingArray() { + char[] encoding = new char[512]; + for (int i = 0; i < 256; ++i) { + encoding[i] = ALPHABET.charAt(i >>> 4); + encoding[i | 0x100] = ALPHABET.charAt(i & 0xF); + } + return encoding; + } + + private static byte[] buildDecodingArray() { + byte[] decoding = new byte[ASCII_CHARACTERS]; + Arrays.fill(decoding, (byte) -1); + for (int i = 0; i < ALPHABET.length(); i++) { + char c = ALPHABET.charAt(i); + decoding[c] = (byte) i; + } + return decoding; + } + + /** + * Returns the {@code long} value. + * @param chars the base8 or base16 representation of the {@code long}. + * @return long array from string. Either contains high and low or just low trace id + */ + public static long[] fromString(CharSequence chars) { + if (chars == null || chars.length() == 0) { + return new long[] { 0 }; + } + if (chars.length() == 32) { + long high = HexCodec.lenientLowerHexToUnsignedLong(chars, 0, 16); + long low = HexCodec.lenientLowerHexToUnsignedLong(chars, 16, 32); + return new long[] { high, low }; + } + return new long[] { HexCodec.lenientLowerHexToUnsignedLong(chars, 0, 16) }; + } + + /** + * Returns the {@code long} value whose base16 representation is stored in the first + * 16 chars of {@code chars} starting from the {@code offset}. + * @param chars the base16 representation of the {@code long}. + * @return long value from string + */ + public static long longFromBase16String(CharSequence chars) { + return longFromBase16String(chars, 0); + } + + /** + * Returns the {@code long} value whose base16 representation is stored in the first + * 16 chars of {@code chars} starting from the {@code offset}. + * @param chars the base16 representation of the {@code long}. + */ + static long longFromBase16String(CharSequence chars, int offset) { + Assert.isTrue(chars.length() >= offset + LONG_BASE16, "chars too small"); + return (decodeByte(chars.charAt(offset), chars.charAt(offset + 1)) & 0xFFL) << 56 + | (decodeByte(chars.charAt(offset + 2), chars.charAt(offset + 3)) & 0xFFL) << 48 + | (decodeByte(chars.charAt(offset + 4), chars.charAt(offset + 5)) & 0xFFL) << 40 + | (decodeByte(chars.charAt(offset + 6), chars.charAt(offset + 7)) & 0xFFL) << 32 + | (decodeByte(chars.charAt(offset + 8), chars.charAt(offset + 9)) & 0xFFL) << 24 + | (decodeByte(chars.charAt(offset + 10), chars.charAt(offset + 11)) & 0xFFL) << 16 + | (decodeByte(chars.charAt(offset + 12), chars.charAt(offset + 13)) & 0xFFL) << 8 + | (decodeByte(chars.charAt(offset + 14), chars.charAt(offset + 15)) & 0xFFL); + } + + /** + * Decodes the specified two character sequence, and returns the resulting + * {@code byte}. + * @param chars the character sequence to be decoded. + * @param offset the starting offset in the {@code CharSequence}. + * @return the resulting {@code byte} + * @throws IllegalArgumentException if the input is not a valid encoded string + * according to this encoding. + */ + public static byte byteFromBase16String(CharSequence chars, int offset) { + Assert.isTrue(chars.length() >= offset + 2, "chars too small"); + return decodeByte(chars.charAt(offset), chars.charAt(offset + 1)); + } + + private static byte decodeByte(char hi, char lo) { + Assert.isTrue(lo < ASCII_CHARACTERS && DECODING[lo] != -1, "invalid character " + lo); + Assert.isTrue(hi < ASCII_CHARACTERS && DECODING[hi] != -1, "invalid character " + hi); + int decoded = DECODING[hi] << 4 | DECODING[lo]; + return (byte) decoded; + } + + /** + * Checks if string is valid base16. + * @param value to check + * @return {@code true} if valid base16 string + */ + public static boolean isValidBase16String(CharSequence value) { + for (int i = 0; i < value.length(); i++) { + char b = value.charAt(i); + // 48..57 && 97..102 are valid + if (!isDigit(b) && !isLowercaseHexCharacter(b)) { + return false; + } + } + return true; + } + + /** + * Converts long into string. + * @param id 64 bit + * @return string representation of the long + */ + public static String fromLong(long id) { + return fromLongs(0, id); + } + + /** + * Converts longs into string. + * @param idHigh - trace id high part + * @param idLow - trace id low part + * @return string representation of the long + */ + public static String fromLongs(long idHigh, long idLow) { + if (idHigh == 0L) { + return HexCodec.toLowerHex(idLow); + } + else { + char[] chars = getTemporaryBuffer(); + longToBase16String(idHigh, chars, 0); + longToBase16String(idLow, chars, 16); + return new String(chars); + } + } + + public static void longToBase16String(long value, char[] dest, int destOffset) { + byteToBase16((byte) ((int) (value >> 56 & 255L)), dest, destOffset); + byteToBase16((byte) ((int) (value >> 48 & 255L)), dest, destOffset + 2); + byteToBase16((byte) ((int) (value >> 40 & 255L)), dest, destOffset + 4); + byteToBase16((byte) ((int) (value >> 32 & 255L)), dest, destOffset + 6); + byteToBase16((byte) ((int) (value >> 24 & 255L)), dest, destOffset + 8); + byteToBase16((byte) ((int) (value >> 16 & 255L)), dest, destOffset + 10); + byteToBase16((byte) ((int) (value >> 8 & 255L)), dest, destOffset + 12); + byteToBase16((byte) ((int) (value & 255L)), dest, destOffset + 14); + } + + public static void byteToBase16(byte value, char[] dest, int destOffset) { + int b = value & 255; + dest[destOffset] = ENCODING[b]; + dest[destOffset + 1] = ENCODING[b | 256]; + } + + private static char[] getTemporaryBuffer() { + char[] chars = charBuffer.get(); + if (chars == null) { + chars = new char[32]; + charBuffer.set(chars); + } + return chars; + } + + private static boolean isLowercaseHexCharacter(char b) { + return 97 <= b && b <= 102; + } + + private static boolean isDigit(char b) { + return 48 <= b && b <= 57; + } + +} + +// taken from brave.internal.codec.HexCodec +final class HexCodec { + + private HexCodec() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + /** + * Parses a 16 character lower-hex string with no prefix into an unsigned long, + * starting at the specified index. + * + * This reads a trace context a sequence potentially larger than the format. The + * use-case is reducing garbage, by re-using the input {@code value} across multiple + * parse operations. + * @param value the sequence that contains a lower-hex encoded unsigned long. + * @param beginIndex the inclusive begin index: {@linkplain CharSequence#charAt(int) + * index} of the first lower-hex character representing the unsigned long. + */ + static long lowerHexToUnsignedLong(CharSequence value, int beginIndex) { + int endIndex = Math.min(beginIndex + 16, value.length()); + long result = lenientLowerHexToUnsignedLong(value, beginIndex, endIndex); + if (result == 0) { + throw isntLowerHexLong(value); + } + return result; + } + + /** + * Like {@link #lowerHexToUnsignedLong(CharSequence, int)}, but returns zero on + * invalid input. + * @param value the sequence that contains a lower-hex encoded unsigned long. + * @param beginIndex the inclusive begin index: {@linkplain CharSequence#charAt(int) + * index} of the first lower-hex character representing the unsigned long. + * @param endIndex the exclusive end index: {@linkplain CharSequence#charAt(int) + * index} after the last lower-hex character representing the unsigned long. + */ + static long lenientLowerHexToUnsignedLong(CharSequence value, int beginIndex, int endIndex) { + long result = 0; + int pos = beginIndex; + while (pos < endIndex) { + char c = value.charAt(pos++); + result <<= 4; + if (c >= '0' && c <= '9') { + result |= c - '0'; + } + else if (c >= 'a' && c <= 'f') { + result |= c - 'a' + 10; + } + else { + return 0; + } + } + return result; + } + + static NumberFormatException isntLowerHexLong(CharSequence lowerHex) { + throw new NumberFormatException(lowerHex + " should be a 1 to 32 character lower-hex string with no prefix"); + } + + /** Inspired by {@code okio.Buffer.writeLong}. */ + static String toLowerHex(long v) { + char[] data = RecyclableBuffers.parseBuffer(); + writeHexLong(data, 0, v); + return new String(data, 0, 16); + } + + /** Inspired by {@code okio.Buffer.writeLong}. */ + static void writeHexLong(char[] data, int pos, long v) { + writeHexByte(data, pos + 0, (byte) ((v >>> 56L) & 0xff)); + writeHexByte(data, pos + 2, (byte) ((v >>> 48L) & 0xff)); + writeHexByte(data, pos + 4, (byte) ((v >>> 40L) & 0xff)); + writeHexByte(data, pos + 6, (byte) ((v >>> 32L) & 0xff)); + writeHexByte(data, pos + 8, (byte) ((v >>> 24L) & 0xff)); + writeHexByte(data, pos + 10, (byte) ((v >>> 16L) & 0xff)); + writeHexByte(data, pos + 12, (byte) ((v >>> 8L) & 0xff)); + writeHexByte(data, pos + 14, (byte) (v & 0xff)); + } + + static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + static void writeHexByte(char[] data, int pos, byte b) { + data[pos + 0] = HEX_DIGITS[(b >> 4) & 0xf]; + data[pos + 1] = HEX_DIGITS[b & 0xf]; + } + +} + +// taken from brave +final class RecyclableBuffers { + + private RecyclableBuffers() { + throw new IllegalStateException("Can't instantiate a utility class"); + } + + private static final ThreadLocal PARSE_BUFFER = new ThreadLocal<>(); + + /** + * Returns a {@link ThreadLocal} reused {@code char[]} for use when decoding bytes + * into an ID hex string. The buffer should be immediately copied into a + * {@link String} after decoding within the same method. + */ + static char[] parseBuffer() { + char[] idBuffer = PARSE_BUFFER.get(); + if (idBuffer == null) { + idBuffer = new char[32 + 1 + 16 + 3 + 16]; // traceid128-spanid-1-parentid + PARSE_BUFFER.set(idBuffer); + } + return idBuffer; + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java index 295d2288d..0b56fc984 100644 --- a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/instrument/deployer/SimpleTracer.java @@ -85,6 +85,11 @@ class SimpleTracer implements Tracer { return null; } + @Override + public TraceContext.Builder traceContextBuilder() { + return null; + } + @Override public Map getAllBaggage() { return new HashMap<>(); diff --git a/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/EncodingUtilsTests.java b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/EncodingUtilsTests.java new file mode 100644 index 000000000..3472e237f --- /dev/null +++ b/spring-cloud-sleuth-instrumentation/src/test/java/org/springframework/cloud/sleuth/internal/EncodingUtilsTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.internal; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; + +class EncodingUtilsTests { + + @Test + void should_convert_back_and_forth_with_64bits() { + long[] fromString = EncodingUtils.fromString("7c6239a5ad0a4287"); + BDDAssertions.then(fromString).hasSize(1); + + String fromLong = EncodingUtils.fromLong(fromString[0]); + + BDDAssertions.then(fromLong).isEqualTo("7c6239a5ad0a4287"); + } + + @Test + void should_convert_back_and_forth_with_128bits() { + long[] fromString = EncodingUtils.fromString("596e1787feb110407c6239a5ad0a4287"); + BDDAssertions.then(fromString).hasSize(2); + String fromLong = EncodingUtils.fromLongs(fromString[0], fromString[1]); + + BDDAssertions.then(fromLong).isEqualTo("596e1787feb110407c6239a5ad0a4287"); + } + +} diff --git a/tests/brave/pom.xml b/tests/brave/pom.xml index 621d49fe6..b742ec657 100644 --- a/tests/brave/pom.xml +++ b/tests/brave/pom.xml @@ -54,6 +54,7 @@ spring-cloud-sleuth-instrumentation-scheduling-tests spring-cloud-sleuth-instrumentation-task-tests spring-cloud-sleuth-instrumentation-webflux-tests + spring-cloud-sleuth-instrumentation-rsocket-tests spring-cloud-sleuth-zipkin-tests diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/pom.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/pom.xml new file mode 100644 index 000000000..5df34188c --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/pom.xml @@ -0,0 +1,100 @@ + + + + + 4.0.0 + + spring-cloud-sleuth-instrumentation-rsocket-tests + jar + Spring Cloud Sleuth Brave RSocket Instrumentation Tests + Spring Cloud Sleuth Brave RSocket Instrumentation Tests + + + org.springframework.cloud + spring-cloud-sleuth-tests-brave + 3.1.0-SNAPSHOT + .. + + + + true + + + + + + + maven-deploy-plugin + + true + + + + + + + + ${project.groupId} + spring-cloud-sleuth-tests-common + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.boot + spring-boot-starter-rsocket + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.boot + spring-boot-starter-test + + + io.zipkin.brave + brave-tests + + + org.awaitility + awaitility + + + + diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rsocket/TraceRSocketTests.java b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rsocket/TraceRSocketTests.java new file mode 100644 index 000000000..4cd869a93 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rsocket/TraceRSocketTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.brave.instrument.rsocket; + +import brave.sampler.Sampler; + +import org.springframework.cloud.sleuth.brave.BraveTestSpanHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +public class TraceRSocketTests extends org.springframework.cloud.sleuth.instrument.rsocket.TraceRSocketTests { + + @Override + protected Class testConfiguration() { + return Config.class; + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + org.springframework.cloud.sleuth.test.TestSpanHandler testSpanHandlerSupplier( + brave.test.TestSpanHandler testSpanHandler) { + return new BraveTestSpanHandler(testSpanHandler); + } + + @Bean + Sampler alwaysSampler() { + return Sampler.ALWAYS_SAMPLE; + } + + @Bean + brave.test.TestSpanHandler braveTestSpanHandler() { + return new brave.test.TestSpanHandler(); + } + + } + +} diff --git a/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/resources/logback.xml b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/resources/logback.xml new file mode 100644 index 000000000..c5c54bb21 --- /dev/null +++ b/tests/brave/spring-cloud-sleuth-instrumentation-rsocket-tests/src/test/resources/logback.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/common/pom.xml b/tests/common/pom.xml index 16cb95b52..7c1fb98de 100644 --- a/tests/common/pom.xml +++ b/tests/common/pom.xml @@ -1,230 +1,235 @@ - - - - - 4.0.0 - - spring-cloud-sleuth-tests-common - jar - Spring Cloud Sleuth Tests Common - Spring Cloud Sleuth Tests Common - - - org.springframework.cloud - spring-cloud-sleuth-tests - 3.1.0-SNAPSHOT - .. - - - - - org.springframework.cloud - spring-cloud-sleuth-instrumentation - - - org.springframework.boot - spring-boot-starter-test - compile - - - org.awaitility - awaitility - compile - - - com.squareup.okhttp3 - mockwebserver - true - - - org.springframework.integration - spring-integration-core - true - - - org.springframework.boot - spring-boot-starter-websocket - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-webflux - true - - - org.springframework.cloud - spring-cloud-starter-gateway - true - - - org.springframework.cloud - spring-cloud-starter-task - true - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-resilience4j - true - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-reactor-resilience4j - true - - - org.springframework.boot - spring-boot-starter-quartz - true - - - org.springframework.cloud - spring-cloud-starter-openfeign - true - - - io.github.openfeign - feign-okhttp - true - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - true - - - org.springframework.cloud - spring-cloud-config-server - true - - - org.apache.httpcomponents - httpclient - true - - - org.springframework.cloud - spring-cloud-sleuth-autoconfigure - true - - - org.springframework.cloud - spring-cloud-sleuth-brave - true - - - io.zipkin.brave - brave-tests - true - - - io.projectreactor.kafka - reactor-kafka - true - - - org.testcontainers - testcontainers - true - - - org.testcontainers - junit-jupiter - true - - - org.testcontainers - kafka - true - - - org.springframework.cloud - spring-cloud-sleuth-zipkin - true - - - io.zipkin.zipkin2 - zipkin - true - - - io.zipkin.reporter2 - zipkin-reporter - true - - - io.zipkin.reporter2 - zipkin-reporter-brave - true - - - io.zipkin.reporter2 - zipkin-sender-kafka - true - - - - org.apache.kafka - kafka-clients - - - - - io.zipkin.reporter2 - zipkin-sender-activemq-client - true - - - org.apache.activemq - activemq-client - - - - - org.apache.activemq - activemq-client - true - - - io.zipkin.reporter2 - zipkin-sender-amqp-client - true - - - - com.rabbitmq - amqp-client - - - - - - - + + + + + 4.0.0 + + spring-cloud-sleuth-tests-common + jar + Spring Cloud Sleuth Tests Common + Spring Cloud Sleuth Tests Common + + + org.springframework.cloud + spring-cloud-sleuth-tests + 3.1.0-SNAPSHOT + .. + + + + + org.springframework.cloud + spring-cloud-sleuth-instrumentation + + + org.springframework.boot + spring-boot-starter-test + compile + + + org.awaitility + awaitility + compile + + + com.squareup.okhttp3 + mockwebserver + true + + + org.springframework.integration + spring-integration-core + true + + + org.springframework.boot + spring-boot-starter-websocket + true + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.boot + spring-boot-starter-web + true + + + org.springframework.boot + spring-boot-starter-webflux + true + + + org.springframework.cloud + spring-cloud-starter-gateway + true + + + org.springframework.cloud + spring-cloud-starter-task + true + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-resilience4j + true + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-reactor-resilience4j + true + + + org.springframework.boot + spring-boot-starter-quartz + true + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + io.github.openfeign + feign-okhttp + true + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + true + + + org.springframework.cloud + spring-cloud-config-server + true + + + org.apache.httpcomponents + httpclient + true + + + org.springframework.cloud + spring-cloud-sleuth-autoconfigure + true + + + org.springframework.cloud + spring-cloud-sleuth-brave + true + + + io.zipkin.brave + brave-tests + true + + + io.projectreactor.kafka + reactor-kafka + true + + + org.testcontainers + testcontainers + true + + + org.testcontainers + junit-jupiter + true + + + org.testcontainers + kafka + true + + + org.springframework.boot + spring-boot-starter-rsocket + true + + + org.springframework.cloud + spring-cloud-sleuth-zipkin + true + + + io.zipkin.zipkin2 + zipkin + true + + + io.zipkin.reporter2 + zipkin-reporter + true + + + io.zipkin.reporter2 + zipkin-reporter-brave + true + + + io.zipkin.reporter2 + zipkin-sender-kafka + true + + + + org.apache.kafka + kafka-clients + + + + + io.zipkin.reporter2 + zipkin-sender-activemq-client + true + + + org.apache.activemq + activemq-client + + + + + org.apache.activemq + activemq-client + true + + + io.zipkin.reporter2 + zipkin-sender-amqp-client + true + + + + com.rabbitmq + amqp-client + + + + + + + diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java index e27a43140..8a954219e 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/config/ConfigServerIntegrationTests.java @@ -88,7 +88,7 @@ public abstract class ConfigServerIntegrationTests { void call(int port) { log.info("Sending request"); - String result = new RestTemplate().getForObject("http://localhost:" + port + "/master/application.yml", + String result = new RestTemplate().getForObject("http://localhost:" + port + "/foo/default/main", String.class); log.info("Got [\n" + result + "\n]"); } diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java new file mode 100644 index 000000000..556b4ff54 --- /dev/null +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java @@ -0,0 +1,363 @@ +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import java.net.URI; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; + +import brave.Span; +import brave.Tracer; +import brave.test.TestSpanHandler; +import io.rsocket.frame.FrameType; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketRequester.Builder; +import org.springframework.messaging.rsocket.RSocketStrategies; +import org.springframework.stereotype.Controller; +import org.springframework.util.MimeType; + +import static org.assertj.core.api.BDDAssertions.then; + +public abstract class TraceRSocketTests { + + public static final String EXPECTED_TRACE_ID = "b919095138aa4c6e"; + + @Test + public void should_instrument_responder() throws Exception { + // setup + ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.rsocket.server.transport=websocket", + "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", + "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + final TestSpanHandler spans = context.getBean(TestSpanHandler.class); + final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); + final TestController controller2 = context.getBean(TestController.class); + final RSocketStrategies strategies = context.getBean(RSocketStrategies.class); + + final Builder rsocketRequesterBuilder = RSocketRequester.builder().rsocketStrategies(strategies); + + final RSocketRequester rSocketRequester = rsocketRequesterBuilder + .websocket(URI.create("ws://localhost:" + port + "/rsocket")); + + // REQUEST FNF + whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf").block(); + + FrameType receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.fnf", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + whenRequestResponseIsSent(rSocketRequester, "api.c2.rr").block(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rr", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + whenRequestStreamIsSent(rSocketRequester, "api.c2.rs").blockLast(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rs", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + whenRequestChannelIsSent(rSocketRequester, "api.c2.rc").blockLast(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rc", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST FNF + whenNonSampledRequestFnfIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + whenNonSampledRequestResponseIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + whenNonSampledRequestStreamIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + whenNonSampledRequestChannelIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // cleanup + context.close(); + } + + @Test + public void should_instrument_requester_and_responder() throws Exception { + // setup + ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.rsocket.server.transport=websocket", + "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", + "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + + final org.springframework.cloud.sleuth.Tracer tracer = context + .getBean(org.springframework.cloud.sleuth.Tracer.class); + final TestSpanHandler spans = context.getBean(TestSpanHandler.class); + final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); + final TestController controller2 = context.getBean(TestController.class); + + final Builder rsocketRequesterBuilder = context.getBean(Builder.class); + + final RSocketRequester rSocketRequester = rsocketRequesterBuilder + .websocket(URI.create("ws://localhost:" + port + "/rsocket")); + + // REQUEST FNF + final org.springframework.cloud.sleuth.Span nextSpanFnf = tracer.nextSpan().start(); + whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanFnf.context())) + .doFinally(signalType -> nextSpanFnf.end()).block(); + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanFnf.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + final org.springframework.cloud.sleuth.Span nextSpanRR = tracer.nextSpan().start(); + whenRequestResponseIsSent(rSocketRequester, "api.c2.rr") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRR.context())) + .doFinally(signalType -> nextSpanRR.end()).block(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRR.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + final org.springframework.cloud.sleuth.Span nextSpanRS = tracer.nextSpan().start(); + whenRequestStreamIsSent(rSocketRequester, "api.c2.rs") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRS.context())) + .doFinally(signalType -> nextSpanRS.end()).blockLast(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRS.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + final org.springframework.cloud.sleuth.Span nextSpanRC = tracer.nextSpan().start(); + whenRequestChannelIsSent(rSocketRequester, "api.c2.rc") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRC.context())) + .doFinally(signalType -> nextSpanRC.end()).blockLast(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRC.context().traceId()); + spans.clear(); + controller2.reset(); + + // cleanup + context.close(); + } + + protected abstract Class testConfiguration(); + + private void thenSpanWasReportedWithTags(TestSpanHandler spans, String path, FrameType frameType) { + then(spans).hasSize(1); + // TODO: Preferred option would be : [api.c2.{name}] + then(spans.get(0).name()).isEqualTo(frameType.name() + " " + path); + } + + private Mono whenRequestFnFIsSent(RSocketRequester requester, String path) { + return requester.route(path).send(); + } + + private Mono whenRequestResponseIsSent(RSocketRequester requester, String path) { + return requester.route(path).retrieveMono(String.class); + } + + private Flux whenRequestStreamIsSent(RSocketRequester requester, String path) { + return requester.route(path).retrieveFlux(String.class); + } + + private Flux whenRequestChannelIsSent(RSocketRequester requester, String path) { + return requester.route(path).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class); + } + + private void whenNonSampledRequestFnfIsSent(RSocketRequester requester) { + requester.route("api.c2.fnf").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).send().block(); + } + + private void whenNonSampledRequestResponseIsSent(RSocketRequester requester) { + requester.route("api.c2.rr").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).retrieveMono(String.class).block(); + } + + private void whenNonSampledRequestStreamIsSent(RSocketRequester requester) { + requester.route("api.c2.rs").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).retrieveFlux(String.class).blockLast(); + } + + private void whenNonSampledRequestChannelIsSent(RSocketRequester requester) { + requester.route("api.c2.rc").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class).blockLast(); + } + + private void thenNoSpanWasReported(TestSpanHandler spans, TestController controller2, String expectedTraceId) { + // then(spans).isEmpty(); // FIXME: does not work for request case + then(controller2.getSpan()).isNotNull(); + then(controller2.getSpan().context().traceIdString()).isEqualTo(expectedTraceId); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + static class MyConfig { + + @Bean + TestController controller(Tracer tracer) { + return new TestController(tracer); + } + + } + + @Controller + @MessageMapping("api.c2") + static class TestController { + + final Tracer tracer; + + Span span; + + ContextView interceptedContext; + + BlockingQueue receivedFrames = new LinkedBlockingDeque<>(); + + TestController(Tracer tracer) { + this.tracer = tracer; + } + + BlockingQueue getReceivedFrames() { + return this.receivedFrames; + } + + Span getSpan() { + return this.span; + } + + void reset() { + this.span = null; + } + + @MessageMapping("fnf") + Mono testFnf() { + + this.span = this.tracer.currentSpan(); + + return Mono.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_FNF); + return Mono.empty(); + }); + } + + @MessageMapping("rr") + Mono testRR() { + this.span = this.tracer.currentSpan(); + + return Mono.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_RESPONSE); + return Mono.just("response"); + }); + } + + @MessageMapping("rs") + Flux testRS() { + this.span = this.tracer.currentSpan(); + + return Flux.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_STREAM); + return Flux.just("stream"); + }); + } + + @MessageMapping("rc") + Flux testRC(@Payload Flux inbound) { + this.span = this.tracer.currentSpan(); + + return Flux.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_CHANNEL); + return inbound; + }); + } + + } + +} From a6bf9a328a951fef9b750a430fba5e9d876dfb7f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 29 Apr 2021 14:08:49 +0200 Subject: [PATCH 78/78] Fixed the messaging aspect --- .../instrument/deployer/TraceAppDeployer.java | 516 ++++++------- .../messaging/TraceMessagingAspect.java | 2 +- .../instrument/rsocket/TraceRSocketTests.java | 730 +++++++++--------- 3 files changed, 626 insertions(+), 622 deletions(-) diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java index b236a6057..b4f2febe5 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/deployer/TraceAppDeployer.java @@ -1,92 +1,92 @@ -/* - * Copyright 2018-2021 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 - * - * https://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.instrument.deployer; - -import java.time.Duration; -import java.util.Arrays; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.cloud.deployer.spi.app.AppDeployer; -import org.springframework.cloud.deployer.spi.app.AppScaleRequest; -import org.springframework.cloud.deployer.spi.app.AppStatus; -import org.springframework.cloud.deployer.spi.app.DeploymentState; -import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; -import org.springframework.cloud.deployer.spi.core.RuntimeEnvironmentInfo; -import org.springframework.cloud.sleuth.CurrentTraceContext; -import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; -import org.springframework.core.env.Environment; - -/** - * Trace representation of an {@link AppDeployer}. - * - * @author Marcin Grzejszczak - * @since 3.1.0 - */ -public class TraceAppDeployer implements AppDeployer { - - private static final Log log = LogFactory.getLog(TraceAppDeployer.class); - - private final AppDeployer delegate; - - private final BeanFactory beanFactory; - - private final Environment environment; - - private Tracer tracer; - - private CurrentTraceContext currentTraceContext; - - private Long pollDelay; - - public TraceAppDeployer(AppDeployer delegate, BeanFactory beanFactory, Environment environment) { - this.delegate = delegate; - this.beanFactory = beanFactory; - this.environment = environment; - } - - @Override - public String deploy(AppDeploymentRequest request) { - Span span = tracer().nextSpan().name("deploy"); - // TODO: Is this secure to pass? - // TODO: Does it make sense? - // if (!request.getCommandlineArguments().isEmpty()) { - // span.tag("commandlineArguments", request.getCommandlineArguments().toString()); - // } - // if (!request.getDeploymentProperties().isEmpty()) { - // span.tag("deploymentProperties", request.getDeploymentProperties().toString()); - // } - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - span.event("start"); - String id = this.delegate.deploy(request); - span.tag("deployer.app.id", id); - registerListener(span, id); - return id; - } - } - - private void registerListener(Span span, String id) { - PreviousAndCurrentStatus previousAndCurrentStatus = new PreviousAndCurrentStatus(span); +/* + * Copyright 2018-2021 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 + * + * https://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.instrument.deployer; + +import java.time.Duration; +import java.util.Arrays; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.deployer.spi.app.AppDeployer; +import org.springframework.cloud.deployer.spi.app.AppScaleRequest; +import org.springframework.cloud.deployer.spi.app.AppStatus; +import org.springframework.cloud.deployer.spi.app.DeploymentState; +import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; +import org.springframework.cloud.deployer.spi.core.RuntimeEnvironmentInfo; +import org.springframework.cloud.sleuth.CurrentTraceContext; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth; +import org.springframework.core.env.Environment; + +/** + * Trace representation of an {@link AppDeployer}. + * + * @author Marcin Grzejszczak + * @since 3.1.0 + */ +public class TraceAppDeployer implements AppDeployer { + + private static final Log log = LogFactory.getLog(TraceAppDeployer.class); + + private final AppDeployer delegate; + + private final BeanFactory beanFactory; + + private final Environment environment; + + private Tracer tracer; + + private CurrentTraceContext currentTraceContext; + + private Long pollDelay; + + public TraceAppDeployer(AppDeployer delegate, BeanFactory beanFactory, Environment environment) { + this.delegate = delegate; + this.beanFactory = beanFactory; + this.environment = environment; + } + + @Override + public String deploy(AppDeploymentRequest request) { + Span span = tracer().nextSpan().name("deploy"); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (!request.getCommandlineArguments().isEmpty()) { + // span.tag("commandlineArguments", request.getCommandlineArguments().toString()); + // } + // if (!request.getDeploymentProperties().isEmpty()) { + // span.tag("deploymentProperties", request.getDeploymentProperties().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + String id = this.delegate.deploy(request); + span.tag("deployer.app.id", id); + registerListener(span, id); + return id; + } + } + + private void registerListener(Span span, String id) { + PreviousAndCurrentStatus previousAndCurrentStatus = new PreviousAndCurrentStatus(span); // @formatter:off this.delegate.statusReactive(id) .map(previousAndCurrentStatus::updateCurrent) @@ -97,172 +97,172 @@ public class TraceAppDeployer implements AppDeployer { .doOnError(span::error) // we will close the span in the reactive part .doFinally(signalType -> span.end()).subscribe(); - // @formatter:on - } - - @Override - public void undeploy(String id) { - Span span = tracer().nextSpan().name("undeploy"); - span.tag("deployer.app.id", id); - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - span.event("start"); - this.delegate.undeploy(id); - registerListener(span, id); - } - finally { - span.end(); - } - } - - @Override - public AppStatus status(String id) { - Span span = tracer().nextSpan().name("status"); - span.tag("deployer.app.id", id); - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - return this.delegate.status(id); - } - finally { - span.end(); - } - } - - @Override - public Mono statusReactive(String id) { - return ReactorSleuth.tracedMono(tracer(), currentTraceContext(), "status", - () -> this.delegate.statusReactive(id), span -> span.tag("deployer.app.id", id)); - } - - @Override - public Flux statusesReactive(String... ids) { - return ReactorSleuth.tracedFlux(tracer(), currentTraceContext(), "statuses", - () -> this.delegate.statusesReactive(ids), span -> span.tag("deployer.app.ids", Arrays.toString(ids))); - } - - @Override - public RuntimeEnvironmentInfo environmentInfo() { - return this.delegate.environmentInfo(); - } - - @Override - public String getLog(String id) { - Span span = tracer().nextSpan().name("getLog"); - span.tag("deployer.app.id", id); - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - return this.delegate.getLog(id); - } - finally { - span.end(); - } - } - - @Override - public void scale(AppScaleRequest appScaleRequest) { - Span span = tracer().nextSpan().name("scale"); - span.tag("deployer.scale.deploymentId", appScaleRequest.getDeploymentId()); - span.tag("deployer.scale.count", String.valueOf(appScaleRequest.getCount())); - // TODO: Is this secure to pass? - // TODO: Does it make sense? - // if (appScaleRequest.getProperties().isPresent() && - // !appScaleRequest.getProperties().get().isEmpty()) { - // span.tag("properties", appScaleRequest.getProperties().get().toString()); - // } - try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { - this.delegate.scale(appScaleRequest); - } - finally { - span.end(); - } - } - - private Tracer tracer() { - if (this.tracer == null) { - this.tracer = this.beanFactory.getBean(Tracer.class); - } - return this.tracer; - } - - private CurrentTraceContext currentTraceContext() { - if (this.currentTraceContext == null) { - this.currentTraceContext = this.beanFactory.getBean(CurrentTraceContext.class); - } - return this.currentTraceContext; - } - - private long pollDelay() { - if (this.pollDelay == null) { - this.pollDelay = this.environment.getProperty("spring.sleuth.deployer.status-poll-delay", Long.class, 500L); - } - return this.pollDelay; - } - - private static final class PreviousAndCurrentStatus { - - private final Span span; - - private AppStatus current; - - private AppStatus previous; - - private PreviousAndCurrentStatus(Span span) { - this.span = span; - if (log.isDebugEnabled()) { - log.debug("Current span is [" + span + "]"); - } - } - - private PreviousAndCurrentStatus updateCurrent(AppStatus current) { - if (log.isTraceEnabled()) { - log.trace("State before change: current [" + this.current + "], previous [" + this.previous + "]"); - } - this.previous = this.current; - this.current = current; - if (log.isTraceEnabled()) { - log.trace("State after change: current [" + this.current + "], previous [" + this.previous + "]"); - } - if (statusChanged()) { - annotateSpan(); - } - else if (log.isTraceEnabled()) { - log.trace("State has not changed, will not annotate the span"); - } - return this; - } - - private void annotateSpan() { - String name = this.current.getState().name(); - if (log.isDebugEnabled()) { - log.debug("Will annotate its state with [" + name + "]"); - } - this.span.event(name); - } - - private boolean statusChanged() { - if (this.previous == null && this.current != null) { - if (log.isDebugEnabled()) { - log.debug("Previous is null, current is not null"); - } - return true; - } - else if (this.current == null) { - throw new IllegalStateException("Current state can't be null"); - } - DeploymentState currentState = this.current.getState(); - DeploymentState previousState = this.previous.getState(); - return currentState != previousState; - } - - private boolean isFinished() { - boolean finished = this.current.getState() == DeploymentState.deployed - || this.current.getState() == DeploymentState.undeployed - || this.current.getState() == DeploymentState.failed - || this.current.getState() == DeploymentState.error - || this.current.getState() == DeploymentState.unknown; - if (log.isTraceEnabled()) { - log.trace("Status is finished [" + finished + "]"); - } - return finished; - } - - } - -} + // @formatter:on + } + + @Override + public void undeploy(String id) { + Span span = tracer().nextSpan().name("undeploy"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + span.event("start"); + this.delegate.undeploy(id); + registerListener(span, id); + } + finally { + span.end(); + } + } + + @Override + public AppStatus status(String id) { + Span span = tracer().nextSpan().name("status"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.status(id); + } + finally { + span.end(); + } + } + + @Override + public Mono statusReactive(String id) { + return ReactorSleuth.tracedMono(tracer(), currentTraceContext(), "status", + () -> this.delegate.statusReactive(id), span -> span.tag("deployer.app.id", id)); + } + + @Override + public Flux statusesReactive(String... ids) { + return ReactorSleuth.tracedFlux(tracer(), currentTraceContext(), "statuses", + () -> this.delegate.statusesReactive(ids), span -> span.tag("deployer.app.ids", Arrays.toString(ids))); + } + + @Override + public RuntimeEnvironmentInfo environmentInfo() { + return this.delegate.environmentInfo(); + } + + @Override + public String getLog(String id) { + Span span = tracer().nextSpan().name("getLog"); + span.tag("deployer.app.id", id); + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + return this.delegate.getLog(id); + } + finally { + span.end(); + } + } + + @Override + public void scale(AppScaleRequest appScaleRequest) { + Span span = tracer().nextSpan().name("scale"); + span.tag("deployer.scale.deploymentId", appScaleRequest.getDeploymentId()); + span.tag("deployer.scale.count", String.valueOf(appScaleRequest.getCount())); + // TODO: Is this secure to pass? + // TODO: Does it make sense? + // if (appScaleRequest.getProperties().isPresent() && + // !appScaleRequest.getProperties().get().isEmpty()) { + // span.tag("properties", appScaleRequest.getProperties().get().toString()); + // } + try (Tracer.SpanInScope spanInScope = tracer().withSpan(span.start())) { + this.delegate.scale(appScaleRequest); + } + finally { + span.end(); + } + } + + private Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + + private CurrentTraceContext currentTraceContext() { + if (this.currentTraceContext == null) { + this.currentTraceContext = this.beanFactory.getBean(CurrentTraceContext.class); + } + return this.currentTraceContext; + } + + private long pollDelay() { + if (this.pollDelay == null) { + this.pollDelay = this.environment.getProperty("spring.sleuth.deployer.status-poll-delay", Long.class, 500L); + } + return this.pollDelay; + } + + private static final class PreviousAndCurrentStatus { + + private final Span span; + + private AppStatus current; + + private AppStatus previous; + + private PreviousAndCurrentStatus(Span span) { + this.span = span; + if (log.isDebugEnabled()) { + log.debug("Current span is [" + span + "]"); + } + } + + private PreviousAndCurrentStatus updateCurrent(AppStatus current) { + if (log.isTraceEnabled()) { + log.trace("State before change: current [" + this.current + "], previous [" + this.previous + "]"); + } + this.previous = this.current; + this.current = current; + if (log.isTraceEnabled()) { + log.trace("State after change: current [" + this.current + "], previous [" + this.previous + "]"); + } + if (statusChanged()) { + annotateSpan(); + } + else if (log.isTraceEnabled()) { + log.trace("State has not changed, will not annotate the span"); + } + return this; + } + + private void annotateSpan() { + String name = this.current.getState().name(); + if (log.isDebugEnabled()) { + log.debug("Will annotate its state with [" + name + "]"); + } + this.span.event(name); + } + + private boolean statusChanged() { + if (this.previous == null && this.current != null) { + if (log.isDebugEnabled()) { + log.debug("Previous is null, current is not null"); + } + return true; + } + else if (this.current == null) { + throw new IllegalStateException("Current state can't be null"); + } + DeploymentState currentState = this.current.getState(); + DeploymentState previousState = this.previous.getState(); + return currentState != previousState; + } + + private boolean isFinished() { + boolean finished = this.current.getState() == DeploymentState.deployed + || this.current.getState() == DeploymentState.undeployed + || this.current.getState() == DeploymentState.failed + || this.current.getState() == DeploymentState.error + || this.current.getState() == DeploymentState.unknown; + if (log.isTraceEnabled()) { + log.trace("Status is finished [" + finished + "]"); + } + return finished; + } + + } + +} diff --git a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java index fda6d71bd..a2b262bc0 100644 --- a/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java +++ b/spring-cloud-sleuth-instrumentation/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAspect.java @@ -59,7 +59,7 @@ public class TraceMessagingAspect { this.spanNamer = spanNamer; } - @Pointcut("@within(org.springframework.messaging.handler.annotation.MessageMapping)") + @Pointcut("@annotation(org.springframework.messaging.handler.annotation.MessageMapping)") private void anyMessageMappingAnnotated() { } // NOSONAR diff --git a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java index 556b4ff54..43a1f9f97 100644 --- a/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java +++ b/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/rsocket/TraceRSocketTests.java @@ -1,363 +1,367 @@ -/* - * Copyright 2013-2021 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 - * - * https://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.instrument.rsocket; - -import java.net.URI; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingDeque; - -import brave.Span; -import brave.Tracer; -import brave.test.TestSpanHandler; -import io.rsocket.frame.FrameType; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.util.context.ContextView; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.sleuth.TraceContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.messaging.rsocket.RSocketRequester; -import org.springframework.messaging.rsocket.RSocketRequester.Builder; -import org.springframework.messaging.rsocket.RSocketStrategies; -import org.springframework.stereotype.Controller; -import org.springframework.util.MimeType; - -import static org.assertj.core.api.BDDAssertions.then; - -public abstract class TraceRSocketTests { - - public static final String EXPECTED_TRACE_ID = "b919095138aa4c6e"; - - @Test - public void should_instrument_responder() throws Exception { - // setup - ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) - .web(WebApplicationType.REACTIVE) - .properties("server.port=0", "spring.rsocket.server.transport=websocket", - "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", - "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", - "management.security.enabled=false") - .run(); - final TestSpanHandler spans = context.getBean(TestSpanHandler.class); - final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); - final TestController controller2 = context.getBean(TestController.class); - final RSocketStrategies strategies = context.getBean(RSocketStrategies.class); - - final Builder rsocketRequesterBuilder = RSocketRequester.builder().rsocketStrategies(strategies); - - final RSocketRequester rSocketRequester = rsocketRequesterBuilder - .websocket(URI.create("ws://localhost:" + port + "/rsocket")); - - // REQUEST FNF - whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf").block(); - - FrameType receivedFrame = controller2.getReceivedFrames().take(); - thenSpanWasReportedWithTags(spans, "api.c2.fnf", receivedFrame); - spans.clear(); - controller2.reset(); - - // REQUEST RESPONSE - whenRequestResponseIsSent(rSocketRequester, "api.c2.rr").block(); - - receivedFrame = controller2.getReceivedFrames().take(); - thenSpanWasReportedWithTags(spans, "api.c2.rr", receivedFrame); - spans.clear(); - controller2.reset(); - - // REQUEST STREAM - whenRequestStreamIsSent(rSocketRequester, "api.c2.rs").blockLast(); - - receivedFrame = controller2.getReceivedFrames().take(); - thenSpanWasReportedWithTags(spans, "api.c2.rs", receivedFrame); - spans.clear(); - controller2.reset(); - - // REQUEST CHANNEL - whenRequestChannelIsSent(rSocketRequester, "api.c2.rc").blockLast(); - - receivedFrame = controller2.getReceivedFrames().take(); - thenSpanWasReportedWithTags(spans, "api.c2.rc", receivedFrame); - spans.clear(); - controller2.reset(); - - // REQUEST FNF - whenNonSampledRequestFnfIsSent(rSocketRequester); - controller2.getReceivedFrames().take(); - // then - thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); - spans.clear(); - controller2.reset(); - - // REQUEST RESPONSE - whenNonSampledRequestResponseIsSent(rSocketRequester); - controller2.getReceivedFrames().take(); - // then - thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); - spans.clear(); - controller2.reset(); - - // REQUEST STREAM - whenNonSampledRequestStreamIsSent(rSocketRequester); - controller2.getReceivedFrames().take(); - // then - thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); - spans.clear(); - controller2.reset(); - - // REQUEST CHANNEL - whenNonSampledRequestChannelIsSent(rSocketRequester); - controller2.getReceivedFrames().take(); - // then - thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); - spans.clear(); - controller2.reset(); - - // cleanup - context.close(); - } - - @Test - public void should_instrument_requester_and_responder() throws Exception { - // setup - ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) - .web(WebApplicationType.REACTIVE) - .properties("server.port=0", "spring.rsocket.server.transport=websocket", - "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", - "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", - "management.security.enabled=false") - .run(); - - final org.springframework.cloud.sleuth.Tracer tracer = context - .getBean(org.springframework.cloud.sleuth.Tracer.class); - final TestSpanHandler spans = context.getBean(TestSpanHandler.class); - final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); - final TestController controller2 = context.getBean(TestController.class); - - final Builder rsocketRequesterBuilder = context.getBean(Builder.class); - - final RSocketRequester rSocketRequester = rsocketRequesterBuilder - .websocket(URI.create("ws://localhost:" + port + "/rsocket")); - - // REQUEST FNF - final org.springframework.cloud.sleuth.Span nextSpanFnf = tracer.nextSpan().start(); - whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf") - .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanFnf.context())) - .doFinally(signalType -> nextSpanFnf.end()).block(); - controller2.getReceivedFrames().take(); - thenNoSpanWasReported(spans, controller2, nextSpanFnf.context().traceId()); - spans.clear(); - controller2.reset(); - - // REQUEST RESPONSE - final org.springframework.cloud.sleuth.Span nextSpanRR = tracer.nextSpan().start(); - whenRequestResponseIsSent(rSocketRequester, "api.c2.rr") - .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRR.context())) - .doFinally(signalType -> nextSpanRR.end()).block(); - - controller2.getReceivedFrames().take(); - thenNoSpanWasReported(spans, controller2, nextSpanRR.context().traceId()); - spans.clear(); - controller2.reset(); - - // REQUEST STREAM - final org.springframework.cloud.sleuth.Span nextSpanRS = tracer.nextSpan().start(); - whenRequestStreamIsSent(rSocketRequester, "api.c2.rs") - .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRS.context())) - .doFinally(signalType -> nextSpanRS.end()).blockLast(); - - controller2.getReceivedFrames().take(); - thenNoSpanWasReported(spans, controller2, nextSpanRS.context().traceId()); - spans.clear(); - controller2.reset(); - - // REQUEST CHANNEL - final org.springframework.cloud.sleuth.Span nextSpanRC = tracer.nextSpan().start(); - whenRequestChannelIsSent(rSocketRequester, "api.c2.rc") - .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRC.context())) - .doFinally(signalType -> nextSpanRC.end()).blockLast(); - - controller2.getReceivedFrames().take(); - thenNoSpanWasReported(spans, controller2, nextSpanRC.context().traceId()); - spans.clear(); - controller2.reset(); - - // cleanup - context.close(); - } - - protected abstract Class testConfiguration(); - - private void thenSpanWasReportedWithTags(TestSpanHandler spans, String path, FrameType frameType) { - then(spans).hasSize(1); - // TODO: Preferred option would be : [api.c2.{name}] - then(spans.get(0).name()).isEqualTo(frameType.name() + " " + path); - } - - private Mono whenRequestFnFIsSent(RSocketRequester requester, String path) { - return requester.route(path).send(); - } - - private Mono whenRequestResponseIsSent(RSocketRequester requester, String path) { - return requester.route(path).retrieveMono(String.class); - } - - private Flux whenRequestStreamIsSent(RSocketRequester requester, String path) { - return requester.route(path).retrieveFlux(String.class); - } - - private Flux whenRequestChannelIsSent(RSocketRequester requester, String path) { - return requester.route(path).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class); - } - - private void whenNonSampledRequestFnfIsSent(RSocketRequester requester) { - requester.route("api.c2.fnf").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { - @Override - public String toString() { - return "b3"; - } - }).send().block(); - } - - private void whenNonSampledRequestResponseIsSent(RSocketRequester requester) { - requester.route("api.c2.rr").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { - @Override - public String toString() { - return "b3"; - } - }).retrieveMono(String.class).block(); - } - - private void whenNonSampledRequestStreamIsSent(RSocketRequester requester) { - requester.route("api.c2.rs").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { - @Override - public String toString() { - return "b3"; - } - }).retrieveFlux(String.class).blockLast(); - } - - private void whenNonSampledRequestChannelIsSent(RSocketRequester requester) { - requester.route("api.c2.rc").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { - @Override - public String toString() { - return "b3"; - } - }).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class).blockLast(); - } - - private void thenNoSpanWasReported(TestSpanHandler spans, TestController controller2, String expectedTraceId) { - // then(spans).isEmpty(); // FIXME: does not work for request case - then(controller2.getSpan()).isNotNull(); - then(controller2.getSpan().context().traceIdString()).isEqualTo(expectedTraceId); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class MyConfig { - - @Bean - TestController controller(Tracer tracer) { - return new TestController(tracer); - } - - } - - @Controller - @MessageMapping("api.c2") - static class TestController { - - final Tracer tracer; - - Span span; - - ContextView interceptedContext; - - BlockingQueue receivedFrames = new LinkedBlockingDeque<>(); - - TestController(Tracer tracer) { - this.tracer = tracer; - } - - BlockingQueue getReceivedFrames() { - return this.receivedFrames; - } - - Span getSpan() { - return this.span; - } - - void reset() { - this.span = null; - } - - @MessageMapping("fnf") - Mono testFnf() { - - this.span = this.tracer.currentSpan(); - - return Mono.deferContextual(c -> { - interceptedContext = c; - receivedFrames.offer(FrameType.REQUEST_FNF); - return Mono.empty(); - }); - } - - @MessageMapping("rr") - Mono testRR() { - this.span = this.tracer.currentSpan(); - - return Mono.deferContextual(c -> { - interceptedContext = c; - receivedFrames.offer(FrameType.REQUEST_RESPONSE); - return Mono.just("response"); - }); - } - - @MessageMapping("rs") - Flux testRS() { - this.span = this.tracer.currentSpan(); - - return Flux.deferContextual(c -> { - interceptedContext = c; - receivedFrames.offer(FrameType.REQUEST_STREAM); - return Flux.just("stream"); - }); - } - - @MessageMapping("rc") - Flux testRC(@Payload Flux inbound) { - this.span = this.tracer.currentSpan(); - - return Flux.deferContextual(c -> { - interceptedContext = c; - receivedFrames.offer(FrameType.REQUEST_CHANNEL); - return inbound; - }); - } - - } - -} +/* + * Copyright 2013-2021 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 + * + * https://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.instrument.rsocket; + +import java.net.URI; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; + +import io.rsocket.frame.FrameType; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceContext; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.exporter.FinishedSpan; +import org.springframework.cloud.sleuth.test.TestSpanHandler; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.rsocket.RSocketRequester; +import org.springframework.messaging.rsocket.RSocketRequester.Builder; +import org.springframework.messaging.rsocket.RSocketStrategies; +import org.springframework.stereotype.Controller; +import org.springframework.util.MimeType; + +import static org.assertj.core.api.BDDAssertions.then; + +public abstract class TraceRSocketTests { + + public static final String EXPECTED_TRACE_ID = "b919095138aa4c6e"; + + @Test + public void should_instrument_responder() throws Exception { + // setup + ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.rsocket.server.transport=websocket", + "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", + "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + final TestSpanHandler spans = context.getBean(TestSpanHandler.class); + final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); + final TestController controller2 = context.getBean(TestController.class); + final RSocketStrategies strategies = context.getBean(RSocketStrategies.class); + + final Builder rsocketRequesterBuilder = RSocketRequester.builder().rsocketStrategies(strategies); + + final RSocketRequester rSocketRequester = rsocketRequesterBuilder + .websocket(URI.create("ws://localhost:" + port + "/rsocket")); + + // REQUEST FNF + whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf").block(); + + FrameType receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.fnf", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + whenRequestResponseIsSent(rSocketRequester, "api.c2.rr").block(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rr", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + whenRequestStreamIsSent(rSocketRequester, "api.c2.rs").blockLast(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rs", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + whenRequestChannelIsSent(rSocketRequester, "api.c2.rc").blockLast(); + + receivedFrame = controller2.getReceivedFrames().take(); + thenSpanWasReportedWithTags(spans, "api.c2.rc", receivedFrame); + spans.clear(); + controller2.reset(); + + // REQUEST FNF + whenNonSampledRequestFnfIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + whenNonSampledRequestResponseIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + whenNonSampledRequestStreamIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + whenNonSampledRequestChannelIsSent(rSocketRequester); + controller2.getReceivedFrames().take(); + // then + thenNoSpanWasReported(spans, controller2, EXPECTED_TRACE_ID); + spans.clear(); + controller2.reset(); + + // cleanup + context.close(); + } + + @Test + public void should_instrument_requester_and_responder() throws Exception { + // setup + ConfigurableApplicationContext context = new SpringApplicationBuilder(MyConfig.class, testConfiguration()) + .web(WebApplicationType.REACTIVE) + .properties("server.port=0", "spring.rsocket.server.transport=websocket", + "spring.rsocket.server.mapping-path=/rsocket", "spring.jmx.enabled=false", + "spring.application.name=TraceRSocketTests", "security.basic.enabled=false", + "management.security.enabled=false") + .run(); + + final org.springframework.cloud.sleuth.Tracer tracer = context + .getBean(org.springframework.cloud.sleuth.Tracer.class); + final TestSpanHandler spans = context.getBean(TestSpanHandler.class); + final int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); + final TestController controller2 = context.getBean(TestController.class); + + final Builder rsocketRequesterBuilder = context.getBean(Builder.class); + + final RSocketRequester rSocketRequester = rsocketRequesterBuilder + .websocket(URI.create("ws://localhost:" + port + "/rsocket")); + + // REQUEST FNF + final org.springframework.cloud.sleuth.Span nextSpanFnf = tracer.nextSpan().start(); + whenRequestFnFIsSent(rSocketRequester, "api.c2.fnf") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanFnf.context())) + .doFinally(signalType -> nextSpanFnf.end()).block(); + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanFnf.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST RESPONSE + final org.springframework.cloud.sleuth.Span nextSpanRR = tracer.nextSpan().start(); + whenRequestResponseIsSent(rSocketRequester, "api.c2.rr") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRR.context())) + .doFinally(signalType -> nextSpanRR.end()).block(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRR.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST STREAM + final org.springframework.cloud.sleuth.Span nextSpanRS = tracer.nextSpan().start(); + whenRequestStreamIsSent(rSocketRequester, "api.c2.rs") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRS.context())) + .doFinally(signalType -> nextSpanRS.end()).blockLast(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRS.context().traceId()); + spans.clear(); + controller2.reset(); + + // REQUEST CHANNEL + final org.springframework.cloud.sleuth.Span nextSpanRC = tracer.nextSpan().start(); + whenRequestChannelIsSent(rSocketRequester, "api.c2.rc") + .contextWrite(ctx -> ctx.put(TraceContext.class, nextSpanRC.context())) + .doFinally(signalType -> nextSpanRC.end()).blockLast(); + + controller2.getReceivedFrames().take(); + thenNoSpanWasReported(spans, controller2, nextSpanRC.context().traceId()); + spans.clear(); + controller2.reset(); + + // cleanup + context.close(); + } + + protected abstract Class testConfiguration(); + + private void thenSpanWasReportedWithTags(TestSpanHandler spans, String path, FrameType frameType) { + then(spans).hasSize(1); + // TODO: Preferred option would be : [api.c2.{name}] + FinishedSpan span = spans.get(0); + then(span.getName()).isEqualTo(frameType.name() + " " + path); + then(span.getTags()).containsEntry("messaging.controller.class", "org.springframework.cloud.sleuth.instrument.rsocket.TraceRSocketTests$TestController"); + then(span.getTags()).containsKey("messaging.controller.method"); + } + + private Mono whenRequestFnFIsSent(RSocketRequester requester, String path) { + return requester.route(path).send(); + } + + private Mono whenRequestResponseIsSent(RSocketRequester requester, String path) { + return requester.route(path).retrieveMono(String.class); + } + + private Flux whenRequestStreamIsSent(RSocketRequester requester, String path) { + return requester.route(path).retrieveFlux(String.class); + } + + private Flux whenRequestChannelIsSent(RSocketRequester requester, String path) { + return requester.route(path).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class); + } + + private void whenNonSampledRequestFnfIsSent(RSocketRequester requester) { + requester.route("api.c2.fnf").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).send().block(); + } + + private void whenNonSampledRequestResponseIsSent(RSocketRequester requester) { + requester.route("api.c2.rr").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).retrieveMono(String.class).block(); + } + + private void whenNonSampledRequestStreamIsSent(RSocketRequester requester) { + requester.route("api.c2.rs").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).retrieveFlux(String.class).blockLast(); + } + + private void whenNonSampledRequestChannelIsSent(RSocketRequester requester) { + requester.route("api.c2.rc").metadata(EXPECTED_TRACE_ID + "-" + EXPECTED_TRACE_ID + "-0", new MimeType("b3") { + @Override + public String toString() { + return "b3"; + } + }).data(Flux.fromArray(new String[] { "test1", "test2" })).retrieveFlux(String.class).blockLast(); + } + + private void thenNoSpanWasReported(TestSpanHandler spans, TestController controller2, String expectedTraceId) { + // then(spans).isEmpty(); // FIXME: does not work for request case + then(controller2.getSpan()).isNotNull(); + then(controller2.getSpan().context().traceId()).isEqualTo(expectedTraceId); + } + + @Configuration(proxyBeanMethods = false) + @EnableAutoConfiguration + static class MyConfig { + + @Bean + TestController controller(Tracer tracer) { + return new TestController(tracer); + } + + } + + @Controller + @MessageMapping("api.c2") + static class TestController { + + final Tracer tracer; + + Span span; + + ContextView interceptedContext; + + BlockingQueue receivedFrames = new LinkedBlockingDeque<>(); + + TestController(Tracer tracer) { + this.tracer = tracer; + } + + BlockingQueue getReceivedFrames() { + return this.receivedFrames; + } + + Span getSpan() { + return this.span; + } + + void reset() { + this.span = null; + } + + @MessageMapping("fnf") + Mono testFnf() { + + this.span = this.tracer.currentSpan(); + + return Mono.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_FNF); + return Mono.empty(); + }); + } + + @MessageMapping("rr") + Mono testRR() { + this.span = this.tracer.currentSpan(); + + return Mono.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_RESPONSE); + return Mono.just("response"); + }); + } + + @MessageMapping("rs") + Flux testRS() { + this.span = this.tracer.currentSpan(); + + return Flux.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_STREAM); + return Flux.just("stream"); + }); + } + + @MessageMapping("rc") + Flux testRC(@Payload Flux inbound) { + this.span = this.tracer.currentSpan(); + + return Flux.deferContextual(c -> { + interceptedContext = c; + receivedFrames.offer(FrameType.REQUEST_CHANNEL); + return inbound; + }); + } + + } + +}