Bump to 3.1.x

This commit is contained in:
Marcin Grzejszczak
2021-04-29 14:53:36 +02:00
720 changed files with 18498 additions and 9153 deletions

View File

@@ -1,5 +1,9 @@
root = true
[*]
end_of_line = crlf
insert_final_newline = true
[*.java]
indent_style = tab
indent_size = 4

View File

@@ -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.

View File

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

View File

@@ -22,13 +22,13 @@
<name>Benchmarks</name>
<description>Benchmarks (JMH)</description>
<groupId>org.springframework.cloud</groupId>
<version>3.0.2-SNAPSHOT</version>
<version>3.1.0-SNAPSHOT</version>
<artifactId>benchmarks</artifactId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<version>2.4.5-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
@@ -41,7 +41,7 @@
<okhttp.version>4.9.0</okhttp.version>
<microbenchmark-runner.version>0.2.0.RELEASE</microbenchmark-runner.version>
<jmh.version>1.26</jmh.version>
<spring-cloud-stream.version>3.1.1-SNAPSHOT</spring-cloud-stream.version>
<spring-cloud-stream.version>3.1.3-SNAPSHOT</spring-cloud-stream.version>
</properties>
<dependencyManagement>

View File

@@ -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<ServletWebServerInitializedEvent> {
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<String> 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<ServletWebServerInitializedEvent> {
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<String> 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;
}
}

View File

@@ -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<byte[]> 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<String, String> simple() {
log.info("simple_function");
return new SimpleFunction();
}
@Bean(name = "myFlux")
@ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple")
public Function<Flux<String>, Flux<String>> 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<String>, Message<String>> 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<String>, Message<String>> 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<Message<String>>, Flux<Message<String>>> 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<String, String> 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<String>, Flux<String>> 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<String>, Flux<String>> onLastFunction() {
log.info("on last function");
return new SleuthFunction();
}
}
class SimpleFunction implements Function<String, String> {
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<String>, Flux<String>> {
private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class);
@Override
public Flux<String> apply(Flux<String> input) {
return input.doOnNext(s -> log.info("Hello from simple [{}]", s)).map(String::toUpperCase);
}
}
class SimpleManualFunction implements Function<Message<String>, Message<String>> {
private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class);
private final BeanFactory beanFactory;
SimpleManualFunction(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Message<String> apply(Message<String> 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<String>, Message<String>> {
private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class);
@Override
public Message<String> apply(Message<String> input) {
log.info("Hello from message simple [{}]", input.getPayload());
return MessageBuilder.withPayload(input.getPayload().toUpperCase()).build();
}
}
// tag::simple_reactive[]
class SimpleReactiveManualFunction implements Function<Flux<Message<String>>, Flux<Message<String>>> {
private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class);
private final BeanFactory beanFactory;
SimpleReactiveManualFunction(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Flux<Message<String>> apply(Flux<Message<String>> 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<String, String> {
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<String>, Flux<String>> {
private static final Logger log = LoggerFactory.getLogger(SleuthFunction.class);
static final Scheduler SCHEDULER = Schedulers.newParallel("sleuthFunction");
@Override
public Flux<String> apply(Flux<String> 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<byte[]> 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<String, String> simple() {
log.info("simple_function");
return new SimpleFunction();
}
@Bean(name = "myFlux")
@ConditionalOnProperty(value = "spring.sleuth.function.type", havingValue = "reactive_simple")
public Function<Flux<String>, Flux<String>> 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<String>, Message<String>> 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<String>, Message<String>> 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<Message<String>>, Flux<Message<String>>> 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<String, String> 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<String>, Flux<String>> 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<String>, Flux<String>> 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<String>, Flux<String>> onLastFunction() {
log.info("on last function");
return new SleuthFunction();
}
}
class SimpleFunction implements Function<String, String> {
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<String>, Flux<String>> {
private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class);
@Override
public Flux<String> apply(Flux<String> input) {
return input.doOnNext(s -> log.info("Hello from simple [{}]", s)).map(String::toUpperCase);
}
}
class SimpleManualFunction implements Function<Message<String>, Message<String>> {
private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class);
private final BeanFactory beanFactory;
SimpleManualFunction(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Message<String> apply(Message<String> 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<String>, Message<String>> {
private static final Logger log = LoggerFactory.getLogger(SimpleFunction.class);
@Override
public Message<String> apply(Message<String> input) {
log.info("Hello from message simple [{}]", input.getPayload());
return MessageBuilder.withPayload(input.getPayload().toUpperCase()).build();
}
}
// tag::simple_reactive[]
class SimpleReactiveManualFunction implements Function<Flux<Message<String>>, Flux<Message<String>>> {
private static final Logger log = LoggerFactory.getLogger(SimpleReactiveFunction.class);
private final BeanFactory beanFactory;
SimpleReactiveManualFunction(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Flux<Message<String>> apply(Flux<Message<String>> 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<String, String> {
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<String>, Flux<String>> {
private static final Logger log = LoggerFactory.getLogger(SleuthFunction.class);
static final Scheduler SCHEDULER = Schedulers.newParallel("sleuthFunction");
@Override
public Flux<String> apply(Flux<String> 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();
}));
}
}

View File

@@ -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<ReactiveWebServerInitializedEvent> {
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<String> 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<String> simple() {
return Mono.just("hello").map(String::toUpperCase).doOnNext(s -> log.info("Hello from simple [{}]", s));
}
// tag::simple_manual[]
@GetMapping("/simpleManual")
public Mono<String> 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<String> 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<String> 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<String> 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<ReactiveWebServerInitializedEvent> {
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<String> 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<String> simple() {
return Mono.just("hello").map(String::toUpperCase).doOnNext(s -> log.info("Hello from simple [{}]", s));
}
// tag::simple_manual[]
@GetMapping("/simpleManual")
public Mono<String> 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<String> 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<String> 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<String> 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");
});
}
}

View File

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

View File

@@ -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.

View File

@@ -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<String> 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<byte[]> 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<String> 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<String> 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<byte[]> 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<String> 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 {
}
}

View File

@@ -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.

View File

@@ -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.

View File

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

View File

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

View File

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

View File

@@ -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<String> 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<String> vanilla() {
return () -> "vanilla";
}
}
}

View File

@@ -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<String> vanilla() {
return () -> "vanilla";
}
}
}

View File

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

View File

@@ -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.

View File

@@ -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<String> 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<byte[]> 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<String> 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<String> 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<byte[]> 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<Pair> 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 {
}
}

