Refactoring modules to be consistent with Spring Boot (#1784)

# Modules

* New modules: `spring-cloud-sleuth-autoconfigure`, `spring-cloud-sleuth-api`, `spring-cloud-sleuth-instrumentation`
  `spring-cloud-sleuth-core` removed and changed to `spring-cloud-sleuth-instrumentation` & `spring-cloud-sleuth-api`
* Removed `spring-cloud-starter-sleuth-otel`
  To add OpenTelemetry support you need to add `spring-cloud-starter-sleuth` (adds Brave by default), exclude Brave and add `spring-cloud-sleuth-otel` dependency
* Except for the tests, `spring-cloud-sleuth-autoconfigure` is the only module that can have access to `@Configuration`, `@ConfigurationProperties` classes.
Tests have been added to ensure such separation.

## Package moving

* `org.springframework.cloud.sleuth.api` -> `org.springframework.cloud.sleuth`
* `org.springframework.cloud.sleuth.brave.autoconfig` -> `org.springframework.cloud.sleuth.autoconfig.brave`
* `org.springframework.cloud.sleuth.otel.autoconfig` -> `org.springframework.cloud.sleuth.autoconfig.otel`
* `org.springframework.cloud.sleuth` -> `org.springframework.cloud.sleuth`
* Instrumentation: `org.springframework.cloud.sleuth.annotation` -> `org.springframework.cloud.sleuth.instrument.annotation`
* All the autoconfiguration classes were moved under `org.springframework.cloud/sleuth.autoconfig` package

## Global class modifications

* Any class registered as a bean is now public

## Classes

* `RateLimitingSampler` constructor changed
* Merged a lot of auto configuration classes into one (e.g. `BraveAutoConfiguration` now imports various other configurations)
* Renamed `TraceBraveAutoConfiguration` to `BraveAutoConfiguration`
* Renamed `TraceOtelAutoConfiguration` to `OtelAutoConfiguration`
* Removed all `NoOp` implementations of the API
This commit is contained in:
Marcin Grzejszczak
2020-11-23 15:39:13 +01:00
committed by GitHub
parent c81ee04dac
commit 76ad931b42
625 changed files with 9302 additions and 5795 deletions

View File

@@ -54,7 +54,17 @@ Example of Sleuth with Brave tracer:
<!--
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
-->
</dependencies>
@@ -81,7 +91,7 @@ being traced in the logs (notice the `0b6aaf642574edd3` ids).
[indent=0]
----
2020-10-21 12:01:16.285 INFO [,0b6aaf642574edd3,0b6aaf642574edd3,true] 289589 --- [nio-9000-exec-1] DemoController : Handling home!
2020-10-21 12:01:16.285 INFO [,0b6aaf642574edd3,0b6aaf642574edd3,true] 289589 --- [nio-9000-exec-1] DemoController : Handling home!
----
NOTE: Instead of logging the request in the handler explicitly, you could set `logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG`.

View File

@@ -24,9 +24,9 @@ Just execute them from the root folder like this:
For JMH we're building a shaded JAR file that is next executed.
For JMeter we're running two applications, one with Sleuth, one without with Spring Boot
Maven Plugin. Next a Maven JMeter plugin is executed that loads the `*.jmx` files, starts
JMeter and prints out the results. At the end Spring Boot Maven Plugin stops the applications.
For JMeter we're running two applications, one with Sleuth, one without with Spring Boot Maven Plugin.
Next a Maven JMeter plugin is executed that loads the `*.jmx` files, starts JMeter and prints out the results.
At the end Spring Boot Maven Plugin stops the applications.
=== What are we testing?

View File

@@ -70,7 +70,7 @@
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@@ -35,11 +35,11 @@ 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.api.Span;
import org.springframework.cloud.sleuth.api.Tracer;
import org.springframework.cloud.sleuth.instrument.web.SkipPatternProvider;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;

View File

@@ -148,7 +148,8 @@ class SimpleFunction implements Function<String, String> {
@Override
public String apply(String input) {
// tracing works cause headers from the input message get propagated to the output message
// tracing works cause headers from the input message get propagated to the output
// message
log.info("Hello from simple [{}]", input);
return input.toUpperCase();
}
@@ -185,7 +186,8 @@ class SimpleManualFunction implements Function<Message<String>, Message<String>>
})).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));
.andThen(msg -> MessagingSleuthOperators.afterMessageHandled(this.beanFactory, msg, null))
.apply(input));
}
}

View File

@@ -34,7 +34,7 @@ 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.api.TraceContext;
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;

View File

