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/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index aeafef9d3..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 sample 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.
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 32d179893..2e7786e55 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -1,31 +1,32 @@
-# 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:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- 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
+name: Build
+
+on:
+ push:
+ branches: [ 3.1.x ]
+ pull_request:
+ branches: [ 3.1.x ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ java: ["8", "11", "16"]
+
+ steps:
+ - 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 -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false
diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
index 2e529b161..d7b910b9a 100644
--- a/benchmarks/pom.xml
+++ b/benchmarks/pom.xml
@@ -22,13 +22,13 @@
Benchmarks
Benchmarks (JMH)
org.springframework.cloud
- 3.0.2-SNAPSHOT
+ 3.1.0-SNAPSHOT
benchmarks
org.springframework.boot
spring-boot-starter-parent
- 2.4.3
+ 2.4.5-SNAPSHOT
@@ -41,7 +41,7 @@
4.9.0
0.2.0.RELEASE
1.26
- 3.1.1-SNAPSHOT
+ 3.1.3-SNAPSHOT
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 67b51420c..943d5055d 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,181 +1,181 @@
-/*
- * 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.mvc;
-
-import java.util.concurrent.Future;
-import java.util.regex.Pattern;
-
-import javax.annotation.PreDestroy;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
-import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent;
-import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
-import org.springframework.cloud.sleuth.Span;
-import org.springframework.cloud.sleuth.Tracer;
-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.context.annotation.Configuration;
-import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.util.SocketUtils;
-
-/**
- * @author Marcin Grzejszczak
- */
-@SpringBootApplication
-@EnableAsync
-public class SleuthBenchmarkingSpringApp implements ApplicationListener {
-
- private static final Log log = LogFactory.getLog(SleuthBenchmarkingSpringApp.class);
-
- /**
- * Port of the app.
- */
- public int port;
-
- @Autowired(required = false)
- Tracer tracer;
-
- @Autowired
- AClass aClass;
-
- @Autowired
- AsyncSimulationController controller;
-
- public static void main(String... args) {
- SpringApplication.run(SleuthBenchmarkingSpringApp.class, args);
- }
-
- @PreDestroy
- public void clean() {
- this.controller.clean();
- }
-
- public String manualSpan() {
- return this.aClass.manualSpan();
- }
-
- public String newSpan() {
- return this.aClass.newSpan();
- }
-
- @Override
- public void onApplicationEvent(ServletWebServerInitializedEvent event) {
- this.port = event.getSource().getPort();
- }
-
- public Future async() {
- return this.controller.async();
- }
-
- @Configuration
- static class Config {
- @Autowired(required = false)
- Tracer tracer;
-
- @Bean
- AnotherClass anotherClass() {
- return new AnotherClass(this.tracer);
- }
-
- @Bean
- AClass aClass() {
- return new AClass(this.tracer, anotherClass());
- }
-
- @Bean
- SkipPatternProvider patternProvider() {
- return new SkipPatternProvider() {
- @Override
- public Pattern skipPattern() {
- return Pattern.compile("");
- }
- };
- }
-
-
- @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 {
-
- private final Tracer tracer;
-
- private final AnotherClass anotherClass;
-
- AClass(Tracer tracer, AnotherClass anotherClass) {
- this.tracer = tracer;
- this.anotherClass = anotherClass;
- }
-
- public String manualSpan() {
- Span manual = this.tracer.nextSpan().name("span-name");
- try (Tracer.SpanInScope ws = this.tracer.withSpan(manual.start())) {
- return this.anotherClass.continuedSpan();
- }
- finally {
- manual.end();
- }
- }
-
- @NewSpan
- public String newSpan() {
- return this.anotherClass.continuedAnnotation("bar");
- }
-
-}
-
-class AnotherClass {
-
- private final Tracer tracer;
-
- AnotherClass(Tracer tracer) {
- this.tracer = tracer;
- }
-
- @ContinueSpan(log = "continuedspan")
- public String continuedAnnotation(@SpanTag("foo") String tagValue) {
- return "continued";
- }
-
- public String continuedSpan() {
- Span span = this.tracer.currentSpan();
- span.tag("foo", "bar");
- span.event("continuedspan.before");
- String response = "continued";
- span.event("continuedspan.after");
- return response;
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.mvc;
+
+import java.util.concurrent.Future;
+import java.util.regex.Pattern;
+
+import javax.annotation.PreDestroy;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent;
+import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
+import org.springframework.cloud.sleuth.Span;
+import org.springframework.cloud.sleuth.Tracer;
+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.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.util.SocketUtils;
+
+/**
+ * @author Marcin Grzejszczak
+ */
+@SpringBootApplication
+@EnableAsync
+public class SleuthBenchmarkingSpringApp implements ApplicationListener {
+
+ private static final Log log = LogFactory.getLog(SleuthBenchmarkingSpringApp.class);
+
+ /**
+ * Port of the app.
+ */
+ public int port;
+
+ @Autowired(required = false)
+ Tracer tracer;
+
+ @Autowired
+ AClass aClass;
+
+ @Autowired
+ AsyncSimulationController controller;
+
+ public static void main(String... args) {
+ SpringApplication.run(SleuthBenchmarkingSpringApp.class, args);
+ }
+
+ @PreDestroy
+ public void clean() {
+ this.controller.clean();
+ }
+
+ public String manualSpan() {
+ return this.aClass.manualSpan();
+ }
+
+ public String newSpan() {
+ return this.aClass.newSpan();
+ }
+
+ @Override
+ public void onApplicationEvent(ServletWebServerInitializedEvent event) {
+ this.port = event.getSource().getPort();
+ }
+
+ public Future async() {
+ return this.controller.async();
+ }
+
+ @Configuration
+ static class Config {
+ @Autowired(required = false)
+ Tracer tracer;
+
+ @Bean
+ AnotherClass anotherClass() {
+ return new AnotherClass(this.tracer);
+ }
+
+ @Bean
+ AClass aClass() {
+ return new AClass(this.tracer, anotherClass());
+ }
+
+ @Bean
+ SkipPatternProvider patternProvider() {
+ return new SkipPatternProvider() {
+ @Override
+ public Pattern skipPattern() {
+ return Pattern.compile("");
+ }
+ };
+ }
+
+
+ @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 {
+
+ private final Tracer tracer;
+
+ private final AnotherClass anotherClass;
+
+ AClass(Tracer tracer, AnotherClass anotherClass) {
+ this.tracer = tracer;
+ this.anotherClass = anotherClass;
+ }
+
+ public String manualSpan() {
+ Span manual = this.tracer.nextSpan().name("span-name");
+ try (Tracer.SpanInScope ws = this.tracer.withSpan(manual.start())) {
+ return this.anotherClass.continuedSpan();
+ }
+ finally {
+ manual.end();
+ }
+ }
+
+ @NewSpan
+ public String newSpan() {
+ return this.anotherClass.continuedAnnotation("bar");
+ }
+
+}
+
+class AnotherClass {
+
+ private final Tracer tracer;
+
+ AnotherClass(Tracer tracer) {
+ this.tracer = tracer;
+ }
+
+ @ContinueSpan(log = "continuedspan")
+ public String continuedAnnotation(@SpanTag("foo") String tagValue) {
+ return "continued";
+ }
+
+ public String continuedSpan() {
+ Span span = this.tracer.currentSpan();
+ span.tag("foo", "bar");
+ span.event("continuedspan.before");
+ String response = "continued";
+ span.event("continuedspan.after");
+ return response;
+ }
+
+}
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 c8aa01ed6..ca33e5bd8 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
@@ -1,275 +1,283 @@
-/*
- * 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.beans.factory.BeanFactory;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.cloud.sleuth.instrument.messaging.MessagingSleuthOperators;
-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.function.type", havingValue = "simple_manual")
- public Function, Message> simpleManual(BeanFactory beanFactory) {
- log.info("simple_manual_function");
- return new SimpleManualFunction(beanFactory);
- }
-
- @Bean(name = "myFlux")
- @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple_manual")
- public Function>, Flux>> reactiveSimpleManual(BeanFactory beanFactory) {
- log.info("simple_reactive_manual_function");
- return new SimpleReactiveManualFunction(beanFactory);
- }
-
- @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 SimpleManualFunction implements Function, Message> {
-
- private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class);
-
- private final BeanFactory beanFactory;
-
- SimpleManualFunction(BeanFactory beanFactory) {
- this.beanFactory = beanFactory;
- }
-
- @Override
- public Message apply(Message input) {
- return (MessagingSleuthOperators.asFunction(this.beanFactory, input)
- .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> {
- log.info("Hello from simple manual [{}]", stringMessage.getPayload());
- return stringMessage;
- })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null))
- .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg))
- .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders()))
- .andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null))
- .apply(input));
- }
-
-}
-
-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();
- }
-
-}
-
-// tag::simple_reactive[]
-class SimpleReactiveManualFunction implements Function>, Flux>> {
-
- private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class);
-
- private final BeanFactory beanFactory;
-
- SimpleReactiveManualFunction(BeanFactory beanFactory) {
- this.beanFactory = beanFactory;
- }
-
- @Override
- public Flux> apply(Flux> input) {
- return input.map(message -> (MessagingSleuthOperators.asFunction(this.beanFactory, message))
- .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> {
- log.info("Hello from simple manual [{}]", stringMessage.getPayload());
- return stringMessage;
- })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null))
- .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders()))
- .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg)).apply(message));
- }
-
-}
-// end::simple_reactive[]
-
-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();
- }));
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.beans.factory.BeanFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.sleuth.instrument.messaging.MessagingSleuthOperators;
+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", "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);
+ 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.function.type", havingValue = "simple_manual")
+ public Function, Message> simpleManual(BeanFactory beanFactory) {
+ log.info("simple_manual_function");
+ return new SimpleManualFunction(beanFactory);
+ }
+
+ @Bean(name = "myFlux")
+ @ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple_manual")
+ public Function>, Flux>> reactiveSimpleManual(BeanFactory beanFactory) {
+ log.info("simple_reactive_manual_function");
+ return new SimpleReactiveManualFunction(beanFactory);
+ }
+
+ @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_QUEUES",
+ matchIfMissing = true)
+ public Function, Flux> decorateQueuesFunction() {
+ log.info("decorate queues 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 SimpleManualFunction implements Function, Message> {
+
+ private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class);
+
+ private final BeanFactory beanFactory;
+
+ SimpleManualFunction(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+ @Override
+ public Message apply(Message input) {
+ return (MessagingSleuthOperators.asFunction(this.beanFactory, input)
+ .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> {
+ log.info("Hello from simple manual [{}]", stringMessage.getPayload());
+ return stringMessage;
+ })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null))
+ .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg))
+ .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders()))
+ .andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null))
+ .apply(input));
+ }
+
+}
+
+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();
+ }
+
+}
+
+// tag::simple_reactive[]
+class SimpleReactiveManualFunction implements Function>, Flux>> {
+
+ private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class);
+
+ private final BeanFactory beanFactory;
+
+ SimpleReactiveManualFunction(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+ @Override
+ public Flux> apply(Flux> input) {
+ return input.map(message -> (MessagingSleuthOperators.asFunction(this.beanFactory, message))
+ .andThen(msg -> MessagingSleuthOperators.withSpanInScope(this.beanFactory, msg, stringMessage -> {
+ log.info("Hello from simple manual [{}]", stringMessage.getPayload());
+ return stringMessage;
+ })).andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null))
+ .andThen(msg -> MessageBuilder.createMessage(msg.getPayload().toUpperCase(), msg.getHeaders()))
+ .andThen(msg -> MessagingSleuthOperators.handleOutputMessage(this.beanFactory, msg)).apply(message));
+ }
+
+}
+// end::simple_reactive[]
+
+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 ac61085db..bdda1256e 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,153 +1,153 @@
-/*
- * 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.webflux;
-
-import java.time.Duration;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.core.publisher.SignalType;
-import reactor.core.scheduler.Scheduler;
-import reactor.core.scheduler.Schedulers;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.WebApplicationType;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
-import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent;
-import org.springframework.cloud.sleuth.TraceContext;
-import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider;
-import org.springframework.cloud.sleuth.instrument.web.WebFluxSleuthOperators;
-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;
-
-/**
- * @author alvin
- */
-@SpringBootApplication
-@RestController
-public class SleuthBenchmarkingSpringWebFluxApp implements ApplicationListener {
-
- 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);
- }
-
- @RequestMapping("/foo")
- public Mono foo() {
- return Mono.just("foo");
- }
-
- @Bean
- SkipPatternProvider patternProvider() {
- return () -> Pattern.compile("");
- }
-
- @Bean
- NettyReactiveWebServerFactory nettyReactiveWebServerFactory(@Value("${server.port:0}") int serverPort) {
- log.info("Starting container at port [" + serverPort + "]");
- return new NettyReactiveWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort);
- }
-
- @Override
- public void onApplicationEvent(ReactiveWebServerInitializedEvent event) {
- 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));
- }
-
- // tag::simple_manual[]
- @GetMapping("/simpleManual")
- public Mono simpleManual() {
- return Mono.just("hello").map(String::toUpperCase).doOnEach(WebFluxSleuthOperators
- .withSpanInScope(SignalType.ON_NEXT, signal -> log.info("Hello from simple [{}]", signal.get())));
- }
- // end::simple_manual[]
-
- @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.traceId().startsWith("0000000000000000")) {
- Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated");
- } else {
- Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated");
- }
- log.info("Assertions passed");
- });
- }
-
- @GetMapping("/complexManual")
- public Mono complexManual() {
- return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList())
- .doOnEach(WebFluxSleuthOperators.withSpanInScope(SignalType.ON_NEXT, () -> log.info("Got a request")))
- .flatMap(s -> Mono.subscriberContext().delayElement(Duration.ofMillis(1), FOO_SCHEDULER).map(ctx -> {
- WebFluxSleuthOperators.withSpanInScope(ctx, () -> log.info("Logging [{}] from flat map", s));
- return "";
- })).doOnEach(signal -> {
- WebFluxSleuthOperators.withSpanInScope(signal.getContext(), () -> log.info("Doing assertions"));
- TraceContext traceContext = signal.getContext().get(TraceContext.class);
- Assert.notNull(traceContext, "Context must be set by Sleuth instrumentation");
- if (traceContext.traceId().startsWith("0000000000000000")) {
- Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated");
- } else {
- Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated");
- }
- log.info("Assertions passed");
- });
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.webflux;
+
+import java.time.Duration;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.core.publisher.SignalType;
+import reactor.core.scheduler.Scheduler;
+import reactor.core.scheduler.Schedulers;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
+import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent;
+import org.springframework.cloud.sleuth.TraceContext;
+import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider;
+import org.springframework.cloud.sleuth.instrument.web.WebFluxSleuthOperators;
+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;
+
+/**
+ * @author alvin
+ */
+@SpringBootApplication
+@RestController
+public class SleuthBenchmarkingSpringWebFluxApp implements ApplicationListener {
+
+ 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);
+ }
+
+ @RequestMapping("/foo")
+ public Mono foo() {
+ return Mono.just("foo");
+ }
+
+ @Bean
+ SkipPatternProvider patternProvider() {
+ return () -> Pattern.compile("");
+ }
+
+ @Bean
+ NettyReactiveWebServerFactory nettyReactiveWebServerFactory(@Value("${server.port:0}") int serverPort) {
+ log.info("Starting container at port [" + serverPort + "]");
+ return new NettyReactiveWebServerFactory(serverPort == 0 ? SocketUtils.findAvailableTcpPort() : serverPort);
+ }
+
+ @Override
+ public void onApplicationEvent(ReactiveWebServerInitializedEvent event) {
+ 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));
+ }
+
+ // tag::simple_manual[]
+ @GetMapping("/simpleManual")
+ public Mono simpleManual() {
+ return Mono.just("hello").map(String::toUpperCase).doOnEach(WebFluxSleuthOperators
+ .withSpanInScope(SignalType.ON_NEXT, signal -> log.info("Hello from simple [{}]", signal.get())));
+ }
+ // end::simple_manual[]
+
+ @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.traceId().startsWith("0000000000000000")) {
+ Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated");
+ } else {
+ Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated");
+ }
+ log.info("Assertions passed");
+ });
+ }
+
+ @GetMapping("/complexManual")
+ public Mono complexManual() {
+ return Flux.range(1, 10).map(String::valueOf).collect(Collectors.toList())
+ .doOnEach(WebFluxSleuthOperators.withSpanInScope(SignalType.ON_NEXT, () -> log.info("Got a request")))
+ .flatMap(s -> Mono.subscriberContext().delayElement(Duration.ofMillis(1), FOO_SCHEDULER).map(ctx -> {
+ WebFluxSleuthOperators.withSpanInScope(ctx, () -> log.info("Logging [{}] from flat map", s));
+ return "";
+ })).doOnEach(signal -> {
+ WebFluxSleuthOperators.withSpanInScope(signal.getContext(), () -> log.info("Doing assertions"));
+ TraceContext traceContext = signal.getContext().get(TraceContext.class);
+ Assert.notNull(traceContext, "Context must be set by Sleuth instrumentation");
+ if (traceContext.traceId().startsWith("0000000000000000")) {
+ Assert.state(traceContext.traceId().equals("00000000000000004883117762eb9420"), "TraceId must be propagated");
+ } else {
+ Assert.state(traceContext.traceId().equals("4883117762eb9420"), "TraceId must be propagated");
+ }
+ log.info("Assertions passed");
+ });
+ }
+
+}
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..67c0ca5fe
--- /dev/null
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/Pair.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ * 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.springframework.cloud.sleuth.autoconfig.instrument.reactor.SleuthReactorProperties;
+
+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 onHook() {
+ return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES.name());
+ }
+
+ public static Pair noSleuth() {
+ return new Pair("spring.sleuth.enabled", "false");
+ }
+
+ public static Pair onEach() {
+ 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());
+ }
+
+ public static Pair onLast() {
+ return new Pair("spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.DECORATE_ON_LAST.name());
+ }
+}
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/SampleTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/SampleTests.java
index 3cadc3077..9da2c9478 100644
--- 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
@@ -1,163 +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 {
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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/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/bridge/BridgeTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/bridge/BridgeTests.java
index f14424c77..ab4a7f5af 100644
--- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/bridge/BridgeTests.java
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/bridge/BridgeTests.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/AnnotationBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java
index 16b014d0a..a4b4ad197 100644
--- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AnnotationBenchmarksTests.java
@@ -1,88 +1,88 @@
-/*
- * 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 = 5, time = 1)
-@Warmup(iterations = 5, time = 1)
-@Fork(2)
-@BenchmarkMode(Mode.SampleTime)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
-@Threads(Threads.MAX)
-@Microbenchmark
-public class AnnotationBenchmarksTests {
-
- @Benchmark
- public void manuallyCreatedSpans(BenchmarkContext context) throws Exception {
- then(context.sleuth.manualSpan()).isEqualTo("continued");
- }
-
- @Benchmark
- public void spanCreatedWithAnnotations(BenchmarkContext context) throws Exception {
- then(context.sleuth.newSpan()).isEqualTo("continued");
- }
-
- @State(Scope.Benchmark)
- public static class BenchmarkContext {
-
- volatile ConfigurableApplicationContext withSleuth;
-
- 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.tracerImplementation.name());
- this.sleuth = this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class);
- }
-
- @TearDown
- public void clean() {
- this.sleuth.clean();
- this.withSleuth.close();
- }
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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 AnnotationBenchmarksTests {
+
+ @Benchmark
+ public void manuallyCreatedSpans(BenchmarkContext context) throws Exception {
+ then(context.sleuth.manualSpan()).isEqualTo("continued");
+ }
+
+ @Benchmark
+ public void spanCreatedWithAnnotations(BenchmarkContext context) throws Exception {
+ then(context.sleuth.newSpan()).isEqualTo("continued");
+ }
+
+ @State(Scope.Benchmark)
+ public static class BenchmarkContext {
+
+ volatile ConfigurableApplicationContext withSleuth;
+
+ 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.tracerImplementation.name());
+ this.sleuth = this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class);
+ }
+
+ @TearDown
+ public void clean() {
+ this.sleuth.clean();
+ this.withSleuth.close();
+ }
+
+ }
+
+}
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
index 3869b98fa..cd1b74f30 100644
--- 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
@@ -1,81 +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 = 5, time = 1)
-@Warmup(iterations = 5, time = 1)
-@Fork(2)
-@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();
- }
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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 = 5, time = 1)
+@Warmup(iterations = 5, time = 1)
+@Fork(2)
+@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/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java
index 868e41efc..f97f64c55 100644
--- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/AsyncWithoutSleuthBenchmarksTests.java
@@ -1,78 +1,78 @@
-/*
- * 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.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.context.ConfigurableApplicationContext;
-
-import static org.assertj.core.api.BDDAssertions.then;
-
-@Measurement(iterations = 5, time = 1)
-@Warmup(iterations = 5, time = 1)
-@Fork(2)
-@BenchmarkMode(Mode.SampleTime)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
-@Threads(Threads.MAX)
-@Microbenchmark
-public class AsyncWithoutSleuthBenchmarksTests {
- @Benchmark
- public void asyncMethodWithoutSleuth(BenchmarkContext context) throws Exception {
- then(context.app.async().get()).isEqualTo("async");
- }
-
- @State(Scope.Benchmark)
- public static class BenchmarkContext {
- volatile ConfigurableApplicationContext context;
- volatile SleuthBenchmarkingSpringApp app;
-
- @Setup
- public void setup() {
- 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.app.clean();
- this.context.close();
- }
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.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.context.ConfigurableApplicationContext;
+
+import static org.assertj.core.api.BDDAssertions.then;
+
+@Measurement(iterations = 5, time = 1)
+@Warmup(iterations = 5, time = 1)
+@Fork(2)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Threads(Threads.MAX)
+@Microbenchmark
+public class AsyncWithoutSleuthBenchmarksTests {
+ @Benchmark
+ public void asyncMethodWithoutSleuth(BenchmarkContext context) throws Exception {
+ then(context.app.async().get()).isEqualTo("async");
+ }
+
+ @State(Scope.Benchmark)
+ public static class BenchmarkContext {
+ volatile ConfigurableApplicationContext context;
+ volatile SleuthBenchmarkingSpringApp app;
+
+ @Setup
+ public void setup() {
+ 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.app.clean();
+ this.context.close();
+ }
+
+ }
+
+}
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 91570bf0c..05b3a871f 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
@@ -1,187 +1,167 @@
-/*
- * 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.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.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.instrument.web.servlet.TracingFilter;
-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.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)
-@BenchmarkMode(Mode.SampleTime)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
-@Threads(Threads.MAX)
-@Microbenchmark
-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();
- response.setContentType(MediaType.APPLICATION_JSON_VALUE);
-
- context.tracingFilter.doFilter(request, response, new MockFilterChain());
- }
-
- @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");
- }
-
- 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 withSleuth;
-
- volatile DummyFilter dummyFilter = new DummyFilter();
-
- volatile TracingFilter tracingFilter;
-
- volatile MockMvc mockMvcForTracedController;
-
- 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.tracerImplementation.name());
- this.tracingFilter = this.withSleuth.getBean(TracingFilter.class);
- this.mockMvcForTracedController = MockMvcBuilders
- .standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)).build();
- this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build();
- }
-
- @TearDown
- public void clean() {
- this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean();
- this.withSleuth.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";
- }
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.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;
+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 HttpFilterBenchmarksTests {
+
+ @Benchmark
+ public void filterWithSleuth(BenchmarkContext context) throws ServletException, IOException {
+ MockHttpServletRequest request = builder().buildRequest(new MockServletContext());
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+
+ context.tracingFilter.doFilter(request, response, new MockFilterChain());
+ }
+
+ @Benchmark
+ public void asyncWithSleuth(BenchmarkContext context) throws Exception {
+ performRequest(context.mockMvcForTracedController, "bar", "bar");
+ }
+
+ 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 withSleuth;
+
+ volatile TracingFilter tracingFilter;
+
+ volatile MockMvc mockMvcForTracedController;
+
+ @Param
+ private TracerImplementation tracerImplementation;
+
+ @Setup
+ public void setup() {
+ this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false",
+
+ "--spring.application.name=withSleuth_" + this.tracerImplementation.name());
+ 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();
+ }
+
+ @TearDown
+ public void clean() {
+ this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean();
+ this.withSleuth.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/mvc/HttpFilterNoSleuthBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/HttpFilterNoSleuthBenchmarksTests.java
new file mode 100644
index 000000000..bbab91076
--- /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/mvc/RestTemplateBenchmarkTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java
index 6066b8274..a5ad1d1d5 100644
--- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/mvc/RestTemplateBenchmarkTests.java
@@ -1,111 +1,111 @@
-/*
- * 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.io.IOException;
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.ServletException;
-
-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.app.mvc.controller.AsyncSimulationController;
-import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation;
-import org.springframework.cloud.sleuth.instrument.web.mvc.TracingClientHttpRequestInterceptor;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.test.web.client.MockMvcClientHttpRequestFactory;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.web.client.RestTemplate;
-
-import static org.assertj.core.api.BDDAssertions.then;
-
-/**
- * We're checking how much overhead does the instrumentation of the RestTemplate take
- */
-@Measurement(iterations = 5, time = 1)
-@Warmup(iterations = 5, time = 1)
-@Fork(2)
-@BenchmarkMode(Mode.SampleTime)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
-@Threads(Threads.MAX)
-@Microbenchmark
-public class RestTemplateBenchmarkTests {
-
- @Benchmark
- 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 {
- then(context.tracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo");
- }
-
- @State(Scope.Benchmark)
- public static class BenchmarkContext {
-
- volatile ConfigurableApplicationContext withSleuth;
-
- volatile MockMvc mockMvc;
-
- volatile RestTemplate tracedTemplate;
-
- volatile RestTemplate untracedTemplate;
-
- @Param
- private TracerImplementation tracerImplementation;
-
- @Setup
- public void setup() {
- 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));
- }
-
- @TearDown
- public void clean() {
- this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean();
- this.withSleuth.close();
- }
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.Collections;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.ServletException;
+
+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.app.mvc.controller.AsyncSimulationController;
+import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation;
+import org.springframework.cloud.sleuth.instrument.web.mvc.TracingClientHttpRequestInterceptor;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.test.web.client.MockMvcClientHttpRequestFactory;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.client.RestTemplate;
+
+import static org.assertj.core.api.BDDAssertions.then;
+
+/**
+ * We're checking how much overhead does the instrumentation of the RestTemplate take
+ */
+@Measurement(iterations = 5, time = 1)
+@Warmup(iterations = 5, time = 1)
+@Fork(2)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Threads(Threads.MAX)
+@Microbenchmark
+public class RestTemplateBenchmarkTests {
+
+ @Benchmark
+ 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 {
+ then(context.tracedTemplate.getForObject("/foo", String.class)).isEqualTo("foo");
+ }
+
+ @State(Scope.Benchmark)
+ public static class BenchmarkContext {
+
+ volatile ConfigurableApplicationContext withSleuth;
+
+ volatile MockMvc mockMvc;
+
+ volatile RestTemplate tracedTemplate;
+
+ volatile RestTemplate untracedTemplate;
+
+ @Param
+ private TracerImplementation tracerImplementation;
+
+ @Setup
+ public void setup() {
+ 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));
+ }
+
+ @TearDown
+ public void clean() {
+ this.withSleuth.getBean(SleuthBenchmarkingSpringApp.class).clean();
+ this.withSleuth.close();
+ }
+
+ }
+
+}
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/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 6c332d407..bdc933410 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
@@ -1,192 +1,207 @@
-/*
- * 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.HashSet;
-import java.util.List;
-import java.util.Set;
-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.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 org.springframework.util.StringUtils;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@Measurement(iterations = 5, time = 1)
-@Warmup(iterations = 5, time = 1)
-@Fork(2)
-@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(instrumentation.entires.stream().map(s -> "--" + s).collect(Collectors.toList()));
- 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 {
-
- noSleuthSimple("spring.sleuth.enabled=false,spring.sleuth.function.type=simple"), sleuthSimple(
- "spring.sleuth.function.type=simple"), sleuthSimpleWithAround(
- "spring.sleuth.function.type=simple_function_with_around"), noSleuthReactiveSimple(
- "spring.sleuth.enabled=false,spring.sleuth.function.type=reactive_simple"), sleuthReactiveSimpleManual(
- "spring.sleuth.function.type=reactive_simple_manual"), sleuthReactiveSimpleOnEach(
- "spring.sleuth.reactor.instrumentation-type=DECORATE_ON_EACH,spring.sleuth.integration.enabled=true,spring.sleuth.function.type=DECORATE_ON_EACH"),
- // This won't work with messaging
- // sleuthReactiveSimpleOnLast("spring.sleuth.reactor.instrumentation-type=DECORATE_ON_LAST,spring.sleuth.function.type=DECORATE_ON_LAST"),
- // NO FUNCTION, NO INTEGRATION, MANUAL OPERATORS
- sleuthSimpleManual(
- "spring.sleuth.function.enabled=false,spring.sleuth.integration.enabled=false,spring.sleuth.function.type=simple_manual"), sleuthSimpleNoFunctionInstrumentationManual(
- "spring.sleuth.function.type=simple_manual,spring.sleuth.function.enabled=false,spring.sleuth.integration.enabled=true,spring.sleuth.reactor.instrumentation-type=MANUAL"), sleuthReactiveSimpleNoFunctionInstrumentationManual(
- "spring.sleuth.function.type=reactive_simple_manual,spring.sleuth.function.enabled=false,spring.sleuth.integration.enabled=true,spring.sleuth.reactor.instrumentation-type=MANUAL");
-
- 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 {
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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 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.Tracer;
+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");
+ }
+ assertThat(this.applicationContext.getBean(Tracer.class).currentSpan()).isNull();
+ }
+ }
+
+ @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")),
+ sleuthSimpleOnQueues(function("simple"), Pair.onHook()),
+ sleuthSimpleManual(function("simple_manual"), Pair.manual(), functionDisabled(), integrationDisabled()),
+ sleuthSimpleNoFunctionInstrumentationManual(function("simple_manual"), Pair.manual(), functionDisabled(), integrationEnabled()),
+ sleuthSimpleOnEach(function("simple"), Pair.onEach()),
+ sleuthSimpleOnLast(function("simple"), Pair.onLast()),
+ sleuthSimpleWithAroundOnQueues(function("simple_function_with_around")),
+ noSleuthReactiveSimple(function("reactive_simple"), Pair.noSleuth()),
+ 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());
+ // @formatter:on
+
+ private final List pairs;
+
+ Instrumentation(Pair... pairs) {
+ this.pairs = Arrays.asList(pairs);
+ }
+
+ String[] asParams() {
+ return this.pairs.stream().map(p -> "--" + p.asProp()).toArray(String[]::new);
+ }
+
+ static Pair function(String type) {
+ return Pair.of("spring.sleuth.function.type", type);
+ }
+
+ static Pair integrationEnabled() {
+ return Pair.of("spring.sleuth.integration.enabled", "true");
+ }
+
+ static Pair integrationDisabled() {
+ return Pair.of("spring.sleuth.integration.enabled", "false");
+ }
+
+ static Pair functionDisabled() {
+ return Pair.of("spring.sleuth.function.enabled", "false");
+ }
+ }
+
+ }
+
+ @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
index 89ed7c443..b7913e07e 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
@@ -1,143 +1,156 @@
-/*
- * 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.concurrent.TimeUnit;
-
-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.TracerImplementation;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.test.web.reactive.server.WebTestClient;
-
-@Measurement(iterations = 5, time = 1)
-@Warmup(iterations = 5, time = 1)
-@Fork(2)
-@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() {
- return new String[] { "--spring.jmx.enabled=false",
- "--spring.application.name=defaultTraceContext" + instrumentation.name() + "_"
- + tracerImplementation.name(),
- "--" + instrumentation.key + "=" + instrumentation.value };
- }
-
- 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 {
-
- noSleuthSimple("spring.sleuth.enabled", "false", "/simple"), sleuthSimpleManual(
- "spring.sleuth.reactor.instrumentation-type", "MANUAL",
- "/simple"), sleuthManual("spring.sleuth.reactor.instrumentation-type", "MANUAL",
- "/simpleManual"), sleuthSimpleOnEach("spring.sleuth.reactor.instrumentation-type",
- "DECORATE_ON_EACH",
- "/simple"), sleuthSimpleOnLast("spring.sleuth.reactor.instrumentation-type",
- "DECORATE_ON_LAST", "/simple"), noSleuthComplex("spring.sleuth.enabled",
- "false", "/complexNoSleuth"), onEachComplex(
- "spring.sleuth.reactor.instrumentation-type",
- "DECORATE_ON_EACH", "/complex"), onLastComplex(
- "spring.sleuth.reactor.instrumentation-type",
- "DECORATE_ON_LAST", "/complex"), onManualComplex(
- "spring.sleuth.reactor.instrumentation-type",
- "MANUAL", "/complexManual");
-
- private String key;
-
- private String value;
-
- private String url;
-
- Instrumentation(String key, String value, String url) {
- this.key = key;
- this.value = value;
- this.url = url;
- }
-
- }
-
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.Tracer;
+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;
+
+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 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();
+ 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
+ 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()),
+ onQueuesSimple("/simple", Pair.onHook()),
+ onManualSimple("/simpleManual", Pair.manual()),
+ onEachSimple("/simple", Pair.onEach()),
+ onLastSimple("/simple", Pair.onLast()),
+ noSleuthComplex("/complexNoSleuth", Pair.noSleuth()),
+ onQueueComplex("/complex", Pair.onHook()),
+ onManualComplex("/complexManual", Pair.manual()),
+ onEachComplex("/complex", Pair.onEach()),
+ onLastComplex("/complex", 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/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java
index b7c7719af..1776ab3f6 100644
--- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/SpringWebFluxBenchmarksTests.java
@@ -1,183 +1,183 @@
-/*
- * 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.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-import brave.Tracing;
-import brave.handler.SpanHandler;
-import brave.http.HttpTracing;
-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;
-import org.apache.http.util.EntityUtils;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Fork;
-import org.openjdk.jmh.annotations.Measurement;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.TearDown;
-import org.openjdk.jmh.annotations.Threads;
-import org.openjdk.jmh.annotations.Warmup;
-import org.openjdk.jmh.runner.Runner;
-import org.openjdk.jmh.runner.RunnerException;
-import org.openjdk.jmh.runner.options.Options;
-import org.openjdk.jmh.runner.options.OptionsBuilder;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.WebApplicationType;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.cloud.sleuth.benchmarks.app.webflux.SleuthBenchmarkingSpringWebFluxApp;
-import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation;
-import org.springframework.context.ConfigurableApplicationContext;
-
-@Measurement(iterations = 5, time = 1)
-@Warmup(iterations = 5, time = 1)
-@Fork(2)
-@BenchmarkMode(Mode.SampleTime)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
-@Threads(2)
-@State(Scope.Benchmark)
-@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 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(".*" + SpringWebFluxBenchmarksTests.class.getSimpleName() + ".*")
- .build();
-
- new Runner(opt).run();
- }
-
- public String getBaseUrl() {
- return baseUrl;
- }
-
- protected CloseableHttpClient newClient(HttpTracing httpTracing) {
- return TracingHttpClientBuilder.create(httpTracing).disableAutomaticRetries().build();
- }
-
- protected CloseableHttpClient newClient() {
- return HttpClients.custom().disableAutomaticRetries().build();
- }
-
- protected void get(CloseableHttpClient client) throws Exception {
- EntityUtils.consume(client.execute(new HttpGet(getBaseUrl())).getEntity());
- }
-
- protected void close(CloseableHttpClient client) throws IOException {
- client.close();
- }
-
- @Setup
- public void setup() {
- ConfigurableApplicationContext context = initContext();
- this.applicationContext = context;
- this.springWebFluxApp = this.applicationContext.getBean(SleuthBenchmarkingSpringWebFluxApp.class);
- baseUrl = "http://127.0.0.1:" + springWebFluxApp.port + "/foo";
- client = newClient();
- tracedClient = newClient(HttpTracing.create(Tracing.newBuilder().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();
- customSpringApplication(application);
- return application.run(runArgs());
- }
-
- protected void customSpringApplication(SpringApplication springApplication) {
-
- }
-
- protected void postSetUp() {
- }
-
- protected String[] runArgs() {
- return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext",
- TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true" };
- }
-
- @TearDown
- public void clean() throws Exception {
- close(client);
- close(unsampledClient);
- close(tracedClient);
- Tracing.current().close();
- try {
-
- this.applicationContext.close();
- }
- catch (Exception ig) {
-
- }
- }
-
- @Benchmark
- public void client_get() throws Exception {
- get(client);
- }
-
- @Benchmark
- public void unsampledClient_get() throws Exception {
- get(unsampledClient);
- }
-
- @Benchmark
- public void tracedClient_get() throws Exception {
- get(tracedClient);
- }
-
- @Benchmark
- public void tracedClient_get_resumeTrace() throws Exception {
- try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext().newScope(defaultTraceContext)) {
- get(tracedClient);
- }
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import brave.Tracing;
+import brave.handler.SpanHandler;
+import brave.http.HttpTracing;
+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;
+import org.apache.http.util.EntityUtils;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.cloud.sleuth.benchmarks.app.webflux.SleuthBenchmarkingSpringWebFluxApp;
+import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation;
+import org.springframework.context.ConfigurableApplicationContext;
+
+@Measurement(iterations = 5, time = 1)
+@Warmup(iterations = 5, time = 1)
+@Fork(2)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Threads(2)
+@State(Scope.Benchmark)
+@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 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(".*" + SpringWebFluxBenchmarksTests.class.getSimpleName() + ".*")
+ .build();
+
+ new Runner(opt).run();
+ }
+
+ public String getBaseUrl() {
+ return baseUrl;
+ }
+
+ protected CloseableHttpClient newClient(HttpTracing httpTracing) {
+ return TracingHttpClientBuilder.create(httpTracing).disableAutomaticRetries().build();
+ }
+
+ protected CloseableHttpClient newClient() {
+ return HttpClients.custom().disableAutomaticRetries().build();
+ }
+
+ protected void get(CloseableHttpClient client) throws Exception {
+ EntityUtils.consume(client.execute(new HttpGet(getBaseUrl())).getEntity());
+ }
+
+ protected void close(CloseableHttpClient client) throws IOException {
+ client.close();
+ }
+
+ @Setup
+ public void setup() {
+ ConfigurableApplicationContext context = initContext();
+ this.applicationContext = context;
+ this.springWebFluxApp = this.applicationContext.getBean(SleuthBenchmarkingSpringWebFluxApp.class);
+ baseUrl = "http://127.0.0.1:" + springWebFluxApp.port + "/foo";
+ client = newClient();
+ tracedClient = newClient(HttpTracing.create(Tracing.newBuilder().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();
+ customSpringApplication(application);
+ return application.run(runArgs());
+ }
+
+ protected void customSpringApplication(SpringApplication springApplication) {
+
+ }
+
+ protected void postSetUp() {
+ }
+
+ protected String[] runArgs() {
+ return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext",
+ TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true" };
+ }
+
+ @TearDown
+ public void clean() throws Exception {
+ close(client);
+ close(unsampledClient);
+ close(tracedClient);
+ Tracing.current().close();
+ try {
+
+ this.applicationContext.close();
+ }
+ catch (Exception ig) {
+
+ }
+ }
+
+ @Benchmark
+ public void client_get() throws Exception {
+ get(client);
+ }
+
+ @Benchmark
+ public void unsampledClient_get() throws Exception {
+ get(unsampledClient);
+ }
+
+ @Benchmark
+ public void tracedClient_get() throws Exception {
+ get(tracedClient);
+ }
+
+ @Benchmark
+ public void tracedClient_get_resumeTrace() throws Exception {
+ try (CurrentTraceContext.Scope scope = Tracing.current().currentTraceContext().newScope(defaultTraceContext)) {
+ get(tracedClient);
+ }
+ }
+
+}
diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java
index 3629040a1..93f35d8a2 100644
--- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutReactorSleuthSpringWebFluxBenchmarksTests.java
@@ -1,54 +1,54 @@
-/*
- * 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 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
- */
-@Microbenchmark
-public class WithOutReactorSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests {
-
- public static void main(String[] args) throws RunnerException {
- 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",
- TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true",
- "--spring.sleuth.reactor.enabled=false"
-
- };
- }
-
- @Override
- protected void postSetUp() {
- super.postSetUp();
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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 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
+ */
+@Microbenchmark
+public class WithOutReactorSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests {
+
+ public static void main(String[] args) throws RunnerException {
+ 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",
+ TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true",
+ "--spring.sleuth.reactor.enabled=false"
+
+ };
+ }
+
+ @Override
+ protected void postSetUp() {
+ super.postSetUp();
+ }
+
+}
diff --git a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java
index 8185d0c20..f609fd615 100644
--- a/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java
+++ b/benchmarks/src/test/java/org/springframework/cloud/sleuth/benchmarks/jmh/webflux/WithOutSleuthSpringWebFluxBenchmarksTests.java
@@ -1,51 +1,51 @@
-/*
- * 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 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
- */
-@Microbenchmark
-public class WithOutSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests {
-
- public static void main(String[] args) throws RunnerException {
- 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",
- TracerImplementation.brave.toString(), "--spring.sleuth.enabled=false" };
- }
-
- @Override
- protected void postSetUp() {
- super.postSetUp();
- }
-
-}
+/*
+ * Copyright 2013-2021 the original author 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 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
+ */
+@Microbenchmark
+public class WithOutSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenchmarksTests {
+
+ public static void main(String[] args) throws RunnerException {
+ 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",
+ TracerImplementation.brave.toString(), "--spring.sleuth.enabled=false" };
+ }
+
+ @Override
+ protected void postSetUp() {
+ super.postSetUp();
+ }
+
+}
diff --git a/docs/pom.xml b/docs/pom.xml
index 03a3c3b77..cf86faac6 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -21,7 +21,7 @@
org.springframework.cloud
spring-cloud-sleuth
- 3.0.2-SNAPSHOT
+ 3.1.0-SNAPSHOT
spring-cloud-sleuth-docs
jar
diff --git a/docs/src/main/asciidoc/_configprops.adoc b/docs/src/main/asciidoc/_configprops.adoc
index 44d2be68d..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}.
@@ -62,6 +66,7 @@
|spring.sleuth.web.webclient.enabled | `true` | Enable tracing instrumentation for WebClient.
|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.
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/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.
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/integrations.adoc b/docs/src/main/asciidoc/integrations.adoc
index 2313adf7f..322c2ff23 100644
--- a/docs/src/main/asciidoc/integrations.adoc
+++ b/docs/src/main/asciidoc/integrations.adoc
@@ -1,568 +1,594 @@
-[[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 three modes of instrumenting reactor based applications that can be set via `spring.sleuth.reactor.instrumentation-type` property:
-
-* `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.
-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.
-In order to disable this instrumentation set `spring.sleuth.circuitbreaker.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`.
+
+
+[[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/docs/src/main/asciidoc/legal.adoc b/docs/src/main/asciidoc/legal.adoc
index cc02760e7..8d6a7e9ad 100644
--- a/docs/src/main/asciidoc/legal.adoc
+++ b/docs/src/main/asciidoc/legal.adoc
@@ -3,6 +3,6 @@
{project-version}
-Copyright © 2012-2020
+Copyright © 2012-2021
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
\ No newline at end of file
diff --git a/docs/src/main/asciidoc/project-features.adoc b/docs/src/main/asciidoc/project-features.adoc
index 63201f262..fb84d25c7 100644
--- a/docs/src/main/asciidoc/project-features.adoc
+++ b/docs/src/main/asciidoc/project-features.adoc
@@ -316,6 +316,13 @@ object, you will have to create a bean of `zipkin2.reporter.Sender` type.
}
----
+By default, api path will be set to `api/v2/spans` or `api/v1/spans` depending on the encoder version. If you want to use a custom api path, you can configure it using the following property (empty case, set ""):
+
+[source,yaml]
+----
+spring.zipkin.api-path: v2/path2
+----
+
[[features-zipkin-custom-service-name]]
=== Custom service name
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]
diff --git a/pom.xml b/pom.xml
index baa7df39c..7a970cd8d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,442 +1,474 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth
- 3.0.2-SNAPSHOT
- pom
- Spring Cloud Sleuth
- Spring Cloud Sleuth
-
-
- org.springframework.cloud
- spring-cloud-build
- 3.0.2-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.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
- 1.3.3
- 2.6.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
-
-
-
-
-
-
- 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.security.oauth.boot
- spring-security-oauth2-autoconfigure
- ${spring-security-boot-autoconfigure.version}
- true
-
-
- com.wavefront
- wavefront-runtime-sdk-jvm
- ${wavefront-runtime-sdk-jvm.version}
- true
-
-
- com.wavefront
- wavefront-sdk-java
- ${wavefront-sdk-java.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}
-
-
-
-
-
-
- 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
+ 1.3.3
+ 2.6.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
+
+
+ com.wavefront
+ wavefront-runtime-sdk-jvm
+ ${wavefront-runtime-sdk-jvm.version}
+ true
+
+
+ com.wavefront
+ wavefront-sdk-java
+ ${wavefront-sdk-java.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-api/pom.xml b/spring-cloud-sleuth-api/pom.xml
index 9fb4fbeb6..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.2-SNAPSHOT
+ 3.1.0-SNAPSHOT
..
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java
index 268aaff40..70f56a5fd 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageInScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java
index 459f071e4..861ae6843 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/BaggageManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java
index c92c7d910..aaece67cb 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/CurrentTraceContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java
index ded583cea..6edbe35fc 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SamplerFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java
index 44ea086d3..adf4696b2 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/ScopedSpan.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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 769f7a3c9..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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-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..807e871c6
--- /dev/null
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanAndScope.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;
+
+/**
+ * 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;
+ }
+
+ @Override
+ public String toString() {
+ return "SpanAndScope{" + "span=" + this.span + '}';
+ }
+
+}
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java
index 8b8718103..a00a108fb 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanCustomizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java
index d80e95650..44b17e55d 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java
index e75deb94f..f0cee8e44 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/SpanNamer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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-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 65157b0df..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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 86a027864..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java
index eebe14a22..f9f625fc0 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/ContinueSpan.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java
index f68660794..28d9114aa 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpan.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java
index bd2d3ffb5..eb4791aed 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NewSpanParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java
index 82e021172..70a91420a 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java
index a6fd706d4..9bfbed59b 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthMethodInvocationProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java
index d56a3c9b9..ba812c4fe 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTag.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java
index 8342a1d3f..662eeeeff 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueExpressionResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java
index f5708c46a..8fde99e03 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/annotation/TagValueResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java
index 12a5293c1..0c39356ca 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/autoconfig/SingleSkipPattern.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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..5daee0411 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java
index 756b3e044..4b1432ab1 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java
index 49a7b8d50..d38cb659b 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java
index 5aac0f7f9..afe0fd92a 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java
index ea5d9fa9f..22b5c037b 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java
index 99ffa6f87..3c356f2e1 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpClientResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java
index 2fa3ce7d4..890257d33 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java
index 4edd2c055..001f477fa 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpRequestParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java
index f8b2fc8ee..2c7be8917 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java
index eef2026fc..ac129315d 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpResponseParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java
index 47c4f5b20..9d65b65d2 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java
index 3da043e2c..93f97211d 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java
index 4c76251e7..76acc57e3 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/HttpServerResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java
index ea7af4287..bd371523a 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Request.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java
index 4f74be603..8fffaec45 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/http/Response.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java
index bdedb6de0..dfa72c8ba 100644
--- a/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java
+++ b/spring-cloud-sleuth-api/src/main/java/org/springframework/cloud/sleuth/propagation/Propagator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java
index 434c404af..53b9421e7 100644
--- a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java
+++ b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/ArchitectureTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java
index 75ce679cd..0fa85b175 100644
--- a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java
+++ b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/annotation/NoOpTagValueResolverTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java
index 3a3a14172..7814b8f8a 100644
--- a/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java
+++ b/spring-cloud-sleuth-api/src/test/java/org/springframework/cloud/sleuth/exporter/SpanIgnoringSpanFilterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/pom.xml b/spring-cloud-sleuth-autoconfigure/pom.xml
index 68a1dac05..525554657 100644
--- a/spring-cloud-sleuth-autoconfigure/pom.xml
+++ b/spring-cloud-sleuth-autoconfigure/pom.xml
@@ -1,446 +1,478 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth-autoconfigure
- jar
- Spring Cloud Sleuth AutoConfigure
- Spring Cloud Sleuth AutoConfigure
-
-
- org.springframework.cloud
- spring-cloud-sleuth
- 3.0.2-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-function-context
- true
-
-
- org.springframework.boot
- spring-boot-starter-websocket
- true
-
-
- org.springframework.cloud
- spring-cloud-stream
- 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.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
-
-
-
-
-
-
- com.wavefront
- wavefront-runtime-sdk-jvm
- true
-
-
- com.wavefront
- wavefront-sdk-java
- true
-
-
- io.micrometer
- micrometer-registry-wavefront
- true
-
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.awaitility
- awaitility
- 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.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
+
+
+
+
+
+
+ com.wavefront
+ wavefront-runtime-sdk-jvm
+ true
+
+
+ com.wavefront
+ wavefront-sdk-java
+ true
+
+
+ io.micrometer
+ micrometer-registry-wavefront
+ true
+
+
+
+
+ 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/SleuthAnnotationConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthAnnotationConfiguration.java
index 1d5062634..6782c9d15 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthAnnotationConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthAnnotationConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java
index da35ebf8b..9f629e987 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthBaggageProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java
index b697c706e..db087d4eb 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthOpentracingProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java
index 5c53b92c5..03332866b 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthSpanFilterProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java
index 1c0ff46e5..e06e55c06 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/SleuthTracerProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java
index a55d2c28a..9d286d8fb 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java
index 56d3879ba..bbcb203fc 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceEnvironmentPostProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java
index 7b27b25d6..123f337b3 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java
index ced1f1a6c..e307d2b3d 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBaggageConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java
index 44005ed02..cefcd9574 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveBridgeConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java
index 1369a02e2..0bf5498a2 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/BraveSamplerConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java
index a74ed8636..2436b62d7 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/ConditionalOnBraveEnabled.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java
index 3f5284399..850854f71 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerCondition.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java
index ca0968ecf..7fbafc457 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SamplerProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java
index e2ecffea0..af02e84de 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthPropagationProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java
index 39dc6aaa9..92e635faa 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/SleuthProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java
index d671441b9..b14dce503 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/grpc/BraveGrpcAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java
index 4e5068bb7..80995e822 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveKafkaStreamsAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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 0da77fc78..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/mongodb/BraveMongoDbAutoConfiguration.java
index bb119746a..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import org.springframework.boot.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/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java
index 6e8048e0b..717469501 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/opentracing/BraveOpentracingAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java
index a88eae66d..22cbb4049 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/BraveRedisAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java
index 3350917e8..16fa29c1f 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/redis/TraceRedisProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java
index 2bb708d81..25d54ca60 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java
index 4fedd8f34..566ceb97c 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/BraveHttpBridgeConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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 6e355fe7a..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java
index ee98c220e..49f5b35fd 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/web/client/BraveWebClientAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java
index d15f15679..ee90fcd47 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/ExecutorBeanPostProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java
index 2aac2a055..b86ec4328 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/SleuthAsyncProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java
index 4605e0c53..ae57cea49 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java
index 4ac599fd4..dcf398ac2 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncCustomAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java
index ae9ecffd2..0fa6d75f0 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/async/TraceAsyncDefaultAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java
index f18e802d4..52055d5c5 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/circuitbreaker/SleuthCircuitBreakerProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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 7684a9b50..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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-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/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/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java
index 86d5a7477..1b16803cc 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/SleuthIntegrationMessagingProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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 fca89b281..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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/TraceFunctionAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceFunctionAutoConfiguration.java
index 1b9b03342..f0ec48468 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceFunctionAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceFunctionAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java
index ff2f75d8d..2758e00fa 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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 084e6ccf1..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author 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,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/messaging/TraceWebSocketAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfiguration.java
index 313e3d9d9..694c75400 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/messaging/TraceWebSocketAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java
index 24c3e9f4e..b13262208 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/quartz/TraceQuartzAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java
index 0c22d1eaf..bb1810243 100644
--- a/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java
+++ b/spring-cloud-sleuth-autoconfigure/src/main/java/org/springframework/cloud/sleuth/autoconfig/instrument/reactor/SleuthReactorProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
/**
* Sleuth Reactor settings.
@@ -58,6 +59,8 @@ public class SleuthReactorProperties {
this.enabled = enabled;
}
+ @DeprecatedConfigurationProperty(reason = "An enum is a more clear solution",
+ replacement = "spring.sleuth.reactor.instrumentation-type=DECORATE_ON_EACH")
@Deprecated
public boolean isDecorateOnEach() {
warn();
@@ -86,6 +89,13 @@ public class SleuthReactorProperties {
public enum InstrumentationType {
+ /**
+ * Uses the new decorate queues feature from Project Reactor. Should allow the
+ * feature set of {@link InstrumentationType#DECORATE_ON_EACH} with the least
+ * impact on the performance.
+ */
+ DECORATE_QUEUES,
+
/**
* Decorates on each operator, will be less performing, but logging will always
* contain the tracing entries in each operator.
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 e81b12d70..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
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2020 the original author or authors.
+ * Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,13 @@ package org.springframework.cloud.sleuth.autoconfig.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 brave.propagation.CurrentTraceContext;
+import brave.propagation.TraceContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.reactivestreams.Publisher;
@@ -47,6 +52,7 @@ 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.autoconfig.instrument.reactor.TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY;
import static org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration.TraceReactorConfiguration.SLEUTH_TRACE_REACTOR_KEY;
@@ -78,6 +84,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;
@@ -91,6 +99,10 @@ public class TraceReactorAutoConfiguration {
return new HookRegisteringBeanDefinitionRegistryPostProcessor(context);
}
+ private static boolean isQueueWrapperOnTheClasspath() {
+ return ReflectionUtils.findMethod(Hooks.class, "addQueueWrapper", String.class, Function.class) != null;
+ }
+
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RefreshScope.class)
static class HooksRefresherConfiguration {
@@ -127,8 +139,19 @@ class HooksRefresher implements ApplicationListener
}
Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY);
Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY);
- Hooks.resetOnLastOperator(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY);
+ Hooks.removeQueueWrapper(SLEUTH_TRACE_REACTOR_KEY);
+ Schedulers.resetOnScheduleHook(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY);
switch (this.reactorProperties.getInstrumentationType()) {
+ case DECORATE_QUEUES:
+ if (TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH) {
+ if (log.isTraceEnabled()) {
+ 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));
+ }
case DECORATE_ON_EACH:
if (log.isTraceEnabled()) {
log.trace("Decorating onEach operator instrumentation");
@@ -178,26 +201,45 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor implements BeanDefiniti
SleuthReactorProperties.InstrumentationType property = environment.getProperty(
"spring.sleuth.reactor.instrumentation-type", SleuthReactorProperties.InstrumentationType.class,
SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH);
- Boolean decorateOnEach = environment.getProperty("spring.sleuth.reactor.decorate-on-each", Boolean.class, true);
- if (!decorateOnEach) {
+ if (wrapperNotOnClasspathHooksPropertyTurnedOn(property)) {
log.warn(
- "You're using the deprecated [spring.sleuth.reactor.decorate-on-each] property. Please use the [spring.sleuth.reactor.instrumentation-type] one instead.");
- decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext));
+ "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.4.3). Will fall back to the previous reactor instrumentation mode");
+ property = SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH;
}
- else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH) {
- decorateOnEach(springContext);
- decorateOnLast(onLastOperatorForOnEachInstrumentation(springContext));
- decorateScheduler(springContext);
- }
- else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_LAST) {
+ if (property == SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES) {
+ addQueueWrapper(springContext);
decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext));
decorateScheduler(springContext);
}
- else if (property == SleuthReactorProperties.InstrumentationType.MANUAL) {
- decorateOnLast(ReactorSleuth.springContextSpanOperator(springContext));
+ else {
+ Boolean decorateOnEach = environment.getProperty("spring.sleuth.reactor.decorate-on-each", Boolean.class,
+ true);
+ if (!decorateOnEach) {
+ log.warn(
+ "You're using the deprecated [spring.sleuth.reactor.decorate-on-each] property. Please use the [spring.sleuth.reactor.instrumentation-type] one instead.");
+ decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext));
+ }
+ else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_EACH) {
+ decorateOnEach(springContext);
+ decorateOnLast(onLastOperatorForOnEachInstrumentation(springContext));
+ decorateScheduler(springContext);
+ }
+ else if (property == SleuthReactorProperties.InstrumentationType.DECORATE_ON_LAST) {
+ decorateOnLast(ReactorSleuth.scopePassingSpanOperator(springContext));
+ decorateScheduler(springContext);
+ }
+ else if (property == SleuthReactorProperties.InstrumentationType.MANUAL) {
+ decorateOnLast(ReactorSleuth.springContextSpanOperator(springContext));
+ }
}
}
+ private static boolean wrapperNotOnClasspathHooksPropertyTurnedOn(
+ SleuthReactorProperties.InstrumentationType property) {
+ return property == SleuthReactorProperties.InstrumentationType.DECORATE_QUEUES
+ && !TraceReactorAutoConfiguration.TraceReactorConfiguration.IS_QUEUE_WRAPPER_ON_THE_CLASSPATH;
+ }
+
private static void decorateScheduler(ConfigurableApplicationContext springContext) {
Schedulers.onScheduleHook(TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY,
ReactorSleuth.scopePassingOnScheduleHook(springContext));
@@ -218,6 +260,13 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor implements BeanDefiniti
ReactorSleuth.onEachOperatorForOnEachInstrumentation(springContext));
}
+ static void addQueueWrapper(ConfigurableApplicationContext springContext) {
+ if (log.isTraceEnabled()) {
+ log.trace("Decorating queues");
+ }
+ Hooks.addQueueWrapper(SLEUTH_TRACE_REACTOR_KEY, queue -> traceQueue(springContext, queue));
+ }
+
@Override
public void close() throws IOException {
if (log.isTraceEnabled()) {
@@ -225,7 +274,97 @@ class HookRegisteringBeanDefinitionRegistryPostProcessor implements BeanDefiniti
}
Hooks.resetOnEachOperator(SLEUTH_TRACE_REACTOR_KEY);
Hooks.resetOnLastOperator(SLEUTH_TRACE_REACTOR_KEY);
+ Hooks.removeQueueWrapper(SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY);
Schedulers.resetOnScheduleHook(TraceReactorAutoConfiguration.SLEUTH_REACTOR_EXECUTOR_SERVICE_KEY);
}
+ 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