View File

@@ -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<String> 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<Pair> 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]);
}
}
}
}

View File

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

View File

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

View File

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

View File

@@ -21,7 +21,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth</artifactId>
<version>3.0.2-SNAPSHOT</version>
<version>3.1.0-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-sleuth-docs</artifactId>
<packaging>jar</packaging>

View File

@@ -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.

View File

@@ -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.adoc#legal,Legal>> :: Legal information.
<<documentation-overview.adoc#sleuth-documentation-about,Documentation Overview>> :: About the Documentation, Getting Help, First Steps, and more.
<<getting-started.adoc#getting-started,Getting Started>> :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application
<<using.adoc#using,Using {project-full-name}>> :: {project-full-name} usage examples and workflows.
<<project-features.adoc#features,{project-full-name} Features>> :: Span creation, context propagation, and more.
<<howto.adoc#howto,"`How-to`" Guides>> :: Add sampling, propagate remote tags, and more.
<<integrations.adoc#sleuth-integration,{project-full-name} Integrations>> :: Instrumentation configuration, context propagation, and more.
<<appendix.adoc#appendix,Appendices>> :: Configuration properties.

View File

@@ -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]

View File

@@ -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]

View File

@@ -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.
You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` module.

View File

@@ -0,0 +1 @@
spring-cloud-sleuth.adoc

View File

@@ -1 +0,0 @@
include::_index.adoc[]

View File

@@ -0,0 +1 @@
spring-cloud-sleuth.adoc

View File

@@ -1 +0,0 @@
include::_index_single.adoc[]

View File

@@ -0,0 +1 @@
spring-cloud-sleuth.htmlsingleadoc

View File

@@ -0,0 +1 @@
spring-cloud-sleuth.pdfadoc

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,6 @@
{project-version}
Copyright &#169; 2012-2020
Copyright &#169; 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.

View File

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

View File

@@ -1 +0,0 @@
index.htmladoc

View File

@@ -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.adoc#legal,Legal>> :: Legal information.
<<documentation-overview.adoc#sleuth-documentation-about,Documentation Overview>> :: About the Documentation, Getting Help, First Steps, and more.
<<getting-started.adoc#getting-started,Getting Started>> :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application
<<using.adoc#using,Using {project-full-name}>> :: {project-full-name} usage examples and workflows.
<<project-features.adoc#features,{project-full-name} Features>> :: Span creation, context propagation, and more.
<<howto.adoc#howto,"`How-to`" Guides>> :: Add sampling, propagate remote tags, and more.
<<integrations.adoc#sleuth-integration,{project-full-name} Integrations>> :: Instrumentation configuration, context propagation, and more.
<<appendix.adoc#appendix,Appendices>> :: Configuration properties.

View File

@@ -1 +0,0 @@
index.htmlsingleadoc

View File

@@ -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]

View File

@@ -1 +1,13 @@
include::_index_pdf.adoc[]
[[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]

916
pom.xml
View File

@@ -1,442 +1,474 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2013-2018 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ 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.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-sleuth</artifactId>
<version>3.0.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Cloud Sleuth</name>
<description>Spring Cloud Sleuth</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>3.0.2-SNAPSHOT</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<scm>
<url>https://github.com/spring-cloud/spring-cloud-sleuth</url>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git
</connection>
<developerConnection>
scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git
</developerConnection>
<tag>HEAD</tag>
</scm>
<modules>
<module>spring-cloud-sleuth-dependencies</module>
<module>spring-cloud-sleuth-api</module>
<module>spring-cloud-sleuth-instrumentation</module>
<module>spring-cloud-sleuth-brave</module>
<module>spring-cloud-sleuth-autoconfigure</module>
<module>tests</module>
<module>spring-cloud-sleuth-zipkin</module>
<module>spring-cloud-starter-sleuth</module>
<module>spring-cloud-sleuth-samples</module>
<module>docs</module>
</modules>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.testTarget>1.8</maven.compiler.testTarget>
<maven.compiler.testSource>1.8</maven.compiler.testSource>
<spring-cloud-build.version>3.0.2-SNAPSHOT</spring-cloud-build.version>
<spring-cloud-commons.version>3.0.2-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-gateway.version>3.0.2-SNAPSHOT</spring-cloud-gateway.version>
<spring-cloud-circuitbreaker.version>2.0.1-SNAPSHOT</spring-cloud-circuitbreaker.version>
<spring-cloud-stream.version>3.1.1-SNAPSHOT</spring-cloud-stream.version>
<spring-cloud-function.version>3.1.2-SNAPSHOT</spring-cloud-function.version>
<spring-cloud-netflix.version>3.0.2-SNAPSHOT</spring-cloud-netflix.version>
<spring-cloud-openfeign.version>3.0.2-SNAPSHOT</spring-cloud-openfeign.version>
<brave.version>5.13.2</brave.version>
<wavefront-runtime-sdk-jvm.version>1.3.3</wavefront-runtime-sdk-jvm.version>
<wavefront-sdk-java.version>2.6.2</wavefront-sdk-java.version>
<opentracing.version>0.32.0</opentracing.version>
<spring-security-boot-autoconfigure.version>2.3.4.RELEASE</spring-security-boot-autoconfigure.version>
<disable.nohttp.checks>false</disable.nohttp.checks>
<okhttp.version>4.9.0</okhttp.version>
<mockwebserver.version>4.8.0</mockwebserver.version>
<guava.version>20.0</guava.version>
<javax.resource-api.version>1.7.1</javax.resource-api.version>
<cglib-nodep.version>3.3.0</cglib-nodep.version>
<objenesis.version>3.0.1</objenesis.version>
<spring-security-oauth2.version>2.2.0.RELEASE</spring-security-oauth2.version>
<!-- Until we switch it to true in sc-build -->
<javadoc.failOnError>true</javadoc.failOnError>
<javadoc.failOnWarnings>false</javadoc.failOnWarnings>
<commons-lang3.version>3.8.1</commons-lang3.version>
<hamcrest-core.version>2.2</hamcrest-core.version>
<awaitility.version>4.0.3</awaitility.version>
<brave-propagation-aws.version>0.21.3</brave-propagation-aws.version>
<archunit-junit5.version>0.14.1</archunit-junit5.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<executions>
<execution>
<id>default-compile</id>
<configuration>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArguments>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</compilerArguments>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<configuration>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArguments>
<source>${maven.compiler.testSource}</source>
<target>${maven.compiler.testTarget}</target>
</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce-java</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>${maven.compiler.testTarget}</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-surefire-report-plugin</artifactId>
</plugin>
</plugins>
</reporting>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-dependencies</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
<version>${spring-cloud-netflix.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons-dependencies</artifactId>
<version>${spring-cloud-commons.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-dependencies</artifactId>
<version>${spring-cloud-gateway.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-circuitbreaker-dependencies</artifactId>
<version>${spring-cloud-circuitbreaker.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-dependencies</artifactId>
<version>${spring-cloud-stream.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-dependencies</artifactId>
<version>${spring-cloud-function.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>${spring-cloud-openfeign.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>${spring-security-boot-autoconfigure.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-runtime-sdk-jvm</artifactId>
<version>${wavefront-runtime-sdk-jvm.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-sdk-java</artifactId>
<version>${wavefront-sdk-java.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib-nodep.version}</version>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>${objenesis.version}</version>
<!-- not test because we need it in stream -->
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>${mockwebserver.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${spring-security-oauth2.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.aws</groupId>
<artifactId>brave-propagation-aws</artifactId>
<version>${brave-propagation-aws.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest-core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>${archunit-junit5.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>spring</id>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<!-- BRAVE -->
<repository>
<id>jfrog-snapshots</id>
<name>JFrog Snapshots</name>
<url>https://oss.jfrog.org/oss-snapshot-local/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>ide</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.testSource}</source>
<target>${maven.compiler.testTarget}</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>benchmarks</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<modules>
<module>benchmarks</module>
</modules>
</profile>
<profile>
<id>sonar</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
<destFile>${project.build.directory}/jacoco.exec
</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/jacoco.exec
</dataFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2013-2018 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ 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.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-sleuth</artifactId>
<version>3.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Cloud Sleuth</name>
<description>Spring Cloud Sleuth</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>3.0.3-SNAPSHOT</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<scm>
<url>https://github.com/spring-cloud/spring-cloud-sleuth</url>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git
</connection>
<developerConnection>
scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git
</developerConnection>
<tag>HEAD</tag>
</scm>
<modules>
<module>spring-cloud-sleuth-dependencies</module>
<module>spring-cloud-sleuth-api</module>
<module>spring-cloud-sleuth-instrumentation</module>
<module>spring-cloud-sleuth-brave</module>
<module>spring-cloud-sleuth-autoconfigure</module>
<module>tests</module>
<module>spring-cloud-sleuth-zipkin</module>
<module>spring-cloud-starter-sleuth</module>
<module>spring-cloud-sleuth-samples</module>
<module>docs</module>
</modules>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.testTarget>1.8</maven.compiler.testTarget>
<maven.compiler.testSource>1.8</maven.compiler.testSource>
<spring-cloud-build.version>3.0.3-SNAPSHOT</spring-cloud-build.version>
<spring-cloud-commons.version>3.0.3-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-gateway.version>3.0.3-SNAPSHOT</spring-cloud-gateway.version>
<spring-cloud-config.version>3.0.3-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-circuitbreaker.version>2.0.2-SNAPSHOT</spring-cloud-circuitbreaker.version>
<spring-cloud-stream.version>3.1.3-SNAPSHOT</spring-cloud-stream.version>
<spring-cloud-function.version>3.1.3-SNAPSHOT</spring-cloud-function.version>
<spring-cloud-netflix.version>3.0.3-SNAPSHOT</spring-cloud-netflix.version>
<spring-cloud-openfeign.version>3.0.3-SNAPSHOT</spring-cloud-openfeign.version>
<spring-cloud-task.version>2.3.2-SNAPSHOT</spring-cloud-task.version>
<spring-cloud-deployer.version>2.5.1</spring-cloud-deployer.version>
<brave.version>5.13.2</brave.version>
<wavefront-runtime-sdk-jvm.version>1.3.3</wavefront-runtime-sdk-jvm.version>
<wavefront-sdk-java.version>2.6.2</wavefront-sdk-java.version>
<opentracing.version>0.32.0</opentracing.version>
<spring-security-boot-autoconfigure.version>2.3.4.RELEASE</spring-security-boot-autoconfigure.version>
<disable.nohttp.checks>false</disable.nohttp.checks>
<okhttp.version>4.9.0</okhttp.version>
<mockwebserver.version>4.8.0</mockwebserver.version>
<guava.version>20.0</guava.version>
<javax.resource-api.version>1.7.1</javax.resource-api.version>
<cglib-nodep.version>3.3.0</cglib-nodep.version>
<objenesis.version>3.0.1</objenesis.version>
<spring-security-oauth2.version>2.2.0.RELEASE</spring-security-oauth2.version>
<!-- Until we switch it to true in sc-build -->
<javadoc.failOnError>true</javadoc.failOnError>
<javadoc.failOnWarnings>false</javadoc.failOnWarnings>
<commons-lang3.version>3.8.1</commons-lang3.version>
<hamcrest-core.version>2.2</hamcrest-core.version>
<awaitility.version>4.0.3</awaitility.version>
<brave-propagation-aws.version>0.21.3</brave-propagation-aws.version>
<archunit-junit5.version>0.14.1</archunit-junit5.version>
<testcontainers.version>1.15.3</testcontainers.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<executions>
<execution>
<id>default-compile</id>
<configuration>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArguments>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</compilerArguments>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<configuration>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArguments>
<source>${maven.compiler.testSource}</source>
<target>${maven.compiler.testTarget}</target>
</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce-java</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>${maven.compiler.testTarget}</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-surefire-report-plugin</artifactId>
</plugin>
</plugins>
</reporting>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-dependencies</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
<version>${spring-cloud-netflix.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons-dependencies</artifactId>
<version>${spring-cloud-commons.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-dependencies</artifactId>
<version>${spring-cloud-gateway.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-circuitbreaker-dependencies</artifactId>
<version>${spring-cloud-circuitbreaker.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-dependencies</artifactId>
<version>${spring-cloud-stream.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-dependencies</artifactId>
<version>${spring-cloud-function.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>${spring-cloud-openfeign.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-dependencies</artifactId>
<version>${spring-cloud-config.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-task-dependencies</artifactId>
<version>${spring-cloud-task.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-deployer-dependencies</artifactId>
<version>${spring-cloud-deployer.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>${spring-security-boot-autoconfigure.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-runtime-sdk-jvm</artifactId>
<version>${wavefront-runtime-sdk-jvm.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-sdk-java</artifactId>
<version>${wavefront-sdk-java.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib-nodep.version}</version>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>${objenesis.version}</version>
<!-- not test because we need it in stream -->
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>${mockwebserver.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${spring-security-oauth2.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.aws</groupId>
<artifactId>brave-propagation-aws</artifactId>
<version>${brave-propagation-aws.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest-core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>${archunit-junit5.version}</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>${testcontainers.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>spring</id>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<!-- BRAVE -->
<repository>
<id>jfrog-snapshots</id>
<name>JFrog Snapshots</name>
<url>https://oss.jfrog.org/oss-snapshot-local/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>ide</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.testSource}</source>
<target>${maven.compiler.testTarget}</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>benchmarks</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<modules>
<module>benchmarks</module>
</modules>
</profile>
<profile>
<id>sonar</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
<destFile>${project.build.directory}/jacoco.exec
</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/jacoco.exec
</dataFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -28,7 +28,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth</artifactId>
<version>3.0.2-SNAPSHOT</version>
<version>3.1.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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<SpanAndScope> threadLocalSpan = new ThreadLocal<>();
private final Deque<SpanAndScope> 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);
}
}
}
}

View File

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

View File

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

View File

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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -1,446 +1,478 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2013-2018 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ 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.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-sleuth-autoconfigure</artifactId>
<packaging>jar</packaging>
<name>Spring Cloud Sleuth AutoConfigure</name>
<description>Spring Cloud Sleuth AutoConfigure</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth</artifactId>
<version>3.0.2-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<dependencies>
<!-- CORE -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-instrumentation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<!-- For Instrumentation of Quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<!-- BRAVE -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
<exclusions>
<exclusion>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-context-slf4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-messaging</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-rpc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-kafka-clients</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-kafka-streams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-httpclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-httpasyncclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-jms</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.aws</groupId>
<artifactId>brave-propagation-aws</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.opentracing.brave</groupId>
<artifactId>brave-opentracing</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<optional>true</optional>
</dependency>
<!-- GRPC Optional Dependencies -->
<dependency>
<groupId>io.github.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-grpc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-metrics-micrometer</artifactId>
<exclusions>
<exclusion>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<!-- Instrumentation of Lettuce -->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
<!-- Zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>zipkin</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-kafka</artifactId>
<optional>true</optional>
<exclusions>
<!-- assigned with spring-kafka -->
<exclusion>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-activemq-client</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-amqp-client</artifactId>
<optional>true</optional>
<exclusions>
<!-- assigned with spring-rabbit -->
<exclusion>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Wavefront -->
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-runtime-sdk-jvm</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-sdk-java</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-wavefront</artifactId>
<optional>true</optional>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<!-- Brave -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-http-tests</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<!-- Zipkin -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<!-- Kotlin... -->
<version>4.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>fast</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkCount>4</forkCount>
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2013-2018 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ 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.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-sleuth-autoconfigure</artifactId>
<packaging>jar</packaging>
<name>Spring Cloud Sleuth AutoConfigure</name>
<description>Spring Cloud Sleuth AutoConfigure</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth</artifactId>
<version>3.1.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<dependencies>
<!-- CORE -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-instrumentation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<!-- TODO: why is this needed? -->
<version>${spring-cloud-stream.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-task</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-deployer-spi</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<!-- For Instrumentation of Quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<!-- BRAVE -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
<exclusions>
<exclusion>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-context-slf4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-messaging</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-rpc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-kafka-clients</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-kafka-streams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-httpclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-httpasyncclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-jms</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.aws</groupId>
<artifactId>brave-propagation-aws</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.opentracing.brave</groupId>
<artifactId>brave-opentracing</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<optional>true</optional>
</dependency>
<!-- GRPC Optional Dependencies -->
<dependency>
<groupId>io.github.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-grpc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-metrics-micrometer</artifactId>
<exclusions>
<exclusion>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<!-- Instrumentation of Lettuce -->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rsocket</artifactId>
<optional>true</optional>
</dependency>
<!-- Zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>zipkin</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-kafka</artifactId>
<optional>true</optional>
<exclusions>
<!-- assigned with spring-kafka -->
<exclusion>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-activemq-client</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-amqp-client</artifactId>
<optional>true</optional>
<exclusions>
<!-- assigned with spring-rabbit -->
<exclusion>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Wavefront -->
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-runtime-sdk-jvm</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-sdk-java</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-wavefront</artifactId>
<optional>true</optional>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<scope>test</scope>
</dependency>
<!-- Brave -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-http-tests</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<!-- Zipkin -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<!-- Kotlin... -->
<version>4.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>fast</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkCount>4</forkCount>
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

Some files were not shown because too many files have changed in this diff Show More