@@ -75,8 +75,11 @@ public class SampleTests {
public static class BenchmarkContext {
volatile ConfigurableApplicationContext applicationContext;
volatile InputDestination input;
volatile OutputDestination output;
@Param
private Instrumentation instrumentation;

View File

@@ -16,13 +16,12 @@
package org.springframework.cloud.sleuth.benchmarks.jmh;
import org.springframework.cloud.sleuth.brave.autoconfig.TraceBraveAutoConfiguration;
import org.springframework.cloud.sleuth.otel.autoconfig.TraceOtelAutoConfiguration;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.autoconfig.otel.OtelAutoConfiguration;
public enum TracerImplementation {
otel(TraceBraveAutoConfiguration.class.getCanonicalName()), brave(
TraceOtelAutoConfiguration.class.getCanonicalName());
otel(BraveAutoConfiguration.class.getCanonicalName()), brave(OtelAutoConfiguration.class.getCanonicalName());
private String key = "spring.autoconfigure.exclude";

View File

@@ -32,17 +32,11 @@ import org.openjdk.jmh.annotations.Warmup;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.api.Tracer;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.autoconfig.otel.OtelAutoConfiguration;
import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation;
import org.springframework.cloud.sleuth.brave.autoconfig.TraceBraveAutoConfiguration;
import org.springframework.cloud.sleuth.brave.bridge.TraceBraveBridgeAutoConfiguation;
import org.springframework.cloud.sleuth.brave.propagation.TraceBravePropagationAutoConfiguration;
import org.springframework.cloud.sleuth.otel.autoconfig.TraceOtelAutoConfiguration;
import org.springframework.cloud.sleuth.otel.bridge.TraceOtelBridgeAutoConfiguation;
import org.springframework.cloud.sleuth.otel.log.TraceOtelLogAutoConfiguration;
import org.springframework.cloud.sleuth.otel.propagation.TraceOtelPropagationAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
@@ -121,11 +115,7 @@ public class BridgeTests {
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration({ TraceAutoConfiguration.class, TraceBraveAutoConfiguration.class,
TraceBraveBridgeAutoConfiguation.class, TraceBravePropagationAutoConfiguration.class,
TraceOtelAutoConfiguration.class, TraceOtelBridgeAutoConfiguation.class,
TraceOtelPropagationAutoConfiguration.class, TraceOtelLogAutoConfiguration.class,
TraceOtelLogAutoConfiguration.class })
@ImportAutoConfiguration({ BraveAutoConfiguration.class, OtelAutoConfiguration.class })
static class TestConfiguration {
}

View File

@@ -54,7 +54,8 @@ public class StartupBenchmarkTests {
@Benchmark
public void withoutAsync(ApplicationState state) throws Exception {
state.setExtraArgs("--spring.sleuth.async.enabled=false", "--spring.sleuth.annotation.enabled=false", state.tracerImplementation.property());
state.setExtraArgs("--spring.sleuth.async.enabled=false", "--spring.sleuth.annotation.enabled=false",
state.tracerImplementation.property());
state.run();
}
@@ -68,7 +69,8 @@ public class StartupBenchmarkTests {
@Benchmark
public void withoutWeb(ApplicationState state) throws Exception {
state.setExtraArgs("--spring.sleuth.web.enabled=false", "--spring.sleuth.scheduled.enabled=false",
"--spring.sleuth.async.enabled=false", "--spring.sleuth.annotation.enabled=false", state.tracerImplementation.property());
"--spring.sleuth.async.enabled=false", "--spring.sleuth.annotation.enabled=false",
state.tracerImplementation.property());
state.run();
}

View File

@@ -107,9 +107,9 @@ public class MicroBenchmarkStreamTests {
protected String[] runArgs() {
List<String> strings = new ArrayList<>();
strings.addAll(Arrays.asList("--spring.jmx.enabled=false",
this.tracerImplementation.property(),
"--spring.application.name=defaultTraceContextForStream" + instrumentation.name() + "_" + tracerImplementation.name()));
strings.addAll(Arrays.asList("--spring.jmx.enabled=false", this.tracerImplementation.property(),
"--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]);
}

View File

@@ -82,9 +82,9 @@ public class MicroBenchmarkHttpTests {
}
protected String[] runArgs() {
return new String[] { "--spring.jmx.enabled=false",
tracerImplementation.property(),
"--spring.application.name=defaultTraceContext" + instrumentation.name() + "_" + tracerImplementation.name(),
return new String[] { "--spring.jmx.enabled=false", tracerImplementation.property(),
"--spring.application.name=defaultTraceContext" + instrumentation.name() + "_"
+ tracerImplementation.name(),
"--" + instrumentation.key + "=" + instrumentation.value };
}

View File

@@ -68,6 +68,7 @@ public 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();
@@ -138,8 +139,8 @@ public class SpringWebFluxBenchmarksTests {
}
protected String[] runArgs() {
return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", TracerImplementation.brave.toString(),
"--spring.sleuth.enabled=true" };
return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext",
TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true" };
}
@TearDown

View File

@@ -40,8 +40,8 @@ public class WithOutReactorSleuthSpringWebFluxBenchmarksTests extends SpringWebF
@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"
TracerImplementation.brave.toString(), "--spring.sleuth.enabled=true",
"--spring.sleuth.reactor.enabled=false"
};
}

View File

@@ -39,8 +39,8 @@ public class WithOutSleuthSpringWebFluxBenchmarksTests extends SpringWebFluxBenc
@Override
protected String[] runArgs() {
return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext", TracerImplementation.brave.toString(),
"--spring.sleuth.enabled=false" };
return new String[] { "--spring.jmx.enabled=false", "--spring.application.name=defaultTraceContext",
TracerImplementation.brave.toString(), "--spring.sleuth.enabled=false" };
}
@Override

View File

@@ -14,7 +14,6 @@
~ 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">
@@ -41,7 +40,7 @@
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>

View File

@@ -47,7 +47,17 @@ Example of Sleuth with Brave tracer:
<!--
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
-->
</dependencies>
@@ -74,7 +84,7 @@ being traced in the logs (notice the `0b6aaf642574edd3` ids).
[indent=0]
----
2020-10-21 12:01:16.285 INFO [,0b6aaf642574edd3,0b6aaf642574edd3,true] 289589 --- [nio-9000-exec-1] DemoController : Handling home!
2020-10-21 12:01:16.285 INFO [,0b6aaf642574edd3,0b6aaf642574edd3,true] 289589 --- [nio-9000-exec-1] DemoController : Handling home!
----
NOTE: Instead of logging the request in the handler explicitly, you could set `logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG`.

View File

@@ -17,6 +17,8 @@
// project-specific attributes
:core_path: {project-root}
:docs_path: {project-root}/docs
:autoconfig_path: {project-root}/spring-cloud-sleuth-autoconfigure
:api_path: {project-root}/spring-cloud-sleuth-api
:brave_path: {project-root}/spring-cloud-sleuth-brave
:otel_path: {project-root}/spring-cloud-sleuth-otel
:tests_path: {core_path}/tests

View File

@@ -1,8 +1,7 @@
|===
|Name | Default | Description
|spring.sleuth.async.configurer.enabled | `true` | Enable default AsyncConfigurer.
|spring.sleuth.async.enabled | `true` | Enable instrumenting async related components so that the tracing information is passed between threads.
|spring.sleuth.async.enabled | `false` |
|spring.sleuth.async.ignored-beans | | List of {@link java.util.concurrent.Executor} bean names that should be ignored and not wrapped in a trace representation.
|spring.sleuth.baggage.correlation-enabled | `true` | context.
|spring.sleuth.baggage.correlation-fields | |
@@ -11,16 +10,11 @@
|spring.sleuth.baggage.tag-fields | |
|spring.sleuth.circuitbreaker.enabled | `true` | Enable Spring Cloud CircuitBreaker instrumentation.
|spring.sleuth.enabled | `true` |
|spring.sleuth.feign.enabled | `true` | Enable span information propagation when using Feign.
|spring.sleuth.feign.processor.enabled | `true` | Enable post processor that wraps Feign Context in its tracing representations.
|spring.sleuth.grpc.enabled | `true` | Enable span information propagation when using GRPC.
|spring.sleuth.feign.enabled | `true` | When true enables instrumentation for feign.
|spring.sleuth.function.enabled | `true` | Enable instrumenting of Spring Cloud Function and Spring Cloud Function based projects (e.g. Spring Cloud Stream).
|spring.sleuth.http.enabled | `true` |
|spring.sleuth.integration.enabled | `true` | Enable Spring Integration sleuth instrumentation.
|spring.sleuth.integration.enabled | `false` | Enable Spring Integration sleuth instrumentation.
|spring.sleuth.integration.patterns | `[!hystrixStreamOutput*, *, !channel*]` | An array of patterns against which channel names will be matched. @see org.springframework.integration.config.GlobalChannelInterceptor#patterns() Defaults to any channel name not matching the Hystrix Stream and functional Stream channel names.
|spring.sleuth.integration.websockets.enabled | `true` | Enable tracing for WebSockets.
|spring.sleuth.messaging.jms.enabled | `true` | Enable tracing of JMS.
|spring.sleuth.messaging.kafka.enabled | `true` | Enable tracing of Kafka.
|spring.sleuth.messaging.kafka.mapper.enabled | `true` | Enable DefaultKafkaHeaderMapper tracing for Kafka.
|spring.sleuth.messaging.messaging.enabled | `false` | Should messaging be turned on.
|spring.sleuth.messaging.messaging.jms.enabled | `false` |
|spring.sleuth.messaging.messaging.jms.remote-service-name | `jms` |
@@ -28,22 +22,30 @@
|spring.sleuth.messaging.messaging.kafka.remote-service-name | `kafka` |
|spring.sleuth.messaging.messaging.rabbit.enabled | `false` |
|spring.sleuth.messaging.messaging.rabbit.remote-service-name | `rabbitmq` |
|spring.sleuth.messaging.rabbit.enabled | `true` | Enable tracing of RabbitMQ.
|spring.sleuth.mongodb.enabled | `true` | Enable tracing for MongoDb.
|spring.sleuth.opentracing.enabled | `true` |
|spring.sleuth.otel.config.instrumentation-name | `org.springframework.cloud.spring-cloud-sleuth` | Instrumentation name to be used to find a Tracer.
|spring.sleuth.otel.config.instrumentation-version | | Instrumentation version to be used to find a Tracer.
|spring.sleuth.otel.config.max-attr-length | `0` | Returns the global default max length of string attribute value in characters.
|spring.sleuth.otel.config.max-attrs | `0` | Returns the global default max number of attributes per {@link Span}.
|spring.sleuth.otel.config.max-event-attrs | `0` | Returns the global default max number of attributes per event.
|spring.sleuth.otel.config.max-events | `0` | Returns the global default max number of events per {@link Span}.
|spring.sleuth.otel.config.max-link-attrs | `0` | Returns the global default max number of attributes per link.
|spring.sleuth.otel.config.max-links | `0` | Returns the global default max number of link entries per {@link Span}.
|spring.sleuth.otel.exporter.sleuth-span-filter.enabled | `true` | This application service name.
|spring.sleuth.otel.log.exporter.enabled | `false` | Enable log support for Otel.
|spring.sleuth.otel.log.slf4j.enabled | `false` | Enable log support for Otel.
|spring.sleuth.otel.propagation.composite-text-map-propagator.enabled | `true` | Enable a composite text map propagator that can combine multiple propagation types into a single text map propagator.
|spring.sleuth.otel.propagation.sleuth-baggage.enabled | `true` | Enable propagating baggage in a Sleuth compatible way (baggage key & value pair means e.g. a key & value HTTP pair).
|spring.sleuth.propagation.type | | Type of propagation.
|spring.sleuth.quartz.enabled | `true` | Enable tracing for Quartz.
|spring.sleuth.reactor.decorate-on-each | `true` | When true decorates on each operator, will be less performing, but logging will always contain the tracing entries in each operator. When false decorates on last operator, will be more performing, but logging might not always contain the tracing entries. @deprecated use explicit value via {@link SleuthReactorProperties#instrumentationType}
|spring.sleuth.reactor.enabled | `true` | When true enables instrumentation for reactor.
|spring.sleuth.reactor.instrumentation-type | |
|spring.sleuth.redis.enabled | `true` | Enable span information propagation when using Redis.
|spring.sleuth.redis.remote-service-name | `redis` | Service name for the remote Redis endpoint.
|spring.sleuth.rpc.enabled | `true` | Enable tracing of RPC.
|spring.sleuth.rxjava.schedulers.hook.enabled | `true` | Enable support for RxJava via RxJavaSchedulersHook.
|spring.sleuth.rxjava.schedulers.ignoredthreads | `[HystrixMetricPoller, ^RxComputation.*$]` | Thread names for which spans will not be sampled.
|spring.sleuth.sampler.probability | | Probability of requests that should be sampled. E.g. 1.0 - 100% requests should be sampled. The precision is whole-numbers only (i.e. there's no support for 0.1% of the traces).
|spring.sleuth.sampler.rate | `10` | A rate per second can be a nice choice for low-traffic endpoints as it allows you surge protection. For example, you may never expect the endpoint to get more than 50 requests per second. If there was a sudden surge of traffic, to 5000 requests per second, you would still end up with 50 traces per second. Conversely, if you had a percentage, like 10%, the same surge would end up with 500 traces per second, possibly overloading your storage. Amazon X-Ray includes a rate-limited sampler (named Reservoir) for this purpose. Brave has taken the same approach via the {@link brave.sampler.RateLimitingSampler}.
|spring.sleuth.sampler.refresh.enabled | `true` | Enable refresh scope for sampler.
|spring.sleuth.scheduled.enabled | `true` | Enable tracing for {@link org.springframework.scheduling.annotation.Scheduled}.
|spring.sleuth.scheduled.skip-pattern | | Pattern for the fully qualified name of a class that should be skipped.
|spring.sleuth.span-filter.additional-span-name-patterns-to-ignore | | Additional list of span names to ignore. Will be appended to {@link #spanNamePatternsToSkip}.
@@ -51,14 +53,15 @@
|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.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}.
|spring.sleuth.web.client.enabled | `true` | Enable interceptor injecting into {@link org.springframework.web.client.RestTemplate}.
|spring.sleuth.web.client.skip-pattern | | Pattern for URLs that should be skipped in client side tracing.
|spring.sleuth.web.enabled | `true` | When true enables instrumentation for web applications.
|spring.sleuth.web.filter-order | | Order in which the tracing filters should be registered. Defaults to {@link TraceWebServletAutoConfiguration#TRACING_FILTER_ORDER}.
|spring.sleuth.web.ignore-auto-configured-skip-patterns | `false` | If set to true, auto-configured skip patterns will be ignored. @see SkipPatternConfiguration
|spring.sleuth.web.filter-order | `0` | Order in which the tracing filters should be registered.
|spring.sleuth.web.ignore-auto-configured-skip-patterns | `false` | If set to true, auto-configured skip patterns will be ignored.
|spring.sleuth.web.servlet.enabled | `true` | Enable servlet instrumentation.
|spring.sleuth.web.skip-pattern | `/api-docs.*\|/swagger.*\|.*\.png\|.*\.css\|.*\.js\|.*\.html\|/favicon.ico\|/hystrix.stream` | Pattern for URLs that should be skipped in tracing.
|spring.sleuth.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.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/).

View File

@@ -1,4 +1,5 @@
:numbered!:
[[appendix]]
[[common-application-properties]]
== Common application properties

View File

@@ -1,11 +1,10 @@
[[documentation]]
= Spring Cloud Sleuth Documentation
include::_attributes.adoc[]
This section provides a brief overview of {project-full-name} reference documentation. It serves
as a map for the rest of the document.
This section provides a brief overview of {project-full-name} reference documentation.
It serves as a map for the rest of the document.
[[sleuth-documentation-about]]
== About the Documentation
@@ -16,32 +15,28 @@ The {project-full-name} reference guide is available as
* {docs-url}/reference/htmlsingle[Single-page HTML]
* {docs-url}/reference/pdf/{project-name}.pdf[PDF]
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.
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.
[[documentation-getting-help]]
== Getting Help
If you have trouble with {project-full-name}, we would like to help.
* Try the <<howto.adoc#howto, How-to documents>>. They provide solutions to the most
common questions.
* Learn the {project-full-name} basics. If you are
starting out with {project-full-name}, try one of the https://spring.io/guides[guides].
* Ask a question. We monitor https://stackoverflow.com[stackoverflow.com] for questions
tagged with https://stackoverflow.com/tags/{project-name}[`{project-name}`].
* Try the <<howto.adoc#howto, How-to documents>>.
They provide solutions to the most common questions.
* Learn the {project-full-name} basics.
If you are starting out with {project-full-name}, try one of the https://spring.io/guides[guides].
* Ask a question.
We monitor https://stackoverflow.com[stackoverflow.com] for questions tagged with https://stackoverflow.com/tags/{project-name}[`{project-name}`].
* Report bugs with {project-full-name} at https://github.com/spring-cloud/{project-name}/issues.
* Chat with us at http://https://gitter.im/spring-cloud/{project-name}[{project-full-name} Gitter]
NOTE: All of {project-full-name} is open source, including the documentation. If you find
problems with the docs or if you want to improve them, please {github-code}[get
involved].
NOTE: All of {project-full-name} is open source, including the documentation.
If you find problems with the docs or if you want to improve them, please {github-code}[get involved].
[[sleuth-documentation-first-steps]]
== First Steps
If you are getting started with {project-full-name} or 'Spring' in general, start with
<<getting-started.adoc#getting-started, the following topics>>:
@@ -51,8 +46,8 @@ If you are getting started with {project-full-name} or 'Spring' in general, star
[[sleuth-documentation-working-with-sleuth]]
== Working with {project-full-name}
Ready to actually start using {project-full-name}? <<using.adoc#using, We have
you covered>>:
Ready to actually start using {project-full-name}? <<using.adoc#using, We have you covered>>:
* <<using.adoc#using-span-lifecycle,Span Lifecycle with Spring Cloud Sleuth's API>>
* <<using.adoc#using-naming-spans,Naming Spans>>
@@ -60,6 +55,7 @@ you covered>>:
[[sleuth-documentation-features]]
== Learning about {project-full-name} Features
Need more details about {project-full-name}'s core features?
<<project-features.adoc#features, The following content is for you>>:
@@ -78,6 +74,7 @@ Need more details about {project-full-name}'s core features?
[[sleuth-documentation-integration]]
== Integrations Topics
Finally, we have topics related to instrumentation integrations:
* *Integrations:*

View File

@@ -18,7 +18,8 @@ It integrates out of the box with two tracer implementations:
* https://opentelemetry.io[OpenTelemetry SDK]
Spring Cloud Sleuth is able to trace your requests and messages so that you can correlate that communication to corresponding log entries.
You can also export the tracing information to an external system to visualize latency. Spring Cloud Sleuth supports https://zipkin.io[OpenZipkin] compatible systems directly and various other ones via the OpenTelemetry integration.
You can also export the tracing information to an external system to visualize latency.
Spring Cloud Sleuth supports https://zipkin.io[OpenZipkin] compatible systems directly and various other ones via the OpenTelemetry integration.
[[getting-started-terminology]]
=== Terminology
@@ -92,7 +93,8 @@ image::{github-raw}/docs/src/main/asciidoc/images/parents.png[Parent child relat
== Developing Your First Spring Cloud sleuth-based Application
This section describes how to develop a small “Hello World!” web application that highlights some of Spring Cloud Sleuths key features.
We use Maven to build this project, since most IDEs support it. As the tracer implementation we'll use https://github.com/openzipkin/brave[OpenZipkin Brave].
We use Maven to build this project, since most IDEs support it.
As the tracer implementation we'll use https://github.com/openzipkin/brave[OpenZipkin Brave].
[TIP]
====
@@ -191,7 +193,35 @@ To add the necessary dependencies, edit your `pom.xml` and add the `spring-boot-
</dependencies>
----
To use Sleuth with OpenTelemetry pass `spring-cloud-starter-sleuth-otel` instead of `spring-cloud-stater-sleuth`.
To use Sleuth with OpenTelemetry do the following.
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
----
<dependencies>
<!-- Boot's Web support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sleuth with Brave tracer implementation -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<!-- Exclude Brave -->
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Add OpenTelemetry tracer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
</dependencies>
----
[[getting-started-first-application-code]]
=== Writing the Code
@@ -232,7 +262,8 @@ We step through the important parts in the next few sections.
[getting-started-first-application-annotations]]
==== The @RestController and @RequestMapping Annotations
Spring Boot sets up the Rest Controller and makes our application bind to a Tomcat port. Spring Cloud Sleuth with Brave tracer will provide instrumentation of the incoming request.
Spring Boot sets up the Rest Controller and makes our application bind to a Tomcat port.
Spring Cloud Sleuth with Brave tracer will provide instrumentation of the incoming request.
[[getting-started-first-application-run]]
=== Running the Example
@@ -273,10 +304,11 @@ If you check the logs you should see a similar output
2020-10-21 12:01:16.285 INFO [backend,0b6aaf642574edd3,0b6aaf642574edd3,true] 289589 --- [nio-9000-exec-1] Example : Hello world!
----
You can notice that the logging format has been updated with the following information `[backend,0b6aaf642574edd3,0b6aaf642574edd3,true]`. This entry corresponds to `[application name,trace id, span id, whether the trace should be propagated to an external system]`. The application name got read from the `SPRING_APPLICATION_NAME` environment variable.
You can notice that the logging format has been updated with the following information `[backend,0b6aaf642574edd3,0b6aaf642574edd3,true]`.
This entry corresponds to `[application name,trace id, span id, whether the trace should be propagated to an external system]`.
The application name got read from the `SPRING_APPLICATION_NAME` environment variable.
NOTE: Instead of logging the request in the handler explicitly, you
could set `logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG`.
NOTE: Instead of logging the request in the handler explicitly, you could set `logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG`.
To gracefully exit the application, press `ctrl-c`.

View File

@@ -50,7 +50,7 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
}
----
====
@@ -58,7 +58,7 @@ dependencies {
[[how-to-set-up-sleuth-with-otel]]
== How to Set Up Sleuth with OpenTelemetry?
Add the Sleuth OpenTelemetry starter to the classpath.
Add the Sleuth starter, exlcude Brave and add OpenTelemetry dependency to the classpath.
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
@@ -78,7 +78,17 @@ Add the Sleuth OpenTelemetry starter to the classpath.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
----
@@ -92,7 +102,9 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth-otel"
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
}
----
====
@@ -138,8 +150,8 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
}
----
====
@@ -147,7 +159,7 @@ dependencies {
[[how-to-set-up-sleuth-with-otel-zipkin-http]]
== How to Set Up Sleuth with OpenTelemetry & Zipkin via HTTP?
Add the Sleuth starter and Zipkin to the classpath.
Add the Sleuth starter, exclude Brave, add OTel and Zipkin to the classpath.
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
@@ -167,7 +179,17 @@ Add the Sleuth starter and Zipkin to the classpath.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
@@ -185,8 +207,10 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth-otel"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
}
----
====
@@ -239,9 +263,9 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
compile "org.springframework.kafka:spring-kafka"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.springframework.kafka:spring-kafka"
}
----
====
@@ -295,9 +319,9 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
compile "org.springframework.amqp:spring-rabbit"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.springframework.amqp:spring-rabbit"
}
----
====
@@ -344,9 +368,9 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
compile "org.apache.activemq:activemq-client"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.apache.activemq:activemq-client"
}
----
====
@@ -384,7 +408,17 @@ If using Kafka, you must add the Kafka dependency.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
@@ -406,9 +440,11 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth-otel"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
compile "org.springframework.kafka:spring-kafka"
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.springframework.kafka:spring-kafka"
}
----
====
@@ -420,7 +456,7 @@ Also, you need to set the property `spring.zipkin.sender.type` property accordin
spring.zipkin.sender.type: kafka
----
If you want Sleuth over RabbitMQ, add the `spring-cloud-starter-sleuth-otel`, `spring-cloud-sleuth-zipkin` and `spring-rabbit` dependencies.
If you want Sleuth over RabbitMQ, add the `spring-cloud-sleuth-otel` (exclude `spring-cloud-sleuth-brave`), `spring-cloud-sleuth-zipkin` and `spring-rabbit` dependencies.
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
@@ -462,14 +498,14 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
compile "org.springframework.amqp:spring-rabbit"
implementation "org.springframework.cloud:spring-cloud-starter-sleuth"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.springframework.amqp:spring-rabbit"
}
----
====
If you want Sleuth over RabbitMQ, add the `spring-cloud-starter-sleuth-otel`, `spring-cloud-sleuth-zipkin` and `activemq-client` dependencies.
If you want Sleuth over RabbitMQ, add the `spring-cloud-sleuth-otel` (exclude `spring-cloud-sleuth-brave`), `spring-cloud-sleuth-zipkin` and `activemq-client` dependencies.
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
@@ -489,7 +525,17 @@ If you want Sleuth over RabbitMQ, add the `spring-cloud-starter-sleuth-otel`, `s
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
@@ -511,9 +557,11 @@ dependencyManagement {
}
dependencies {
compile "org.springframework.cloud:spring-cloud-starter-sleuth-otel"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin"
compile "org.apache.activemq:activemq-client"
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.apache.activemq:activemq-client"
}
----
====
@@ -570,7 +618,7 @@ For example if you want to use the OpenTelemetry Zipkin Exporter just add a depe
.Gradle
----
dependencies {
compile "io.opentelemetry:opentelemetry-exporter-zipkin"
implementation "io.opentelemetry:opentelemetry-exporter-zipkin"
}
----
====
@@ -615,7 +663,7 @@ Example where instrumentation will work:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
@Configuration(proxyBeanMethods = false)
class MyConfiguration {
@Bean RestTemplate myRestTemplate() {
return new RestTemplate();
@@ -665,12 +713,12 @@ Register a bean of `HttpResponseParser` type whose name is `HttpServerResponsePa
====
[source,java,indent=0]
----
import org.springframework.cloud.sleuth.api.http.HttpResponseParser;
import org.springframework.cloud.sleuth.http.HttpResponseParser;
import org.springframework.cloud.sleuth.instrument.web.HttpServerResponseParser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Configuration(proxyBeanMethods = false)
class MyConfig {
@Bean(name = HttpServerResponseParser.NAME)
@@ -689,6 +737,8 @@ class MyConfig {
----
====
IMPORTANT: Your spans need to be sampled for the parser to work. That means that you need to be able to export spans to e.g. Zipkin.
[[how-to-cutomize-http-client-spans]]
== How to Customize HTTP Client Spans?
@@ -715,6 +765,8 @@ include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/inst
----
====
IMPORTANT: Your spans need to be sampled for the parser to work. That means that you need to be able to export spans to e.g. Zipkin.
[[how-to-see-application-name-in-logs]]
== How to See the Application Name in Logs?
@@ -729,7 +781,7 @@ To use the provided defaults you can set the `spring.sleuth.propagation.type` pr
The value can be a list in which case you will propagate more tracing headers.
For Brave we support `AWS`, `B3`, `W3C` propagation types.
For OpenTelemetry we support `AWS`, `B3`, `JAEGER`, `W3C`, `OT_TRACER` and `W3C` via the `io.opentelemetry:opentelemetry-extension-trace-propagators` that we provide via the `spring-cloud-starter-sleuth-otel` starter.
For OpenTelemetry we support `AWS`, `B3`, `JAEGER`, `W3C`, `OT_TRACER` and `W3C` propagation types.
If you want to provide a custom propagation mechanism set the `spring.sleuth.propagation.type` property to `CUSTOM` and implement your own bean (`Propagation.Factory` for Brave and `TextMapPropagator` for OpenTelemetry).
Below you can find the examples:
@@ -739,18 +791,20 @@ Below you can find the examples:
.Brave
----
@Component
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/propagation/TraceBravePropagationAutoConfigurationTests.java[tags=custom_propagator,indent=0]
include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/BravePropagationTests.java[tags=custom_propagator,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.OpenTelemetry
----
@Component
include::{otel_path}/src/test/java/org/springframework/cloud/sleuth/otel/propagation/TraceOtelPropagationAutoConfigurationTests.java[tags=custom_propagator,indent=0]
include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/otel/OtelPropagationConfigurationTests.java[tags=custom_propagator,indent=0]
----
====
[[how-to-implement-own-tracer]]
== How to Implement My Own Tracer?
Spring Cloud Sleuth Core in its `api` module contains all necessary interfaces to be implemented by a tracer. The project comes with OpenZipkin Brave and OpenTelemetry implementations. You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` and `org.springframework.cloud.sleuth.otel.bridge` modules respectively.
Spring Cloud Sleuth API contains all necessary interfaces to be implemented by a tracer.
The project comes with OpenZipkin Brave and OpenTelemetry implementations.
You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` and `org.springframework.cloud.sleuth.otel.bridge` modules respectively.

View File

@@ -1,5 +1,6 @@
[[sleuth-integration]]
= Spring Cloud Sleuth customization
include::_attributes.adoc[]
In this section, we describe how to customize various parts of Spring Cloud Sleuth.
@@ -43,7 +44,8 @@ If you want to skip span creation for some `@Scheduled` annotated classes, you c
This feature is available for both Brave and OpenTelemetry tracer implementation.
We provide `LazyTraceExecutor`, `TraceableExecutorService`, and `TraceableScheduledExecutorService`. Those implementations create spans each time a new task is submitted, invoked, or scheduled.
We provide `LazyTraceExecutor`, `TraceableExecutorService`, and `TraceableScheduledExecutorService`.
Those implementations create spans each time a new task is submitted, invoked, or scheduled.
The following example shows how to pass tracing information with `TraceableExecutorService` when working with `CompletableFuture`:
@@ -56,8 +58,7 @@ include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/inst
IMPORTANT: Sleuth does not work with `parallelStream()` out of the box.
If you want to have the tracing information propagated through the stream, you have to use the approach with `supplyAsync(...)`, as shown earlier.
If there are beans that implement the `Executor` interface that you would like
to exclude from span creation, you can use the `spring.sleuth.async.ignored-beans`
If there are beans that implement the `Executor` interface that you would like to exclude from span creation, you can use the `spring.sleuth.async.ignored-beans`
property where you can provide a list of bean names.
You can disable this behavior by setting the value of `spring.sleuth.async.enabled` to `false`.
@@ -73,11 +74,9 @@ The following example shows how to set up such a custom `Executor`:
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/MultipleAsyncRestTemplateTests.java[tags=custom_executor,indent=0]
----
TIP: To ensure that your configuration gets post processed, remember
to add the `@Role(BeanDefinition.ROLE_INFRASTRUCTURE)` on your
TIP: To ensure that your configuration gets post processed, remember to add the `@Role(BeanDefinition.ROLE_INFRASTRUCTURE)` on your
`@Configuration` class
[[sleuth-http-client-integration]]
== HTTP Client Integration
@@ -101,7 +100,9 @@ If you create a `RestTemplate` instance with a `new` keyword, the instrumentatio
This feature is available for both Brave and OpenTelemetry tracer implementation.
IMPORTANT: Starting with Sleuth `2.0.0`, we no longer register a bean of `AsyncRestTemplate` type. It is up to you to create such a bean. Then we instrument it.
IMPORTANT: Starting with Sleuth `2.0.0`, we no longer register a bean of `AsyncRestTemplate` type.
It is up to you to create such a bean.
Then we instrument it.
To block the `AsyncRestTemplate` features, set `spring.sleuth.web.async.client.enabled` to `false`.
To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper`, set `spring.sleuth.web.async.client.factory.enabled`
@@ -129,7 +130,7 @@ We inject a `ExchangeFilterFunction` implementation that creates a span and, thr
To block this feature, set `spring.sleuth.web.client.enabled` to `false`.
IMPORTANT: You have to register `WebClient` as a bean so that the tracing instrumentation gets applied.
If you create a `WebClient` instance with a `new` keyword, the instrumentation does NOT work.
If you create a `WebClient` instance with a `new` keyword, the instrumentation does NOT work.
[[sleuth-http-client-traverson-integration]]
==== Traverson
@@ -137,8 +138,8 @@ If you create a `WebClient` instance with a `new` keyword, the instrumentation
This feature is available for both Brave and OpenTelemetry tracer implementation.
If you use the https://docs.spring.io/spring-hateoas/docs/current/reference/html/#client.traverson[Traverson] library, you can inject a `RestTemplate` as a bean into your Traverson object.
Since `RestTemplate` is already intercepted, you get full support for tracing in your client. The following pseudo code
shows how to do that:
Since `RestTemplate` is already intercepted, you get full support for tracing in your client.
The following pseudo code shows how to do that:
[source,java,indent=0]
----
@@ -154,8 +155,7 @@ Traverson traverson = new Traverson(URI.create("https://some/address"),
This feature is available for Brave tracer implementation.
We instrument the `HttpClientBuilder` and `HttpAsyncClientBuilder` so that
tracing context gets injected to the sent requests.
We instrument the `HttpClientBuilder` and `HttpAsyncClientBuilder` so that tracing context gets injected to the sent requests.
To block these features, set `spring.sleuth.web.client.enabled` to `false`.
@@ -235,7 +235,9 @@ You can configure which URIs you would like to skip by using the `spring.sleuth.
If you have `ManagementServerProperties` on the classpath, its value of `contextPath` gets appended to the provided skip pattern.
If you want to reuse Sleuth's default skip patterns and append your own, pass those patterns by using the `spring.sleuth.web.additionalSkipPattern`.
In order to achieve best results in terms of performance and context propagation we suggest that you switch the `spring.sleuth.reactor.instrumentation-type` to `MANUAL`. In order to execute code with the span in scope you can call `WebFluxSleuthOperators.withSpanInScope`. Example:
In order to achieve best results in terms of performance and context propagation we suggest that you switch the `spring.sleuth.reactor.instrumentation-type` to `MANUAL`.
In order to execute code with the span in scope you can call `WebFluxSleuthOperators.withSpanInScope`.
Example:
[source,java,indent=0]
-----
@@ -265,8 +267,7 @@ By default, all channels but `hystrixStreamOutput` channel are included.
IMPORTANT: When using the `Executor` to build a Spring Integration `IntegrationFlow`, you must use the untraced version of the `Executor`.
Decorating the Spring Integration Executor Channel with `TraceableExecutorService` causes the spans to be improperly closed.
If you want to customize the way tracing context is read from and written to message headers,
it's enough for you to register beans of types:
If you want to customize the way tracing context is read from and written to message headers, it's enough for you to register beans of types:
* `Propagator.Setter<MessageHeaderAccessor>` - for writing headers to the message
* `Propagator.Getter<MessageHeaderAccessor>` - for reading headers from the message
@@ -276,7 +277,10 @@ it's enough for you to register beans of types:
This feature is available for both Brave and OpenTelemetry tracer implementation.
Spring Cloud Sleuth can instrument Spring Cloud Function. The way to achieve it is to provide a `Function` or `Consumer` or `Supplier` that takes in a `Message` as a parameter e.g. `Function<Message<String>, Message<Integer>>`. If the type is not `Message` then instrumentation will not take place. Out of the box instrumentation will not take place when dealing with Reactor based streams - e.g. `Function<Flux<Message<String>>, Flux<Message<Integer>>>`.
Spring Cloud Sleuth can instrument Spring Cloud Function.
The way to achieve it is to provide a `Function` or `Consumer` or `Supplier` that takes in a `Message` as a parameter e.g. `Function<Message<String>, Message<Integer>>`.
If the type is not `Message` then instrumentation will not take place.
Out of the box instrumentation will not take place when dealing with Reactor based streams - e.g. `Function<Flux<Message<String>>, Flux<Message<Integer>>>`.
Since Spring Cloud Stream reuses Spring Cloud Function, you'll get the instrumentation out of the box.
@@ -294,8 +298,7 @@ include::{project-root}/benchmarks/src/main/java/org/springframework/cloud/sleut
This feature is available for Brave tracer implementation.
We instrument the `RabbitTemplate` so that tracing headers get injected
into the message.
We instrument the `RabbitTemplate` so that tracing headers get injected into the message.
To block this feature, set `spring.sleuth.messaging.rabbit.enabled` to `false`.
@@ -315,9 +318,7 @@ To block this feature, set `spring.sleuth.messaging.kafka.enabled` to `false`.
This feature is available for Brave tracer implementation.
We instrument the `KafkaStreams` `KafkaClientSupplier` so that tracing headers
get injected into the `Producer` and `Consumer`s. A `KafkaStreamsTracing` bean
allows for further instrumentation through additional `TransformerSupplier` and
We instrument the `KafkaStreams` `KafkaClientSupplier` so that tracing headers get injected into the `Producer` and `Consumer`s. A `KafkaStreamsTracing` bean allows for further instrumentation through additional `TransformerSupplier` and
`ProcessorSupplier` methods.
To block this feature, set `spring.sleuth.messaging.kafka.streams.enabled` to `false`.
@@ -327,8 +328,8 @@ To block this feature, set `spring.sleuth.messaging.kafka.streams.enabled` to `f
This feature is available for Brave tracer implementation.
We instrument the `JmsTemplate` so that tracing headers get injected
into the message. We also support `@JmsListener` annotated methods on the consumer side.
We instrument the `JmsTemplate` so that tracing headers get injected into the message.
We also support `@JmsListener` annotated methods on the consumer side.
To block this feature, set `spring.sleuth.messaging.jms.enabled` to `false`.
@@ -348,7 +349,6 @@ You can disable it by setting `spring.sleuth.feign.processor.enabled` to `false`
If you set it to `false`, Spring Cloud Sleuth does not instrument any of your custom Feign components.
However, all the default instrumentation is still there.
[[sleuth-opentracing-integration]]
== OpenTracing
@@ -372,14 +372,20 @@ To turn off this feature, set the `spring.sleuth.quartz.enabled` property to `fa
This feature is available for both Brave and OpenTelemetry tracer implementation.
We have three modes of instrumenting reactor based applications that can
be set via `spring.sleuth.reactor.instrumentation-type` property:
We have three modes of instrumenting reactor based applications that can be set via `spring.sleuth.reactor.instrumentation-type` property:
* `ON_EACH` - wraps every Reactor operator in a trace representation. Passes the tracing context in most cases. This mode might lead to drastic performance degradation.
* `ON_LAST` - wraps last Reactor operator in a trace representation. Passes the tracing context in some cases thus accessing MDC context might not work. This mode might lead to medium performance degradation.
* `MANUAL` - wraps every Reactor in the least invasive way without passing of tracing context. It's up to the user to do it.
* `ON_EACH` - wraps every Reactor operator in a trace representation.
Passes the tracing context in most cases.
This mode might lead to drastic performance degradation.
* `ON_LAST` - wraps last Reactor operator in a trace representation.
Passes the tracing context in some cases thus accessing MDC context might not work.
This mode might lead to medium performance degradation.
* `MANUAL` - wraps every Reactor in the least invasive way without passing of tracing context.
It's up to the user to do it.
Current default is `ON_EACH` for backward compatibility reasons, however we encourage the users to migrate to the `MANUAL` instrumentation and profit from `WebFluxSleuthOperators` and `MessagingSleuthOperators`. The performance improvement can be substantial. Example:
Current default is `ON_EACH` for backward compatibility reasons, however we encourage the users to migrate to the `MANUAL` instrumentation and profit from `WebFluxSleuthOperators` and `MessagingSleuthOperators`.
The performance improvement can be substantial.
Example:
[source,java,indent=0]
-----
@@ -403,45 +409,41 @@ If you wrap your logic in `Runnable` or `Callable`, you can wrap those classes i
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=trace_runnable,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_runnable,indent=0]
----
The following example shows how to do so for `Callable`:
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=trace_callable,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=trace_callable,indent=0]
----
That way, you ensure that a new span is created and closed for each execution.
[[sleuth-rpc-integration]]
== RPC
This feature is available for Brave tracer implementation.
Sleuth automatically configures the `RpcTracing` bean which serves as a
foundation for RPC instrumentation such as gRPC or Dubbo.
Sleuth automatically configures the `RpcTracing` bean which serves as a foundation for RPC instrumentation such as gRPC or Dubbo.
If a customization of client / server sampling of the RPC traces is required,
just register a bean of type `brave.sampler.SamplerFunction<RpcRequest>` and
name the bean `sleuthRpcClientSampler` for client sampler and
If a customization of client / server sampling of the RPC traces is required, just register a bean of type `brave.sampler.SamplerFunction<RpcRequest>` and name the bean `sleuthRpcClientSampler` for client sampler and
`sleuthRpcServerSampler` for server sampler.
For your convenience the `@RpcClientSampler` and `@RpcServerSampler`
annotations can be used to inject the proper beans or to reference the bean
names via their static String `NAME` fields.
annotations can be used to inject the proper beans or to reference the bean names via their static String `NAME` fields.
Ex. Here's a sampler that traces 100 "GetUserToken" server requests per second.
This doesn't start new traces for requests to the health check service. Other
requests will use the global sampling configuration.
Ex.
Here's a sampler that traces 100 "GetUserToken" server requests per second.
This doesn't start new traces for requests to the health check service.
Other requests will use the global sampling configuration.
[source,java,indent=0]
----
@Configuration(proxyBeanMethods = false)
class Config {
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java[tags=custom_rpc_server_sampler,indent=2]
include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/rpc/BraveRpcAutoConfigurationIntegrationTests.java[tags=custom_rpc_server_sampler,indent=2]
}
----
@@ -474,16 +476,19 @@ An example of Spring Cloud Sleuth and Dubbo can be found https://github.com/open
[[sleuth-rpc-grpc-integration]]
=== gRPC
Spring Cloud Sleuth provides instrumentation for https://grpc.io/[gRPC] through `TraceGrpcAutoConfiguration` via the Brave tracer. You can disable it entirely by setting `spring.sleuth.grpc.enabled` to `false`.
Spring Cloud Sleuth provides instrumentation for https://grpc.io/[gRPC] via the Brave tracer.
You can disable it entirely by setting `spring.sleuth.grpc.enabled` to `false`.
[[sleuth-rpc-grpc-variant1-integration]]
==== Variant 1
[[sleuth-rpc-grpc-variant1-dependencies-integration]]
===== Dependencies
IMPORTANT: The gRPC integration relies on two external libraries to instrument clients and servers and both of those libraries must be on the class path to enable the instrumentation.
Maven:
```
<dependency>
<groupId>io.github.lognet</groupId>
@@ -494,7 +499,9 @@ Maven:
<artifactId>brave-instrumentation-grpc</artifactId>
</dependency>
```
Gradle:
```
compile("io.github.lognet:grpc-spring-boot-starter")
compile("io.zipkin.brave:brave-instrumentation-grpc")
@@ -508,9 +515,11 @@ Spring Cloud Sleuth leverages grpc-spring-boot-starter to register Brave's gRPC
[[sleuth-rpc-grpc-variant1-client-integration]]
===== Client Instrumentation
gRPC clients leverage a `ManagedChannelBuilder` to construct a `ManagedChannel` used to communicate to the gRPC server. The native `ManagedChannelBuilder` provides static methods as entry points for construction of `ManagedChannel` instances, however, this mechanism is outside the influence of the Spring application context.
gRPC clients leverage a `ManagedChannelBuilder` to construct a `ManagedChannel` used to communicate to the gRPC server.
The native `ManagedChannelBuilder` provides static methods as entry points for construction of `ManagedChannel` instances, however, this mechanism is outside the influence of the Spring application context.
IMPORTANT: Spring Cloud Sleuth provides a `SpringAwareManagedChannelBuilder` that can be customized through the Spring application context and injected by gRPC clients. *This builder must be used when creating `ManagedChannel` instances.*
IMPORTANT: Spring Cloud Sleuth provides a `SpringAwareManagedChannelBuilder` that can be customized through the Spring application context and injected by gRPC clients.
*This builder must be used when creating `ManagedChannel` instances.*
Sleuth creates a `TracingManagedChannelBuilderCustomizer` which inject Brave's client interceptor into the `SpringAwareManagedChannelBuilder`.
@@ -531,12 +540,12 @@ To disable the custom `RxJavaSchedulersHook`, set the `spring.sleuth.rxjava.sche
You can define a list of regular expressions for thread names for which you do not want spans to be created.
To do so, provide a comma-separated list of regular expressions in the `spring.sleuth.rxjava.schedulers.ignoredthreads` property.
IMPORTANT: The suggested approach to reactive programming and Sleuth is to use
the Reactor support.
IMPORTANT: The suggested approach to reactive programming and Sleuth is to use the Reactor support.
[[sleuth-circuitbreaker-integration]]
== Spring Cloud CircuitBreaker
This feature is available for both Brave and OpenTelemetry tracer implementation.
If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations. In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`.
If you have Spring Cloud CircuitBreaker on the classpath, we will wrap the passed command `Supplier` and the fallback `Function` in its trace representations.
In order to disable this instrumentation set `spring.sleuth.circuitbreaker.enabled` to `false`.

View File

@@ -5,7 +5,4 @@
Copyright &#169; 2012-2020
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.
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

@@ -1,24 +1,21 @@
[[features]]
[[project-features]]
= Spring Cloud Sleuth Features
include::_attributes.adoc[]
This section dives into the details of {project-full-name}. Here you can learn about the key
features that you may want to use and customize. If you have not already done so, you
might want to read the "<<getting-started.adoc#getting-started>>" and
"<<using.adoc#using>>" sections, so that you have a good grounding in the
basics.
This section dives into the details of {project-full-name}.
Here you can learn about the key features that you may want to use and customize.
If you have not already done so, you might want to read the "<<getting-started.adoc#getting-started>>" and "<<using.adoc#using>>" sections, so that you have a good grounding in the basics.
[[features-context-propagation]]
== Context Propagation
Traces connect from service to service using header propagation. The default
format is https://github.com/openzipkin/b3-propagation[B3]. Similar to data
formats, you can configure alternate header formats also, provided trace and
span IDs are compatible with B3. Most notably, this means the trace ID and span
IDs are lower-case hex, not UUIDs. Besides trace identifiers, other properties
(Baggage) can also be passed along with the request. Remote Baggage must be
predefined, but is flexible otherwise.
Traces connect from service to service using header propagation.
The default format is https://github.com/openzipkin/b3-propagation[B3].
Similar to data formats, you can configure alternate header formats also, provided trace and span IDs are compatible with B3. Most notably, this means the trace ID and span IDs are lower-case hex, not UUIDs.
Besides trace identifiers, other properties (Baggage) can also be passed along with the request.
Remote Baggage must be predefined, but is flexible otherwise.
To use the provided defaults you can set the `spring.sleuth.propagation.type` property.
The value can be a list in which case you will propagate more tracing headers.
@@ -31,21 +28,21 @@ You can read more about how to provide custom context propagation in this "<<how
[[features-sampling]]
== Sampling
Spring Cloud Sleuth pushes the sampling decision down to the tracer implementation. However, there are cases where you can change the sampling decision at runtime.
Spring Cloud Sleuth pushes the sampling decision down to the tracer implementation.
However, there are cases where you can change the sampling decision at runtime.
One of such cases is skip reporting of certain client spans. To achieve that you can set the `spring.sleuth.web.client.skip-pattern` with the path patterns to be skipped. Another option is to provide your own custom `org.springframework.cloud.sleuth.api.SamplerFunction<`org.springframework.cloud.sleuth.api.http.HttpRequest>` implementation and define when a given `HttpRequest` should not be sampled.
One of such cases is skip reporting of certain client spans.
To achieve that you can set the `spring.sleuth.web.client.skip-pattern` with the path patterns to be skipped.
Another option is to provide your own custom `org.springframework.cloud.sleuth.SamplerFunction<`org.springframework.cloud.sleuth.http.HttpRequest>` implementation and define when a given `HttpRequest` should not be sampled.
[[features-baggage]]
== Baggage
Distributed tracing works by propagating fields inside and across services that
connect the trace together: traceId and spanId notably. The context that holds
these fields can optionally push other fields that need to be consistent
regardless of many services are touched. The simple name for these extra fields
is "Baggage".
Distributed tracing works by propagating fields inside and across services that connect the trace together: traceId and spanId notably.
The context that holds these fields can optionally push other fields that need to be consistent regardless of many services are touched.
The simple name for these extra fields is "Baggage".
Sleuth allows you to define which baggage are permitted to exist in the trace
context, including what header names are used.
Sleuth allows you to define which baggage are permitted to exist in the trace context, including what header names are used.
The following example shows setting baggage values using Spring Cloud Sleuth's API:
@@ -54,28 +51,24 @@ The following example shows setting baggage values using Spring Cloud Sleuth's A
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/baggage/multiple/MultipleHopsIntegrationTests.java[tags=baggage,indent=0]
----
IMPORTANT: There is currently no limitation of the count or size of baggage
items. Keep in mind that too many can decrease system throughput or increase
RPC latency. In extreme cases, too much baggage can crash the application, due
to exceeding transport-level message or header capacity.
IMPORTANT: There is currently no limitation of the count or size of baggage items.
Keep in mind that too many can decrease system throughput or increase RPC latency.
In extreme cases, too much baggage can crash the application, due to exceeding transport-level message or header capacity.
You can use
properties to define fields that have no special configuration such as name mapping:
You can use properties to define fields that have no special configuration such as name mapping:
* `spring.sleuth.baggage.remote-fields` is a list of header names to accept and propagate to remote services.
* `spring.sleuth.baggage.local-fields` is a list of names to propagate locally
No prefixing applies with these keys. What you set is literally what is used.
No prefixing applies with these keys.
What you set is literally what is used.
A name set in either of these properties will result in a `Baggage` of the same name.
In order to automatically set the baggage values to Slf4j's MDC, you have to set
the `spring.sleuth.baggage.correlation-fields` property with a list of allowed
local or remote keys. E.g. `spring.sleuth.baggage.correlation-fields=country-code` will set the
value of the `country-code` baggage into MDC.
In order to automatically set the baggage values to Slf4j's MDC, you have to set the `spring.sleuth.baggage.correlation-fields` property with a list of allowed local or remote keys. E.g. `spring.sleuth.baggage.correlation-fields=country-code` will set the value of the `country-code` baggage into MDC.
Note that the extra field is propagated and added to MDC starting with the next downstream trace context. To immediately
add the extra field to MDC in the current trace context, configure the field to flush on update:
Note that the extra field is propagated and added to MDC starting with the next downstream trace context.
To immediately add the extra field to MDC in the current trace context, configure the field to flush on update:
```
// configuration
@@ -104,18 +97,19 @@ countryCodeField.updateValue("new-value");
IMPORTANT: Remember that adding entries to MDC can drastically decrease the performance of your application!
If you want to add the baggage entries as tags, to make it possible to search for spans via the baggage entries, you can set the value of
`spring.sleuth.baggage.tag-fields` with a list of allowed baggage keys. To disable the feature you have to pass the `spring.sleuth.propagation.tag.enabled=false` property.
`spring.sleuth.baggage.tag-fields` with a list of allowed baggage keys.
To disable the feature you have to pass the `spring.sleuth.propagation.tag.enabled=false` property.
[[features-baggage-vs-tags]]
=== Baggage versus Tags
Like trace IDs, Baggage is attached to messages or requests, usually as
headers. Tags are key value pairs sent in a Span to Zipkin. Baggage values are
not added spans by default, which means you can't search based on Baggage
unless you opt-in.
Like trace IDs, Baggage is attached to messages or requests, usually as headers.
Tags are key value pairs sent in a Span to Zipkin.
Baggage values are not added spans by default, which means you can't search based on Baggage unless you opt-in.
To make baggage also tags, use the property `spring.sleuth.baggage.tag-fields`
like so:
[source,yml]
----
include::{brave_path}/src/test/resources/application-baggage.yml[indent=0]
@@ -124,9 +118,11 @@ include::{brave_path}/src/test/resources/application-baggage.yml[indent=0]
[[features-brave]]
== OpenZipkin Brave Tracer Integration
Spring Cloud Sleuth integrates with the OpenZipkin Brave tracer via the bridge that is available in the `spring-cloud-sleuth-brave` module. In this section you can read about specific Brave integrations.
Spring Cloud Sleuth integrates with the OpenZipkin Brave tracer via the bridge that is available in the `spring-cloud-sleuth-brave` module.
In this section you can read about specific Brave integrations.
You can choose to use either Sleuth's API or the Brave API directly in your code (e.g. either Sleuth's `Tracer` or Brave's `Tracer`). If you want to use this tracer implementation's API directly please read https://github.com/openzipkin/brave[their documentation to learn more about it].
You can choose to use either Sleuth's API or the Brave API directly in your code (e.g. either Sleuth's `Tracer` or Brave's `Tracer`).
If you want to use this tracer implementation's API directly please read https://github.com/openzipkin/brave[their documentation to learn more about it].
[[features-brave-basics]]
=== Brave Basics
@@ -145,25 +141,28 @@ Here are the most relevant links from the OpenZipkin Brave project:
[[features-brave-sampling]]
=== Brave Sampling
Sampling only applies to tracing backends, such as Zipkin. Trace IDs appear in logs regardless of
sample rate. Sampling is a way to prevent overloading the system, by consistently tracing some, but
not all requests.
Sampling only applies to tracing backends, such as Zipkin.
Trace IDs appear in logs regardless of sample rate.
Sampling is a way to prevent overloading the system, by consistently tracing some, but not all requests.
The default rate of 10 traces per second is controlled by the `spring.sleuth.sampler.rate`
property and applies when we know Sleuth is used for reasons besides logging. Use a rate above 100
traces per second with extreme caution as it can overload your tracing system.
property and applies when we know Sleuth is used for reasons besides logging.
Use a rate above 100 traces per second with extreme caution as it can overload your tracing system.
The sampler can be set by Java Config also, as shown in the following example:
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=always_sampler,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=always_sampler,indent=0]
----
TIP: You can set the HTTP header `b3` to `1`, or, when doing messaging, you can set the `spanFlags` header to `1`.
Doing so forces the current request to be sampled regardless of configuration.
By default samplers will work with the refresh scope mechanism. That means that you can change the sampling properties at runtime, refresh the application and the changes will be reflected. However, sometimes the fact of creating a proxy around samplers and calling it from too early (from `@PostConstruct` annotated method) may lead to dead locks. In such a case either create a sampler bean explicitly, or set the property `spring.sleuth.sampler.refresh.enabled` to `false` to disable the refresh scope support.
By default samplers will work with the refresh scope mechanism.
That means that you can change the sampling properties at runtime, refresh the application and the changes will be reflected.
However, sometimes the fact of creating a proxy around samplers and calling it from too early (from `@PostConstruct` annotated method) may lead to dead locks.
In such a case either create a sampler bean explicitly, or set the property `spring.sleuth.sampler.refresh.enabled` to `false` to disable the refresh scope support.
[[features-brave-baggage]]
=== Brave Baggage Java configuration
@@ -179,12 +178,10 @@ If you need to do anything more advanced than above, do not define properties an
[[features-brave-customizations]]
=== Brave Customizations
The `brave.Tracer` object is fully managed by sleuth, so you rarely need to affect it. That said,
Sleuth supports a number of `Customizer` types, that allow you to configure
anything not already done by Sleuth with auto-configuration or properties.
The `brave.Tracer` object is fully managed by sleuth, so you rarely need to affect it.
That said, Sleuth supports a number of `Customizer` types, that allow you to configure anything not already done by Sleuth with auto-configuration or properties.
If you define one of the following as a `Bean`, Sleuth will invoke it to
customize behaviour:
If you define one of the following as a `Bean`, Sleuth will invoke it to customize behaviour:
* `RpcTracingCustomizer` - for RPC tagging and sampling policy
* `HttpTracingCustomizer` - for HTTP tagging and sampling policy
@@ -196,21 +193,20 @@ customize behaviour:
[[features-brave-sampling-customizations]]
==== Brave Sampling Customizations
If client /server sampling is required, just register a bean of type
`brave.sampler.SamplerFunction<HttpRequest>` and name the bean
If client /server sampling is required, just register a bean of type
`brave.sampler.SamplerFunction<HttpRequest>` and name the bean
`sleuthHttpClientSampler` for client sampler and `sleuthHttpServerSampler`
for server sampler.
for server sampler.
For your convenience the `@HttpClientSampler` and `@HttpServerSampler`
annotations can be used to inject the proper beans or to reference the bean
names via their static String `NAME` fields.
annotations can be used to inject the proper beans or to reference the bean names via their static String `NAME` fields.
Check out Brave's code to see an example of how to make a path-based sampler
https://github.com/openzipkin/brave/tree/master/instrumentation/http#sampling-policy
If you want to completely rewrite the `HttpTracing` bean you can use the `SkipPatternProvider`
interface to retrieve the URL `Pattern` for spans that should be not sampled. Below you can see
an example of usage of `SkipPatternProvider` inside a server side, `Sampler<HttpRequest>`.
interface to retrieve the URL `Pattern` for spans that should be not sampled.
Below you can see an example of usage of `SkipPatternProvider` inside a server side, `Sampler<HttpRequest>`.
[source,java,indent=0]
----
@@ -223,27 +219,24 @@ include::{tests_path}/brave/spring-cloud-sleuth-instrumentation-mvc-tests/src/te
[[features-brave-messaging]]
=== Brave Messaging
Sleuth automatically configures the `MessagingTracing` bean which serves as a
foundation for Messaging instrumentation such as Kafka or JMS.
Sleuth automatically configures the `MessagingTracing` bean which serves as a foundation for Messaging instrumentation such as Kafka or JMS.
If a customization of producer / consumer sampling of messaging traces is required,
just register a bean of type `brave.sampler.SamplerFunction<MessagingRequest>` and
name the bean `sleuthProducerSampler` for producer sampler and `sleuthConsumerSampler`
If a customization of producer / consumer sampling of messaging traces is required, just register a bean of type `brave.sampler.SamplerFunction<MessagingRequest>` and name the bean `sleuthProducerSampler` for producer sampler and `sleuthConsumerSampler`
for consumer sampler.
For your convenience the `@ProducerSampler` and `@ConsumerSampler`
annotations can be used to inject the proper beans or to reference the bean
names via their static String `NAME` fields.
annotations can be used to inject the proper beans or to reference the bean names via their static String `NAME` fields.
Ex. Here's a sampler that traces 100 consumer requests per second, except for
the "alerts" channel. Other requests will use a global rate provided by the
Ex.
Here's a sampler that traces 100 consumer requests per second, except for the "alerts" channel.
Other requests will use a global rate provided by the
`Tracing` component.
[source,java,indent=0]
----
@Configuration(proxyBeanMethods = false)
class Config {
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java[tags=custom_messaging_consumer_sampler,indent=2]
include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/instrument/messaging/BraveMessagingAutoConfigurationIntegrationTests.java[tags=custom_messaging_consumer_sampler,indent=2]
}
----
@@ -253,34 +246,43 @@ For more, see https://github.com/openzipkin/brave/tree/master/instrumentation/me
=== Brave Opentracing
You can integrate with Brave and https://opentracing.io/[OpenTracing] via the
`io.opentracing.brave:brave-opentracing` bridge. Just add it to the classpath and the OpenTracing `Tracer` will be set up automatically.
`io.opentracing.brave:brave-opentracing` bridge.
Just add it to the classpath and the OpenTracing `Tracer` will be set up automatically.
[[features-otel]]
== OpenTelemetry Tracer Integration
Spring Cloud Sleuth integrates with the OpenTelemetry (OTel in short) SDK tracer via the bridge that is available in the `spring-cloud-sleuth-otel` module. In this section you can read about specific OTel integrations.
Spring Cloud Sleuth integrates with the OpenTelemetry (OTel in short) SDK tracer via the bridge that is available in the `spring-cloud-sleuth-otel` module.
In this section you can read about specific OTel integrations.
You can choose to use either Sleuth's API or the OpenTelemetry API directly in your code (e.g. either Sleuth's `Tracer` or OpenTelemetry's `Tracer`). If you want to use this tracer implementation's API directly please read https://github.com/open-telemetry/opentelemetry-java[their documentation to learn more about it].
You can choose to use either Sleuth's API or the OpenTelemetry API directly in your code (e.g. either Sleuth's `Tracer` or OpenTelemetry's `Tracer`).
If you want to use this tracer implementation's API directly please read https://github.com/open-telemetry/opentelemetry-java[their documentation to learn more about it].
[[features-otel-logging]]
=== OpenTelemetry Logging Integration
We're providing an Slf4j integration via a `SpanProcessor` that injects to and removes entries (trace / span ids, baggage, tags etc.) from MDC. You can disable that via the `spring.sleuth.otel.log.slf4j.enabled=false` property.
If it's there on the classpath, we integrate with the `LoggingSpanExporter`. You can disable that integration via the `spring.sleuth.otel.log.exporter.enabled=false` property.
If it's there on the classpath, we integrate with the `LoggingSpanExporter`.
You can disable that integration via the `spring.sleuth.otel.log.exporter.enabled=false` property.
[[features-otel-opentracing]]
=== OpenTelemetry Opentracing
You can integrate with OpenTelemetry and https://opentracing.io/[OpenTracing] via the
`io.opentelemetry:opentelemetry-opentracing-shim` bridge. Just add it to the classpath and the OpenTracing `Tracer` will be set up automatically.
`io.opentelemetry:opentelemetry-opentracing-shim` bridge.
Just add it to the classpath and the OpenTracing `Tracer` will be set up automatically.
[[features-zipkin]]
== Sending Spans to Zipkin
Spring Cloud Sleuth provides various integrations with the https://zipkin.io[OpenZipkin] distributed tracing system. Regardless of the chosen tracer implementation it's enough to add `spring-cloud-sleuth-zipkin` to the classpath to start sending spans to Zipkin. You can choose whether to do that via HTTP or messaging. You can read more about how to do that in "<<howto.adoc#how-to-set-up-sleuth-with-brave-zipkin-messaging,how to section>>".
Spring Cloud Sleuth provides various integrations with the https://zipkin.io[OpenZipkin] distributed tracing system.
Regardless of the chosen tracer implementation it's enough to add `spring-cloud-sleuth-zipkin` to the classpath to start sending spans to Zipkin.
You can choose whether to do that via HTTP or messaging.
You can read more about how to do that in "<<howto.adoc#how-to-set-up-sleuth-with-brave-zipkin-messaging,how to section>>".
When the span is closed, it is sent to Zipkin over HTTP. The communication is asynchronous. You can configure the URL by setting the `spring.zipkin.baseUrl` property, as follows:
When the span is closed, it is sent to Zipkin over HTTP. The communication is asynchronous.
You can configure the URL by setting the `spring.zipkin.baseUrl` property, as follows:
[source,yaml]
----
@@ -297,8 +299,8 @@ spring.zipkin.baseUrl: https://zipkinserver/
To disable this feature just set `spring.zipkin.discovery-client-enabled` to `false.
When the Discovery Client feature is enabled, Sleuth uses
`LoadBalancerClient` to find the URL of the Zipkin Server. It means
that you can set up the load balancing configuration.
`LoadBalancerClient` to find the URL of the Zipkin Server.
It means that you can set up the load balancing configuration.
If you have `web`, `rabbit`, `activemq` or `kafka` together on the classpath, you might need to pick the means by which you would like to send spans to zipkin.
To do so, set `web`, `rabbit`, `activemq` or `kafka` to the `spring.zipkin.sender.type` property.
@@ -309,8 +311,7 @@ The following example shows setting the sender type for `web`:
spring.zipkin.sender.type: web
----
To customize the `RestTemplate` that sends spans to Zipkin via HTTP, you can register
the `ZipkinRestTemplateCustomizer` bean.
To customize the `RestTemplate` that sends spans to Zipkin via HTTP, you can register the `ZipkinRestTemplateCustomizer` bean.
[source,java,indent=0]
----
@@ -376,14 +377,16 @@ spring.zipkin.locator.discovery.enabled: true
In Sleuth, we generate spans with a fixed name.
Some users want to modify the name depending on values of tags.
Sleuth registers a `SpanFilter` bean that can automatically skip reporting spans of given name patterns. The property `spring.sleuth.span-filter.span-name-patterns-to-skip` contains the default skip patterns for span names. The property `spring.sleuth.span-filter.additional-span-name-patterns-to-skip` will append the provided span name patterns to the existing ones. In order to disable this functionality just set `spring.sleuth.span-filter.enabled` to `false`.
Sleuth registers a `SpanFilter` bean that can automatically skip reporting spans of given name patterns.
The property `spring.sleuth.span-filter.span-name-patterns-to-skip` contains the default skip patterns for span names.
The property `spring.sleuth.span-filter.additional-span-name-patterns-to-skip` will append the provided span name patterns to the existing ones.
In order to disable this functionality just set `spring.sleuth.span-filter.enabled` to `false`.
[[features-zipkin-custom-reported-spans-brave]]
==== Brave Customization of Reported Spans
IMPORTANT: This section is applicable for Brave tracer only.
Before reporting spans (for example, to Zipkin) you may want to modify that span in some way.
You can do so by implementing a `SpanHandler`.
@@ -391,33 +394,30 @@ The following example shows how to register two beans that implement `SpanHandle
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java[tags=spanHandler,indent=0]
include::{autoconfig_path}/src/test/java/org/springframework/cloud/sleuth/autoconfig/brave/SpanHandlerTests.java[tags=spanHandler,indent=0]
----
The preceding example results in changing the name of the reported span to `foo bar`, just before it gets reported (for example, to Zipkin).
=== Overriding the auto-configuration of Zipkin
Spring Cloud Sleuth supports sending traces to multiple tracing systems as of version 2.1.0.
In order to get this to work, every tracing system needs to have a `Reporter<Span>` and `Sender`.
Spring Cloud Sleuth supports sending traces to multiple tracing systems as of version 2.1.0. In order to get this to work, every tracing system needs to have a `Reporter<Span>` and `Sender`.
If you want to override the provided beans you need to give them a specific name.
To do this you can use respectively `ZipkinAutoConfiguration.REPORTER_BEAN_NAME` and `ZipkinAutoConfiguration.SENDER_BEAN_NAME`.
[source,java,indent=0]
----
include::{project-root}/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin2/ZipkinAutoConfigurationTests.java[tags=override_default_beans,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/autoconfig/zipkin2/ZipkinAutoConfigurationTests.java[tags=override_default_beans,indent=0]
----
[[features-log-integration]]
== Log integration
Sleuth configures the logging context with variables including the service name
(`%{spring.zipkin.service.name}` or `%{spring.application.name}` if the previous one was not set), span ID (`%{spanId}`) and the trace ID (`%{traceId}`). These help
you connect logs with distributed traces and allow you choice in what tools you
use to troubleshoot your services.
Sleuth configures the logging context with variables including the service name (`%{spring.zipkin.service.name}` or `%{spring.application.name}` if the previous one was not set), span ID (`%{spanId}`) and the trace ID (`%{traceId}`).
These help you connect logs with distributed traces and allow you choice in what tools you use to troubleshoot your services.
Once you find any log with an error, you can look for the trace ID in the
message. Paste that into your distributed tracing system to visualize the entire trace, regardless of how many services the first request ended up hitting.
Once you find any log with an error, you can look for the trace ID in the message.
Paste that into your distributed tracing system to visualize the entire trace, regardless of how many services the first request ended up hitting.
[source]
----
@@ -425,8 +425,9 @@ backend.log: 2020-04-09 17:45:40.516 ERROR [backend,5e8eeec48b08e26882aba313eb0
frontend.log:2020-04-09 17:45:40.574 ERROR [frontend,5e8eeec48b08e26882aba313eb08f0a4,82aba313eb08f0a4,true] 97192 --- [nio-8081-exec-2] o.s.c.s.i.web.ExceptionLoggingFilter : Uncaught exception thrown
----
Above, you'll notice the trace ID is `5e8eeec48b08e26882aba313eb08f0a4`, for
example. This log configuration was automatically setup by Sleuth. You can disable it by disabling Sleuth via `spring.sleuth.enabled=false` property or putting your own `logging.pattern.level` property.
Above, you'll notice the trace ID is `5e8eeec48b08e26882aba313eb08f0a4`, for example.
This log configuration was automatically setup by Sleuth.
You can disable it by disabling Sleuth via `spring.sleuth.enabled=false` property or putting your own `logging.pattern.level` property.
If you use a log aggregating tool (such as https://www.elastic.co/products/kibana[Kibana], https://www.splunk.com/[Splunk], and others), you can order the events that took place.
An example from Kibana would resemble the following image:
@@ -452,6 +453,7 @@ filter {
----
NOTE: If you want to use Grok together with the logs from Cloud Foundry, you have to use the following pattern:
[source]
----
filter {
@@ -477,7 +479,8 @@ To do so, you have to do the following (for readability, we pass the dependencie
*Dependencies Setup*
. Ensure that Logback is on the classpath (`ch.qos.logback:logback-core`).
. Add Logstash Logback encode. For example, to use version `4.6`, add `net.logstash.logback:logstash-logback-encoder:4.6`.
. Add Logstash Logback encode.
For example, to use version `4.6`, add `net.logstash.logback:logstash-logback-encoder:4.6`.
*Logback Setup*
@@ -501,9 +504,9 @@ Otherwise, your custom logback file does not properly read the property.
== What to Read Next
If you want to learn more about any of the classes discussed in this section, you can browse the
{github-code}[source code directly]. If you have specific questions, see the
{github-code}[source code directly].
If you have specific questions, see the
<<howto.adoc#howto, how-to>> section.
If you are comfortable with {project-full-name}'s core features, you can continue on and read
about
If you are comfortable with {project-full-name}'s core features, you can continue on and read about
<<integrations.adoc, {project-full-name}'s integrations>>.

View File

@@ -65,10 +65,11 @@ public class Application {
}
```
Run this app and then hit the home page. You will see traceId and spanId populated in the logs.
If this app calls out to another one (e.g. with `RestTemplate`) it will send the trace data in
headers and if the receiver is another Sleuth app you will see the trace continue there.
Run this app and then hit the home page.
You will see traceId and spanId populated in the logs.
If this app calls out to another one (e.g. with `RestTemplate`) it will send the trace data in headers and if the receiver is another Sleuth app you will see the trace continue there.
* Instead of logging the request in the handler explicitly, you could set `logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG`
* Sleuth defaults to a rate limited sampler. That means that it will sample up to 1000 transactions per second.
* Sleuth defaults to a rate limited sampler.
That means that it will sample up to 1000 transactions per second.
* Set `spring.application.name=bar` (for instance) to see the service name as well as the trace and span ids.

View File

@@ -1,14 +1,13 @@
Spring Cloud Sleuth provides Spring Boot auto-configuration for distributed
tracing.
Spring Cloud Sleuth provides Spring Boot auto-configuration for distributed tracing.
## Features
Sleuth configures everything you need to get started. This includes where trace
data (spans) are reported to, how many traces to keep (sampling), if remote
fields (baggage) are sent, and which libraries are traced.
Sleuth configures everything you need to get started.
This includes where trace data (spans) are reported to, how many traces to keep (sampling), if remote fields (baggage) are sent, and which libraries are traced.
Specifically, Spring Cloud Sleuth...
* Adds trace and span ids to the Slf4J MDC, so you can extract all the logs from a given trace or span in a log aggregator.
* Instruments common ingress and egress points from Spring applications (servlet filter, rest template, scheduled actions, message channels, feign client).
* If `spring-cloud-sleuth-zipkin` is available then the app will generate and report https://zipkin.io[Zipkin]-compatible traces via HTTP. By default it sends them to a Zipkin collector service on localhost (port 9411). Configure the location of the service using `spring.zipkin.baseUrl`.
* If `spring-cloud-sleuth-zipkin` is available then the app will generate and report https://zipkin.io[Zipkin]-compatible traces via HTTP. By default it sends them to a Zipkin collector service on localhost (port 9411).
Configure the location of the service using `spring.zipkin.baseUrl`.

View File

@@ -1,8 +1,11 @@
[[using]]
= Using Spring Cloud Sleuth
include::_attributes.adoc[]
This section goes into more detail about how you should use {project-full-name}. It covers topics such as controlling the span lifecycle with {project-full-name} API or via annotations. We also cover some {project-full-name} best practices.
This section goes into more detail about how you should use {project-full-name}.
It covers topics such as controlling the span lifecycle with {project-full-name} API or via annotations.
We also cover some {project-full-name} best practices.
If you are starting out with {project-full-name}, you should probably read the
<<getting-started.adoc#getting-started, Getting Started>> guide before diving into this section.
@@ -10,12 +13,15 @@ If you are starting out with {project-full-name}, you should probably read the
[[using-span-lifecycle]]
== Span Lifecycle with Spring Cloud Sleuth's API
Spring Cloud Sleuth Core in its `api` module contains all necessary interfaces to be implemented by a tracer. The project comes with OpenZipkin Brave and OpenTelemetry implementations. You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` and `org.springframework.cloud.sleuth.otel.bridge` modules respectively.
Spring Cloud Sleuth Core in its `api` module contains all necessary interfaces to be implemented by a tracer.
The project comes with OpenZipkin Brave and OpenTelemetry implementations.
You can check how both tracers are bridged to the Sleuth's API by looking at the `org.springframework.cloud.sleuth.brave.bridge` and `org.springframework.cloud.sleuth.otel.bridge` modules respectively.
The most commonly used interfaces are:
* `org.springframework.cloud.sleuth.api.Tracer` - Using a tracer, you can create a root span capturing the critical path of a request.
* `org.springframework.cloud.sleuth.api.Span` - Span is a single unit of work that needs to be started and stopped. Contains timing information and events and tags.
* `org.springframework.cloud.sleuth.Tracer` - Using a tracer, you can create a root span capturing the critical path of a request.
* `org.springframework.cloud.sleuth.Span` - Span is a single unit of work that needs to be started and stopped.
Contains timing information and events and tags.
You can also use your tracer implementation's API directly.
@@ -26,7 +32,8 @@ Let's look at the following Span lifecycle actions.
* <<using-continuing-spans, continue>>: The span gets continued e.g. in another thread.
* <<using-creating-spans-with-explicit-parent, create with explicit parent>>: You can create a new span and set an explicit parent for it.
TIP: Spring Cloud Sleuth creates an instance of `Tracer` for you. In order to use it, you can autowire it.
TIP: Spring Cloud Sleuth creates an instance of `Tracer` for you.
In order to use it, you can autowire it.
[[using-creating-and-ending-spans]]
=== Creating and Ending Spans
@@ -35,7 +42,7 @@ You can manually create spans by using the `Tracer`, as shown in the following e
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=manual_span_creation,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=manual_span_creation,indent=0]
----
In the preceding example, we could see how to create a new instance of the span.
@@ -44,13 +51,14 @@ If there is already a span in this thread, it becomes the parent of the new span
IMPORTANT: Always clean after you create a span.
IMPORTANT: If your span contains a name greater than 50 chars, that name is truncated to 50 chars.
Your names have to be explicit and concrete. Big names lead to latency issues and sometimes even exceptions.
Your names have to be explicit and concrete.
Big names lead to latency issues and sometimes even exceptions.
[[using-continuing-spans]]
=== Continuing Spans
Sometimes, you do not want to create a new span but you want to continue one. An example of such a
situation might be as follows:
Sometimes, you do not want to create a new span but you want to continue one.
An example of such a situation might be as follows:
* *AOP*: If there was already a span created before an aspect was reached, you might not want to create a new span.
@@ -58,7 +66,7 @@ To continue a span, you can store the span in one thread and pass it on to anoth
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=manual_span_continuation,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=manual_span_continuation,indent=0]
----
[[using-creating-spans-with-explicit-parent]]
@@ -71,17 +79,19 @@ You can put the span in scope and then call `Tracer.nextSpan()`, as shown in the
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=manual_span_joining,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=manual_span_joining,indent=0]
----
IMPORTANT: After creating such a span, you must finish it. Otherwise it is not reported (e.g. to Zipkin).
IMPORTANT: After creating such a span, you must finish it.
Otherwise it is not reported (e.g. to Zipkin).
You can also use the `Tracer.nextSpan(Span parentSpan)` version to provide the parent span explicitly.
[[using-naming-spans]]
== Naming Spans
Picking a span name is not a trivial task. A span name should depict an operation name.
Picking a span name is not a trivial task.
A span name should depict an operation name.
The name should be low cardinality, so it should not include identifiers.
Since there is a lot of instrumentation going on, some span names are artificial:
@@ -99,14 +109,14 @@ You can name the span explicitly by using the `@SpanName` annotation, as shown i
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=span_name_annotation,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=span_name_annotation,indent=0]
----
In this case, when processed in the following manner, the span is named `calculateTax`:
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=span_name_annotated_runnable_execution,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=span_name_annotated_runnable_execution,indent=0]
----
[[using-naming-spans-to-string]]
@@ -121,7 +131,7 @@ Running such code leads to creating a span named `calculateTax`, as shown in the
[source,java,indent=0]
----
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=span_name_to_string_runnable_execution,indent=0]
include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/brave/SpringCloudSleuthDocTests.java[tags=span_name_to_string_runnable_execution,indent=0]
----
[[using-annotations]]
@@ -129,11 +139,14 @@ include::{brave_path}/src/test/java/org/springframework/cloud/sleuth/documentati
There are a number of good reasons to manage spans with annotations, including:
* API-agnostic means to collaborate with a span. Use of annotations lets users add to a span with no library dependency on a span api.
* API-agnostic means to collaborate with a span.
Use of annotations lets users add to a span with no library dependency on a span api.
Doing so lets Sleuth change its core API to create less impact to user code.
* Reduced surface area for basic span operations. Without this feature, you must use the span api, which has lifecycle commands that could be used incorrectly.
* Reduced surface area for basic span operations.
Without this feature, you must use the span api, which has lifecycle commands that could be used incorrectly.
By only exposing scope, tag, and log functionality, you can collaborate without accidentally breaking span lifecycle.
* Collaboration with runtime generated code. With libraries such as Spring Data and Feign, the implementations of interfaces are generated at runtime.
* Collaboration with runtime generated code.
With libraries such as Spring Data and Feign, the implementations of interfaces are generated at runtime.
Consequently, span wrapping of objects was tedious.
Now you can provide annotations over interfaces and the arguments of those interfaces.
@@ -147,14 +160,14 @@ Now we can consider some examples of usage.
[source,java,indent=0]
----
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java[tags=annotated_method,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java[tags=annotated_method,indent=0]
----
Annotating the method without any parameter leads to creating a new span whose name equals the annotated method name.
[source,java,indent=0]
----
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java[tags=custom_name_on_annotated_method,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java[tags=custom_name_on_annotated_method,indent=0]
----
If you provide the value in the annotation (either directly or by setting the `name` parameter), the created span has the provided value as the name.
@@ -162,24 +175,24 @@ If you provide the value in the annotation (either directly or by setting the `n
[source,java,indent=0]
----
// method declaration
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java[tags=custom_name_and_tag_on_annotated_method,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java[tags=custom_name_and_tag_on_annotated_method,indent=0]
// and method execution
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java[tags=execution,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java[tags=execution,indent=0]
----
You can combine both the name and a tag. Let's focus on the latter.
You can combine both the name and a tag.
Let's focus on the latter.
In this case, the value of the annotated method's parameter runtime value becomes the value of the tag.
In our sample, the tag key is `testTag`, and the tag value is `test`.
[source,java,indent=0]
----
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java[tags=name_on_implementation,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java[tags=name_on_implementation,indent=0]
----
You can place the `@NewSpan` annotation on both the class and an interface.
If you override the interface's method and provide a different value for the `@NewSpan` annotation, the most
concrete one wins (in this case `customNameOnTestMethod3` is set).
If you override the interface's method and provide a different value for the `@NewSpan` annotation, the most concrete one wins (in this case `customNameOnTestMethod3` is set).
[[using-annotations-continuing-spans]]
=== Continuing Spans
@@ -189,10 +202,10 @@ If you want to add tags and annotations to an existing span, you can use the `@C
[source,java,indent=0]
----
// method declaration
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java[tags=continue_span,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java[tags=continue_span,indent=0]
// method execution
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java[tags=continue_span_execution,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SleuthSpanCreatorAspectTests.java[tags=continue_span_execution,indent=0]
----
(Note that, in contrast with the `@NewSpan` annotation ,you can also add logs with the `log` parameter.)
@@ -206,14 +219,16 @@ That way, the span gets continued and:
[[using-annotations-advanced-tag-setting]]
=== Advanced Tag Setting
There are 3 different ways to add tags to a span. All of them are controlled by the `SpanTag` annotation.
There are 3 different ways to add tags to a span.
All of them are controlled by the `SpanTag` annotation.
The precedence is as follows:
. Try with a bean of `TagValueResolver` type and a provided name.
. If the bean name has not been provided, try to evaluate an expression.
We search for a `TagValueExpressionResolver` bean.
The default implementation uses SPEL expression resolution.
**IMPORTANT** You can only reference properties from the SPEL expression. Method execution is not allowed due to security constraints.
**IMPORTANT** You can only reference properties from the SPEL expression.
Method execution is not allowed due to security constraints.
. If we do not find any expression to evaluate, return the `toString()` value of the parameter.
[[using-annotations-custom-extractor]]
@@ -226,14 +241,14 @@ Consider the following annotated method:
[source,java,indent=0]
----
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java[tags=resolver_bean,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java[tags=resolver_bean,indent=0]
----
Now further consider the following `TagValueResolver` bean implementation:
[source,java,indent=0]
----
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java[tags=custom_resolver,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java[tags=custom_resolver,indent=0]
----
The two preceding examples lead to setting a tag value equal to `Value from myCustomTagValueResolver`.
@@ -245,7 +260,7 @@ Consider the following annotated method:
[source,java,indent=0]
----
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java[tags=spel,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java[tags=spel,indent=0]
----
No custom implementation of a `TagValueExpressionResolver` leads to evaluation of the SPEL expression, and a tag with a value of `4 characters` is set on the span.
@@ -258,7 +273,7 @@ Consider the following annotated method:
[source,java,indent=0]
----
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/annotation/SpanTagAnnotationHandlerTests.java[tags=toString,indent=0]
include::{common_tests_path}/src/main/java/org/springframework/cloud/sleuth/instrument/annotation/SpanTagAnnotationHandlerTests.java[tags=toString,indent=0]
----
Running the preceding method with a value of `15` leads to setting a tag with a String value of `"15"`.
@@ -266,7 +281,6 @@ Running the preceding method with a value of `15` leads to setting a tag with a
[[using-whats-next]]
== What to Read Next
You should now understand how you can use {project-full-name} and some best practices that you
should follow. You can now go on to learn about specific
<<project-features#project-features, {project-full-name} features>>, or you could
skip ahead and read about the link:integrations[integrations available in {project-full-name}].
You should now understand how you can use {project-full-name} and some best practices that you should follow.
You can now go on to learn about specific
<<project-features#project-features, {project-full-name} features>>, or you could skip ahead and read about the link:integrations[integrations available in {project-full-name}].

188
mvnw vendored
View File

@@ -34,151 +34,158 @@
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -z "$MAVEN_SKIP_RC" ]; then
if [ -f /etc/mavenrc ] ; then
if [ -f /etc/mavenrc ]; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
if [ -f "$HOME/.mavenrc" ]; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
cygwin=false
darwin=false
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
#
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
# for the new JDKs provided by Oracle.
#
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
fi
case "$(uname)" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true ;;
Darwin*)
darwin=true
#
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
# for the new JDKs provided by Oracle.
#
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ]; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ]; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
#
# Oracle JDKs
#
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ]; then
#
# Oracle JDKs
#
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
#
# Apple JDKs
#
export JAVA_HOME=`/usr/libexec/java_home`
fi
;;
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
#
# Apple JDKs
#
export JAVA_HOME=$(/usr/libexec/java_home)
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
if [ -z "$JAVA_HOME" ]; then
if [ -r /etc/gentoo-release ]; then
JAVA_HOME=$(java-config --jre-home)
fi
fi
if [ -z "$M2_HOME" ] ; then
if [ -z "$M2_HOME" ]; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
while [ -h "$PRG" ]; do
ls=$(ls -ld "$PRG")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' >/dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
PRG="$(dirname "$PRG")/$link"
fi
done
saveddir=`pwd`
saveddir=$(pwd)
M2_HOME=`dirname "$PRG"`/..
M2_HOME=$(dirname "$PRG")/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
M2_HOME=$(cd "$M2_HOME" && pwd)
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
M2_HOME=$(cygpath --unix "$M2_HOME")
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
if $mingw; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
M2_HOME="$( (
cd "$M2_HOME"
pwd
))"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
JAVA_HOME="$( (
cd "$JAVA_HOME"
pwd
))"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
readLink=$(which readlink)
if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then
if $darwin; then
javaHome="$(dirname \"$javaExecutable\")"
javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
javaExecutable="$(readlink -f \"$javaExecutable\")"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
javaHome="$(dirname \"$javaExecutable\")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
if [ -z "$JAVACMD" ]; then
if [ -n "$JAVA_HOME" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
JAVACMD="$(which java)"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
if [ ! -x "$JAVACMD" ]; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
if [ -z "$JAVA_HOME" ]; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
@@ -187,11 +194,11 @@ CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
M2_HOME=$(cygpath --path --windows "$M2_HOME")
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
fi
# traverses directory structure from process work directory to filesystem root
@@ -199,12 +206,15 @@ fi
find_maven_basedir() {
local basedir=$(pwd)
local wdir=$(pwd)
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
while [ "$wdir" != '/' ]; do
if [ -d "$wdir"/.mvn ]; then
basedir=$wdir
break
fi
wdir=$(cd "$wdir/.."; pwd)
wdir=$(
cd "$wdir/.."
pwd
)
done
echo "${basedir}"
}
@@ -212,7 +222,7 @@ find_maven_basedir() {
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
echo "$(tr -s '\n' ' ' <"$1")"
fi
}
@@ -227,23 +237,23 @@ export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
echo "Running version check"
VERSION=$( sed '\!<parent!,\!</parent!d' `dirname $0`/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!' )
VERSION=$(sed '\!<parent!,\!</parent!d' $(dirname $0)/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!')
echo "The found version is [${VERSION}]"
if echo $VERSION | egrep -q 'M|RC'; then
echo Activating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
echo Activating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
else
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
fi
if echo $VERSION | egrep -q 'RELEASE'; then
echo Activating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
echo Activating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
else
echo Deactivating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
echo Deactivating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
fi
exec "$JAVACMD" \

11
pom.xml
View File

@@ -46,13 +46,14 @@
<modules>
<module>spring-cloud-sleuth-dependencies</module>
<module>spring-cloud-sleuth-core</module>
<module>spring-cloud-sleuth-api</module>
<module>spring-cloud-sleuth-instrumentation</module>
<module>spring-cloud-sleuth-brave</module>
<module>spring-cloud-sleuth-otel</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-starter-sleuth-otel</module>
<module>spring-cloud-sleuth-samples</module>
<module>docs</module>
</modules>
@@ -92,6 +93,7 @@
<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>
@@ -287,6 +289,11 @@
<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>

View File

@@ -1,7 +1,7 @@
#!/bin/bash
echo "Running JMH Benchmarks"
ROOT="$( pwd )"
ROOT="$(pwd)"
JMH_RESULT_FILE_PARENT="${ROOT}"
mkdir -p "${JMH_RESULT_FILE_PARENT}"
JMH_RESULT_FILE="${JMH_RESULT_FILE_PARENT}/jmh-result.csv"

View File

@@ -19,38 +19,72 @@
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-api</artifactId>
<packaging>jar</packaging>
<name>Spring Cloud Sleuth API</name>
<description>Spring Cloud Sleuth API</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>spring-cloud-starter-sleuth-otel</artifactId>
<name>Spring Cloud Starter Sleuth with OpenTelemetry</name>
<description>Spring Cloud Starter Sleuth with OpenTelemetry</description>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-auto-annotations</artifactId>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-trace-propagators</artifactId>
<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

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
import java.io.Closeable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
import java.util.Map;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
import java.io.Closeable;
import java.util.concurrent.Callable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
import org.springframework.lang.Nullable;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
/**
* Represents the "current span" until {@link ScopedSpan#end()} ()} is called.

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
import org.springframework.cloud.sleuth.api.propagation.Propagator;
import org.springframework.cloud.sleuth.propagation.Propagator;
/**
*

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
/**
* Allows to customize the current span in scope.

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
import org.springframework.lang.Nullable;

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api;
package org.springframework.cloud.sleuth;
import java.io.Closeable;
import org.springframework.cloud.sleuth.api.propagation.Propagator;
import org.springframework.cloud.sleuth.propagation.Propagator;
import org.springframework.lang.Nullable;
/**

View File

@@ -18,7 +18,7 @@ package org.springframework.cloud.sleuth.annotation;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
/**
* Parses data for a span created via a {@link NewSpan} annotation.

View File

@@ -22,7 +22,7 @@ package org.springframework.cloud.sleuth.annotation;
* @author Marcin Grzejszczak
* @since 1.2.0
*/
class NoOpTagValueResolver implements TagValueResolver {
public class NoOpTagValueResolver implements TagValueResolver {
@Override
public String resolve(Object parameter) {

View File

@@ -24,8 +24,16 @@ import org.aopalliance.intercept.MethodInvocation;
* @author Marcin Grzejszczak
* @since 2.1.0
*/
interface SleuthMethodInvocationProcessor {
public interface SleuthMethodInvocationProcessor {
/**
* Executes a given Sleuth annotated method.
* @param invocation method invocation
* @param newSpan annotation
* @param continueSpan annotation
* @return executed method result
* @throws Throwable exception upon running a method
*/
Object process(MethodInvocation invocation, NewSpan newSpan, ContinueSpan continueSpan) throws Throwable;
}

View File

@@ -14,21 +14,24 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.instrument.web;
package org.springframework.cloud.sleuth.autoconfig;
import java.util.Optional;
import java.util.regex.Pattern;
/**
* Provides a URL {@link Pattern} for spans that should be not sampled. The default
* implementation of {@link SkipPatternProvider} will harvest all
* {@link SingleSkipPattern}s and combine them in a single pattern
* implementation will harvest all {@link SingleSkipPattern}s and combine them in a single
* pattern
*
* @author Marcin Grzejszczak
* @since 2.1.0
*/
interface SingleSkipPattern {
public interface SingleSkipPattern {
/**
* @return optional pattern to skip
*/
Optional<Pattern> skipPattern();
}

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.exporter;
package org.springframework.cloud.sleuth.exporter;
import java.util.Collection;
import java.util.Map;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
import org.springframework.lang.Nullable;
/**

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.exporter;
package org.springframework.cloud.sleuth.exporter;
/**
* An interface that allows to filter whether a given reported span should be exported or

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.autoconfig;
package org.springframework.cloud.sleuth.exporter;
import java.util.ArrayList;
import java.util.List;
@@ -26,8 +26,6 @@ import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.sleuth.api.exporter.FinishedSpan;
import org.springframework.cloud.sleuth.api.exporter.SpanFilter;
import org.springframework.util.StringUtils;
/**
@@ -36,16 +34,20 @@ import org.springframework.util.StringUtils;
* @author Marcin Grzejszczak
* @since 3.0.0
*/
class SpanIgnoringSpanFilter implements SpanFilter {
public class SpanIgnoringSpanFilter implements SpanFilter {
private static final Log log = LogFactory.getLog(SpanIgnoringSpanFilter.class);
private final SleuthSpanFilterProperties sleuthSpanFilterProperties;
private final List<String> spanNamePatternsToSkip;
private final List<String> additionalSpanNamePatternsToIgnore;
static final Map<String, Pattern> cache = new ConcurrentHashMap<>();
SpanIgnoringSpanFilter(SleuthSpanFilterProperties sleuthSpanFilterProperties) {
this.sleuthSpanFilterProperties = sleuthSpanFilterProperties;
public SpanIgnoringSpanFilter(List<String> spanNamePatternsToSkip,
List<String> additionalSpanNamePatternsToIgnore) {
this.spanNamePatternsToSkip = spanNamePatternsToSkip;
this.additionalSpanNamePatternsToIgnore = additionalSpanNamePatternsToIgnore;
}
private List<Pattern> spanNamesToIgnore() {
@@ -54,8 +56,8 @@ class SpanIgnoringSpanFilter implements SpanFilter {
}
private List<String> spanNames() {
List<String> spanNamesToIgnore = new ArrayList<>(this.sleuthSpanFilterProperties.getSpanNamePatternsToSkip());
spanNamesToIgnore.addAll(this.sleuthSpanFilterProperties.getAdditionalSpanNamePatternsToIgnore());
List<String> spanNamesToIgnore = new ArrayList<>(this.spanNamePatternsToSkip);
spanNamesToIgnore.addAll(this.additionalSpanNamePatternsToIgnore);
return spanNamesToIgnore;
}

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.api.TraceContext;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.TraceContext;
import org.springframework.lang.Nullable;
/**

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
/**
* This API is taken from OpenZipkin Brave.

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
import org.springframework.lang.Nullable;
/**

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.lang.Nullable;

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.SpanCustomizer;
import org.springframework.cloud.sleuth.api.TraceContext;
import org.springframework.cloud.sleuth.SpanCustomizer;
import org.springframework.cloud.sleuth.TraceContext;
/**
* This API is taken from OpenZipkin Brave.

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.lang.Nullable;

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.SpanCustomizer;
import org.springframework.cloud.sleuth.api.TraceContext;
import org.springframework.cloud.sleuth.SpanCustomizer;
import org.springframework.cloud.sleuth.TraceContext;
/**
* This API is taken from OpenZipkin Brave.

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
/**
* This API is taken from OpenZipkin Brave.

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
/**
* This API is taken from OpenZipkin Brave.

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
import org.springframework.lang.Nullable;
/**

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import java.util.Collection;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
/**
* This API is taken from OpenZipkin Brave.

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.http;
package org.springframework.cloud.sleuth.http;
import java.util.Collection;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.Span;
import org.springframework.lang.Nullable;
/**

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.api.propagation;
package org.springframework.cloud.sleuth.propagation;
import java.util.List;
import org.springframework.cloud.sleuth.api.Span;
import org.springframework.cloud.sleuth.api.TraceContext;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.TraceContext;
import org.springframework.lang.Nullable;
/**

View File

@@ -0,0 +1,45 @@
/*
* 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;
import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.core.importer.Location;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
@AnalyzeClasses(packagesOf = ArchitectureTests.class, importOptions = ArchitectureTests.ProductionCode.class)
public class ArchitectureTests {
@ArchTest
public static final ArchRule should_not_contain_any_spring_configuration_reference_in_module = noClasses().should()
.dependOnClassesThat().resideInAnyPackage("..org.springframework.boot.context.properties..",
"..org.springframework.context.annotation..");
static class ProductionCode implements ImportOption {
@Override
public boolean includes(Location location) {
return Predefined.DO_NOT_INCLUDE_TESTS.includes(location)
&& Predefined.DO_NOT_INCLUDE_JARS.includes(location);
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.exporter;
import java.util.Collections;
import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import static org.assertj.core.api.BDDAssertions.then;
class SpanIgnoringSpanFilterTests {
private FinishedSpan namedSpan() {
FinishedSpan span = BDDMockito.mock(FinishedSpan.class);
BDDMockito.given(span.getName()).willReturn("someName");
return span;
}
@Test
void should_not_handle_span_when_present_in_main_list_of_spans_to_skip() {
SpanIgnoringSpanFilter handler = new SpanIgnoringSpanFilter(Collections.singletonList("someName"),
Collections.emptyList());
then(handler.isExportable(namedSpan())).isFalse();
}
@Test
void should_not_handle_span_when_present_in_additional_list_of_spans_to_skip() {
SpanIgnoringSpanFilter handler = new SpanIgnoringSpanFilter(Collections.emptyList(),
Collections.singletonList("someName"));
then(handler.isExportable(namedSpan())).isFalse();
}
@Test
void should_use_cached_entry_for_same_patterns() {
export(handler("someOtherName"));
export(handler("someOtherName"));
export(handler("someOtherName"));
then(SpanIgnoringSpanFilter.cache).containsKey("someOtherName");
export(handler("a"));
export(handler("b"));
export(handler("c"));
then(SpanIgnoringSpanFilter.cache).containsKey("someOtherName").containsKey("a").containsKey("b")
.containsKey("c");
}
private void export(SpanIgnoringSpanFilter handler) {
handler.isExportable(namedSpan());
}
private SpanIgnoringSpanFilter handler(String name) {
return new SpanIgnoringSpanFilter(Collections.emptyList(), Collections.singletonList(name));
}
}

View File

@@ -0,0 +1,3 @@
# Auto Configuration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.sleuth.autoconfig.TraceNoOpAutoConfiguration

View File

@@ -0,0 +1,526 @@
<?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.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-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>
<!-- Otel -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-common</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-tracing</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-api</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-auto-annotations</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-logging</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-trace-propagators</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-opentracing-shim</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.opentelemetry</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-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>
<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>

View File

@@ -14,17 +14,24 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.annotation;
package org.springframework.cloud.sleuth.autoconfig;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.sleuth.api.Tracer;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.cloud.sleuth.annotation.NewSpan;
import org.springframework.cloud.sleuth.annotation.NewSpanParser;
import org.springframework.cloud.sleuth.annotation.NoOpTagValueResolver;
import org.springframework.cloud.sleuth.annotation.SleuthMethodInvocationProcessor;
import org.springframework.cloud.sleuth.annotation.TagValueExpressionResolver;
import org.springframework.cloud.sleuth.annotation.TagValueResolver;
import org.springframework.cloud.sleuth.instrument.annotation.DefaultSpanCreator;
import org.springframework.cloud.sleuth.instrument.annotation.NonReactorSleuthMethodInvocationProcessor;
import org.springframework.cloud.sleuth.instrument.annotation.ReactorSleuthMethodInvocationProcessor;
import org.springframework.cloud.sleuth.instrument.annotation.SleuthAdvisorConfig;
import org.springframework.cloud.sleuth.instrument.annotation.SpelTagValueExpressionResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
@@ -41,10 +48,8 @@ import org.springframework.context.annotation.Role;
*/
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConditionalOnBean(Tracer.class)
@ConditionalOnProperty(name = "spring.sleuth.annotation.enabled", matchIfMissing = true)
@AutoConfigureAfter(TraceAutoConfiguration.class)
class SleuthAnnotationAutoConfiguration {
@ConditionalOnProperty(name = { "spring.sleuth.enabled", "spring.sleuth.annotation.enabled" }, matchIfMissing = true)
public class SleuthAnnotationConfiguration {
@Bean
@ConditionalOnMissingBean

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.opentracing;
package org.springframework.cloud.sleuth.autoconfig;
import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@@ -29,7 +29,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @since 1.0.11
*/
@ConfigurationProperties("spring.sleuth.span-filter")
class SleuthSpanFilterProperties {
public class SleuthSpanFilterProperties {
/**
* Will turn on the default Sleuth handler mechanism. Might ignore exporting of

View File

@@ -0,0 +1,65 @@
/*
* 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.autoconfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Sets tracer related properties.
*
* @author Marcin Grzejszczak
* @since 3.0
*/
@ConfigurationProperties("spring.sleuth.tracer")
public class SleuthTracerProperties {
/**
* Set which tracer implementation should be picked.
*/
private TracerMode mode = TracerMode.AUTO;
public TracerMode getMode() {
return this.mode;
}
public void setMode(TracerMode mode) {
this.mode = mode;
}
/**
* Tracer implementation modes.
*/
public enum TracerMode {
/**
* Automatically picks the tracer implementation.
*/
AUTO,
/**
* Picks the OpenZipkin Brave tracer implementation.
*/
BRAVE,
/**
* Picks the OpenTelemetry tracer implementation.
*/
OTEL
}
}

View File

@@ -14,33 +14,44 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.propagation;
package org.springframework.cloud.sleuth.autoconfig;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.sleuth.autoconfig.SleuthBaggageProperties;
import org.springframework.cloud.sleuth.SpanNamer;
import org.springframework.cloud.sleuth.exporter.SpanFilter;
import org.springframework.cloud.sleuth.exporter.SpanIgnoringSpanFilter;
import org.springframework.cloud.sleuth.internal.DefaultSpanNamer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} to enable propagation factories.
* Auto-configuration} to enable tracing via Spring Cloud Sleuth.
*
* @author Spencer Gibb
* @author Marcin Grzejszczak
* @since 3.0.0
* @author Tim Ysewyn
* @since 2.0.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
@EnableConfigurationProperties(SleuthPropagationProperties.class)
public class TraceBravePropagationAutoConfiguration {
@EnableConfigurationProperties({ SleuthSpanFilterProperties.class, SleuthBaggageProperties.class,
SleuthTracerProperties.class })
public class TraceConfiguration {
@Bean
@ConditionalOnMissingBean
PropagationFactorySupplier compositePropagationFactorySupplier(BeanFactory beanFactory,
SleuthBaggageProperties baggageProperties, SleuthPropagationProperties properties) {
return new CompositePropagationFactorySupplier(beanFactory, baggageProperties, properties);
SpanNamer defaultSpanNamer() {
return new DefaultSpanNamer();
}
@Bean
@ConditionalOnProperty(value = "spring.sleuth.span-filter.enabled", matchIfMissing = true)
SpanFilter spanIgnoringSpanExporter(SleuthSpanFilterProperties sleuthSpanFilterProperties) {
return new SpanIgnoringSpanFilter(sleuthSpanFilterProperties.getSpanNamePatternsToSkip(),
sleuthSpanFilterProperties.getAdditionalSpanNamePatternsToIgnore());
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.autoconfig;
package org.springframework.cloud.sleuth.autoconfig.brave;
import java.util.Collections;
import java.util.List;
@@ -30,18 +30,18 @@ import brave.propagation.Propagation;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.sampler.Sampler;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.sleuth.SpanNamer;
import org.springframework.cloud.sleuth.api.exporter.SpanFilter;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.cloud.sleuth.autoconfig.SleuthAnnotationConfiguration;
import org.springframework.cloud.sleuth.autoconfig.SleuthBaggageProperties;
import org.springframework.cloud.sleuth.autoconfig.SleuthSpanFilterProperties;
import org.springframework.cloud.sleuth.autoconfig.SleuthTracerProperties;
import org.springframework.cloud.sleuth.autoconfig.TraceConfiguration;
import org.springframework.cloud.sleuth.autoconfig.brave.instrument.web.BraveHttpConfiguration;
import org.springframework.cloud.sleuth.brave.LocalServiceName;
import org.springframework.cloud.sleuth.brave.bridge.BraveBaggageManager;
import org.springframework.cloud.sleuth.brave.propagation.TraceBravePropagationAutoConfiguration;
import org.springframework.cloud.sleuth.brave.sampler.SamplerAutoConfiguration;
import org.springframework.cloud.sleuth.internal.DefaultSpanNamer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -59,14 +59,15 @@ import org.springframework.util.StringUtils;
* @since 3.0.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnBraveEnabled
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
@EnableConfigurationProperties(SleuthProperties.class)
@Import({ TraceBaggageConfiguration.class, SamplerAutoConfiguration.class })
@AutoConfigureBefore(TraceAutoConfiguration.class)
@AutoConfigureAfter(TraceBravePropagationAutoConfiguration.class)
// public allows @AutoConfigureAfter(TraceAutoConfiguration)
// for components needing Tracing
public class TraceBraveAutoConfiguration {
@ConditionalOnMissingBean(org.springframework.cloud.sleuth.Tracer.class)
@ConditionalOnClass({ Tracer.class, SleuthProperties.class })
@EnableConfigurationProperties({ SleuthProperties.class, SleuthSpanFilterProperties.class,
SleuthBaggageProperties.class, SleuthTracerProperties.class, SleuthBaggageProperties.class })
@Import({ BraveBridgeConfiguration.class, BraveBaggageConfiguration.class, BraveSamplerConfiguration.class,
BraveHttpConfiguration.class, TraceConfiguration.class, SleuthAnnotationConfiguration.class })
public class BraveAutoConfiguration {
/**
* Tracing bean name. Name of the bean matters for some instrumentations.
@@ -81,13 +82,7 @@ public class TraceBraveAutoConfiguration {
/**
* Default value used for service name if none provided.
*/
public static final String DEFAULT_SERVICE_NAME = "default";
@Bean
@ConditionalOnMissingBean
BraveBaggageManager braveBaggageManager() {
return new BraveBaggageManager();
}
private static final String DEFAULT_SERVICE_NAME = "default";
@Bean(name = TRACING_BEAN_NAME)
@ConditionalOnMissingBean
@@ -158,9 +153,4 @@ public class TraceBraveAutoConfiguration {
return CurrentSpanCustomizer.create(tracing);
}
@Bean
SpanHandler compositeSpanHandler(@Nullable List<SpanFilter> exporters) {
return new CompositeSpanHandler(exporters);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.autoconfig;
package org.springframework.cloud.sleuth.autoconfig.brave;
import java.util.ArrayList;
import java.util.List;
@@ -47,7 +47,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.sleuth.autoconfig.SleuthBaggageProperties;
import org.springframework.cloud.sleuth.brave.propagation.PropagationFactorySupplier;
import org.springframework.context.annotation.Bean;
@@ -64,10 +63,9 @@ import org.springframework.lang.Nullable;
* @since 2.0.0
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SleuthBaggageProperties.class)
class TraceBaggageConfiguration {
class BraveBaggageConfiguration {
static final Log logger = LogFactory.getLog(TraceBaggageConfiguration.class);
static final Log logger = LogFactory.getLog(BraveBaggageConfiguration.class);
static final String LOCAL_KEYS = "spring.sleuth.local-keys";
static final String BAGGAGE_KEYS = "spring.sleuth.baggage-keys";
@@ -218,7 +216,6 @@ class TraceBaggageConfiguration {
*/
@Configuration(proxyBeanMethods = false)
@Conditional(BaggageTagSpanHandlerCondition.class)
@EnableConfigurationProperties(SleuthBaggageProperties.class)
static class BaggageTagSpanHandlerConfiguration {
@Bean(WHITELISTED_KEYS)

View File

@@ -0,0 +1,82 @@
/*
* 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.autoconfig.brave;
import java.util.List;
import brave.Tracing;
import brave.handler.SpanHandler;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.sleuth.SpanCustomizer;
import org.springframework.cloud.sleuth.autoconfig.SleuthBaggageProperties;
import org.springframework.cloud.sleuth.brave.bridge.BraveBaggageManager;
import org.springframework.cloud.sleuth.brave.bridge.BraveCurrentTraceContext;
import org.springframework.cloud.sleuth.brave.bridge.BravePropagator;
import org.springframework.cloud.sleuth.brave.bridge.BraveSpanCustomizer;
import org.springframework.cloud.sleuth.brave.bridge.BraveTracer;
import org.springframework.cloud.sleuth.brave.bridge.CompositePropagationFactorySupplier;
import org.springframework.cloud.sleuth.brave.bridge.CompositeSpanHandler;
import org.springframework.cloud.sleuth.brave.propagation.PropagationFactorySupplier;
import org.springframework.cloud.sleuth.exporter.SpanFilter;
import org.springframework.cloud.sleuth.propagation.Propagator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SleuthPropagationProperties.class)
class BraveBridgeConfiguration {
@Bean
org.springframework.cloud.sleuth.Tracer braveTracer(brave.Tracer tracer) {
return new BraveTracer(tracer, new BraveBaggageManager());
}
@Bean
org.springframework.cloud.sleuth.CurrentTraceContext braveCurrentTraceContext(
brave.propagation.CurrentTraceContext currentTraceContext) {
return new BraveCurrentTraceContext(currentTraceContext);
}
@Bean
SpanCustomizer braveSpanCustomizer(brave.SpanCustomizer spanCustomizer) {
return new BraveSpanCustomizer(spanCustomizer);
}
@Bean
Propagator bravePropagator(Tracing tracing) {
return new BravePropagator(tracing);
}
@Bean
@ConditionalOnMissingBean
PropagationFactorySupplier compositePropagationFactorySupplier(BeanFactory beanFactory,
SleuthBaggageProperties baggageProperties, SleuthPropagationProperties properties) {
return new CompositePropagationFactorySupplier(beanFactory, baggageProperties.getLocalFields(),
properties.getType());
}
// Name is important for sampling conditions
@Bean(name = "traceCompositeSpanHandler")
SpanHandler compositeSpanHandler(@Nullable List<SpanFilter> exporters) {
return new CompositeSpanHandler(exporters);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.sampler;
package org.springframework.cloud.sleuth.autoconfig.brave;
import brave.sampler.CountingSampler;
import brave.sampler.Sampler;
@@ -24,6 +24,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.sleuth.brave.sampler.ProbabilityBasedSampler;
import org.springframework.cloud.sleuth.brave.sampler.RateLimitingSampler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@@ -37,10 +39,7 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SamplerProperties.class)
// This is not auto-configuration, but it was in the past. Leaving the name as
// SamplerAutoConfiguration because those not using Zipkin formerly had to
// import this directly. A less precise name is better than rev-locking code.
public class SamplerAutoConfiguration {
class BraveSamplerConfiguration {
@Bean
@ConditionalOnMissingBean
@@ -81,9 +80,9 @@ public class SamplerAutoConfiguration {
// TODO: Rewrite: refresh should replace the sampler, not change its state
// internally
if (config.getProbability() != null) {
return new ProbabilityBasedSampler(config);
return new ProbabilityBasedSampler(config::getProbability);
}
return new RateLimitingSampler(config);
return new RateLimitingSampler(config::getRate);
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.autoconfig.brave;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Conditional;
/**
* Conditional on Brave tracer.
*
* @author Marcin Grzejszczak
* @since 3.0.0
*/
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(AnyTracerModePropertySetCondition.class)
public @interface ConditionalOnBraveEnabled {
}
final class AnyTracerModePropertySetCondition extends AnyNestedCondition {
private AnyTracerModePropertySetCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnProperty(value = "spring.sleuth.tracer.mode", havingValue = "AUTO", matchIfMissing = true)
static class OnAutoTracerMode {
}
@ConditionalOnProperty(value = "spring.sleuth.tracer.mode", havingValue = "BRAVE")
static class OnConcreteTracerMode {
}
}

View File

@@ -14,14 +14,21 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.sampler;
package org.springframework.cloud.sleuth.autoconfig.brave;
import brave.TracingCustomizer;
import brave.handler.SpanHandler;
import brave.sampler.Sampler;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.ConfigurationCondition;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* Sleuth 1.x optimized for log-correlation only. Unless "spring-cloud-sleuth-zipkin" was
@@ -30,14 +37,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
*
* <p>
* "spring-cloud-sleuth-zipkin" obviated the {@link Sampler#NEVER_SAMPLE} default by
* importing {@link SamplerAutoConfiguration}. Nothing else did, so sampling properties
* were effectively ignored unless "spring-cloud-sleuth-zipkin" was in use, or something
* else similarly imported {@link SamplerAutoConfiguration}.
* importing {@link SamplerConfiguration}. Nothing else did, so sampling properties were
* effectively ignored unless "spring-cloud-sleuth-zipkin" was in use, or something else
* similarly imported {@link SamplerConfiguration}.
*
* <p>
* During a review of Wavefront integration, it was considered not correct to have other
* code import {@link SamplerAutoConfiguration}. To avoid that, retain the old behaviour
* about log only nodes, and also not pin configuration to Zipkin involves a more complex
* code import {@link SamplerConfiguration}. To avoid that, retain the old behaviour about
* log only nodes, and also not pin configuration to Zipkin involves a more complex
* condition.
*
* <p>
@@ -55,7 +62,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
* <p>
* An integrated test that shows {@link Sampler#NEVER_SAMPLE} is default on fail exists in
* {@code TraceAutoConfigurationTests} intentionally, as users now needn't import
* {@link SamplerAutoConfiguration} directly.
* {@link SamplerConfiguration} directly.
*/
final class SamplerCondition extends AnyNestedCondition {
@@ -69,7 +76,7 @@ final class SamplerCondition extends AnyNestedCondition {
}
@ConditionalOnBean(SpanHandler.class)
@Conditional(SpanHandlerOtherThanCompositePresent.class)
static final class SpanHandlerAvailable {
}
@@ -79,4 +86,31 @@ final class SamplerCondition extends AnyNestedCondition {
}
static class SpanHandlerOtherThanCompositePresent extends SpringBootCondition implements ConfigurationCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
String[] spanHandlers = ((ListableBeanFactory) context.getBeanFactory())
.getBeanNamesForType(SpanHandler.class);
boolean moreThanSingleHandler = spanHandlers.length > 1;
if (moreThanSingleHandler) {
return ConditionOutcome.match("More than one handler present");
}
if (spanHandlers.length == 0) {
return ConditionOutcome.noMatch("No span handler is available");
}
// bean name is set in Brave bridge configuration
boolean singleCompositeSpanHandler = spanHandlers.length == 1
&& spanHandlers[0].equals("traceCompositeSpanHandler");
return singleCompositeSpanHandler ? ConditionOutcome.noMatch("Composite handler found")
: ConditionOutcome.match("Composite handler not found");
}
@Override
public ConfigurationPhase getConfigurationPhase() {
return ConfigurationPhase.REGISTER_BEAN;
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.sampler;
package org.springframework.cloud.sleuth.autoconfig.brave;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -26,7 +26,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @since 1.0.0
*/
@ConfigurationProperties("spring.sleuth.sampler")
class SamplerProperties {
public class SamplerProperties {
/**
* Probability of requests that should be sampled. E.g. 1.0 - 100% requests should be

View File

@@ -14,12 +14,13 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.propagation;
package org.springframework.cloud.sleuth.autoconfig.brave;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.sleuth.brave.propagation.PropagationType;
/**
* Sleuth settings for OpenTelemetry.
@@ -43,28 +44,4 @@ public class SleuthPropagationProperties {
this.type = type;
}
public enum PropagationType {
/**
* AWS propagation type.
*/
AWS,
/**
* B3 propagation type.
*/
B3,
/**
* W3C propagation type.
*/
W3C,
/**
* Custom propagation type.
*/
CUSTOM
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.autoconfig;
package org.springframework.cloud.sleuth.autoconfig.brave;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -25,7 +25,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @since 1.0.11
*/
@ConfigurationProperties("spring.sleuth")
class SleuthProperties {
public class SleuthProperties {
private boolean enabled = true;

View File

@@ -14,11 +14,12 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.instrument.grpc;
package org.springframework.cloud.sleuth.autoconfig.brave.instrument.grpc;
import java.util.List;
import java.util.Optional;
import brave.Tracing;
import brave.grpc.GrpcTracing;
import brave.rpc.RpcTracing;
import io.grpc.ServerInterceptor;
@@ -29,7 +30,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.sleuth.brave.instrument.rpc.TraceRpcAutoConfiguration;
import org.springframework.cloud.sleuth.autoconfig.brave.instrument.rpc.BraveRpcAutoConfiguration;
import org.springframework.cloud.sleuth.brave.instrument.grpc.GrpcManagedChannelBuilderCustomizer;
import org.springframework.cloud.sleuth.brave.instrument.grpc.SpringAwareManagedChannelBuilder;
import org.springframework.cloud.sleuth.brave.instrument.grpc.TracingManagedChannelBuilderCustomizer;
import org.springframework.context.annotation.Bean;
/**
@@ -43,12 +47,12 @@ import org.springframework.context.annotation.Bean;
*/
@ConditionalOnClass({ GrpcTracing.class, GRpcGlobalInterceptor.class })
@ConditionalOnProperty(value = "spring.sleuth.grpc.enabled", matchIfMissing = true)
@ConditionalOnBean(RpcTracing.class)
@AutoConfigureAfter(TraceRpcAutoConfiguration.class)
class TraceGrpcAutoConfiguration {
@ConditionalOnBean({ Tracing.class, RpcTracing.class })
@AutoConfigureAfter(BraveRpcAutoConfiguration.class)
public class BraveGrpcAutoConfiguration {
@Bean
public GrpcTracing grpcTracing(RpcTracing rpcTracing) {
GrpcTracing grpcTracing(RpcTracing rpcTracing) {
return GrpcTracing.create(rpcTracing);
}
@@ -62,7 +66,7 @@ class TraceGrpcAutoConfiguration {
// This is wrapper around gRPC's managed channel builder that is spring-aware
@Bean
@ConditionalOnMissingBean(SpringAwareManagedChannelBuilder.class)
public SpringAwareManagedChannelBuilder managedChannelBuilder(
SpringAwareManagedChannelBuilder managedChannelBuilder(
Optional<List<GrpcManagedChannelBuilderCustomizer>> customizers) {
return new SpringAwareManagedChannelBuilder(customizers);
}

View File

@@ -14,9 +14,10 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.instrument.messaging;
package org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging;
import brave.Tracing;
import brave.kafka.clients.KafkaTracing;
import brave.kafka.streams.KafkaStreamsTracing;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -25,12 +26,11 @@ import org.apache.kafka.streams.KafkaStreams;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.cloud.sleuth.brave.instrument.messaging.ConditionalOnMessagingEnabled;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.config.StreamsBuilderFactoryBean;
@@ -42,14 +42,13 @@ import org.springframework.kafka.config.StreamsBuilderFactoryBean;
* @author Tim te Beek
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnMessagingEnabled
@ConditionalOnBean(Tracing.class)
@AutoConfigureAfter({ TraceAutoConfiguration.class })
@OnMessagingEnabled
@ConditionalOnProperty(value = "spring.sleuth.messaging.kafka.streams.enabled", matchIfMissing = true)
@ConditionalOnClass(KafkaStreams.class)
class SleuthKafkaStreamsConfiguration {
@ConditionalOnClass({ KafkaStreams.class, KafkaTracing.class })
class BraveKafkaStreamsAutoConfiguration {
protected SleuthKafkaStreamsConfiguration() {
protected BraveKafkaStreamsAutoConfiguration() {
}
/**

View File

@@ -0,0 +1,179 @@
/*
* 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.autoconfig.brave.instrument.messaging;
import java.util.List;
import brave.Tracer;
import brave.Tracing;
import brave.jms.JmsTracing;
import brave.kafka.clients.KafkaTracing;
import brave.messaging.MessagingRequest;
import brave.messaging.MessagingTracing;
import brave.messaging.MessagingTracingCustomizer;
import brave.sampler.SamplerFunction;
import brave.spring.rabbit.SpringRabbitTracing;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.sleuth.brave.instrument.messaging.ConditionalOnMessagingEnabled;
import org.springframework.cloud.sleuth.brave.instrument.messaging.ConsumerSampler;
import org.springframework.cloud.sleuth.brave.instrument.messaging.KafkaFactoryBeanPostProcessor;
import org.springframework.cloud.sleuth.brave.instrument.messaging.ProducerSampler;
import org.springframework.cloud.sleuth.brave.instrument.messaging.SleuthKafkaAspect;
import org.springframework.cloud.sleuth.brave.instrument.messaging.SleuthRabbitBeanPostProcessor;
import org.springframework.cloud.sleuth.brave.instrument.messaging.TracingConnectionFactoryBeanPostProcessor;
import org.springframework.cloud.sleuth.brave.instrument.messaging.TracingJmsBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.jms.annotation.JmsListenerConfigurer;
import org.springframework.jms.config.JmsListenerEndpointRegistry;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.lang.Nullable;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} that registers a tracing instrumentation of messaging components.
*
* @author Marcin Grzejszczak
* @since 2.0.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(MessagingTracing.class)
@ConditionalOnMessagingEnabled
@ConditionalOnBean(Tracing.class)
@EnableConfigurationProperties(SleuthMessagingProperties.class)
public class BraveMessagingAutoConfiguration {
@Bean
@ConditionalOnMissingBean
// NOTE: stable bean name as might be used outside sleuth
MessagingTracing messagingTracing(Tracing tracing,
@Nullable @ProducerSampler SamplerFunction<MessagingRequest> producerSampler,
@Nullable @ConsumerSampler SamplerFunction<MessagingRequest> consumerSampler,
@Nullable List<MessagingTracingCustomizer> messagingTracingCustomizers) {
MessagingTracing.Builder builder = MessagingTracing.newBuilder(tracing);
if (producerSampler != null) {
builder.producerSampler(producerSampler);
}
if (consumerSampler != null) {
builder.consumerSampler(consumerSampler);
}
if (messagingTracingCustomizers != null) {
for (MessagingTracingCustomizer customizer : messagingTracingCustomizers) {
customizer.customize(builder);
}
}
return builder.build();
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.messaging.rabbit.enabled", matchIfMissing = true)
@ConditionalOnClass(RabbitTemplate.class)
protected static class SleuthRabbitConfiguration {
@Bean
// for tests
@ConditionalOnMissingBean
static SleuthRabbitBeanPostProcessor sleuthRabbitBeanPostProcessor(BeanFactory beanFactory) {
return new SleuthRabbitBeanPostProcessor(beanFactory);
}
@Bean
@ConditionalOnMissingBean
SpringRabbitTracing springRabbitTracing(MessagingTracing messagingTracing,
SleuthMessagingProperties properties) {
return SpringRabbitTracing.newBuilder(messagingTracing)
.remoteServiceName(properties.getMessaging().getRabbit().getRemoteServiceName()).build();
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.messaging.kafka.enabled", matchIfMissing = true)
@ConditionalOnClass(ProducerFactory.class)
protected static class SleuthKafkaConfiguration {
@Bean
@ConditionalOnMissingBean
KafkaTracing kafkaTracing(MessagingTracing messagingTracing, SleuthMessagingProperties properties) {
return KafkaTracing.newBuilder(messagingTracing)
.remoteServiceName(properties.getMessaging().getKafka().getRemoteServiceName()).build();
}
@Bean
// for tests
@ConditionalOnMissingBean
SleuthKafkaAspect sleuthKafkaAspect(KafkaTracing kafkaTracing, Tracer tracer) {
return new SleuthKafkaAspect(kafkaTracing, tracer);
}
@Bean
KafkaFactoryBeanPostProcessor kafkaFactoryBeanPostProcessor(BeanFactory beanFactory) {
return new KafkaFactoryBeanPostProcessor(beanFactory);
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.messaging.jms.enabled", matchIfMissing = true)
@ConditionalOnClass(JmsListenerConfigurer.class)
@ConditionalOnBean(JmsListenerEndpointRegistry.class)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
protected static class SleuthJmsConfiguration {
@Bean
@ConditionalOnMissingBean
JmsTracing jmsTracing(MessagingTracing messagingTracing, SleuthMessagingProperties properties) {
return JmsTracing.newBuilder(messagingTracing)
.remoteServiceName(properties.getMessaging().getJms().getRemoteServiceName()).build();
}
@Bean
// for tests
@ConditionalOnMissingBean
TracingConnectionFactoryBeanPostProcessor tracingConnectionFactoryBeanPostProcessor(BeanFactory beanFactory) {
return new TracingConnectionFactoryBeanPostProcessor(beanFactory);
}
@Bean
JmsListenerConfigurer configureTracing(BeanFactory beanFactory, JmsListenerEndpointRegistry defaultRegistry) {
return registrar -> {
TracingJmsBeanPostProcessor processor = beanFactory.getBean(TracingJmsBeanPostProcessor.class);
JmsListenerEndpointRegistry registry = registrar.getEndpointRegistry();
registrar.setEndpointRegistry((JmsListenerEndpointRegistry) processor
.postProcessAfterInitialization(registry == null ? defaultRegistry : registry, ""));
};
}
// Setup the tracing endpoint registry.
@Bean
TracingJmsBeanPostProcessor tracingJmsBeanPostProcessor(BeanFactory beanFactory) {
return new TracingJmsBeanPostProcessor(beanFactory);
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.instrument.messaging;
package org.springframework.cloud.sleuth.autoconfig.brave.instrument.messaging;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -25,7 +25,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @since 2.0.0
*/
@ConfigurationProperties("spring.sleuth.messaging")
class SleuthMessagingProperties {
public class SleuthMessagingProperties {
private Messaging messaging = new Messaging();

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.instrument.mongodb;
package org.springframework.cloud.sleuth.autoconfig.brave.instrument.mongodb;
import brave.Tracing;
import brave.mongodb.MongoDBTracing;
@@ -28,7 +28,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer;
import org.springframework.cloud.sleuth.brave.autoconfig.TraceBraveAutoConfiguration;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.brave.instrument.mongodb.TraceMongoClientSettingsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -41,11 +42,11 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(Tracing.class)
@AutoConfigureAfter(TraceBraveAutoConfiguration.class)
@AutoConfigureAfter(BraveAutoConfiguration.class)
@AutoConfigureBefore(MongoAutoConfiguration.class)
@ConditionalOnProperty(value = "spring.sleuth.mongodb.enabled", matchIfMissing = true)
@ConditionalOnClass(MongoClientSettings.Builder.class)
class TraceMongoDbAutoConfiguration {
@ConditionalOnClass({ MongoClientSettings.Builder.class, MongoDBTracing.class })
public class BraveMongoDbAutoConfiguration {
@Bean
// for tests
@@ -55,18 +56,3 @@ class TraceMongoDbAutoConfiguration {
}
}
class TraceMongoClientSettingsBuilderCustomizer implements MongoClientSettingsBuilderCustomizer {
private final Tracing tracing;
TraceMongoClientSettingsBuilderCustomizer(Tracing tracing) {
this.tracing = tracing;
}
@Override
public void customize(MongoClientSettings.Builder clientSettingsBuilder) {
clientSettingsBuilder.addCommandListener(MongoDBTracing.create(this.tracing).commandListener());
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth.brave.instrument.opentracing;
package org.springframework.cloud.sleuth.autoconfig.brave.instrument.opentracing;
import brave.Tracing;
import brave.opentracing.BraveTracer;
@@ -26,8 +26,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.sleuth.brave.autoconfig.TraceBraveAutoConfiguration;
import org.springframework.cloud.sleuth.opentracing.SleuthOpentracingProperties;
import org.springframework.cloud.sleuth.autoconfig.SleuthOpentracingProperties;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -42,10 +42,10 @@ import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.opentracing.enabled", matchIfMissing = true)
@ConditionalOnBean(Tracing.class)
@ConditionalOnClass(Tracer.class)
@AutoConfigureAfter(TraceBraveAutoConfiguration.class)
@ConditionalOnClass({ Tracer.class, BraveTracer.class })
@AutoConfigureAfter(BraveAutoConfiguration.class)
@EnableConfigurationProperties(SleuthOpentracingProperties.class)
class OpentracingAutoConfiguration {
public class BraveOpentracingAutoConfiguration {
@Bean
@ConditionalOnMissingBean

View File

@@ -0,0 +1,55 @@
/*
* 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.autoconfig.brave.instrument.redis;
import brave.Tracing;
import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.tracing.BraveTracing;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
import org.springframework.cloud.sleuth.autoconfig.instrument.redis.TraceLettuceClientResourcesBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} enables Redis span information propagation.
*
* @author Chao Chang
* @since 2.2.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.redis.enabled", matchIfMissing = true)
@ConditionalOnBean({ Tracing.class, ClientResources.class })
@AutoConfigureAfter({ BraveAutoConfiguration.class })
@EnableConfigurationProperties(TraceRedisProperties.class)
@ConditionalOnClass(BraveTracing.class)
public class BraveRedisAutoConfiguration {
@Bean
static TraceLettuceClientResourcesBeanPostProcessor traceLettuceClientResourcesBeanPostProcessor(
BeanFactory beanFactory, TraceRedisProperties traceRedisProperties) {
return new TraceLettuceClientResourcesBeanPostProcessor(beanFactory, traceRedisProperties);
}
}

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