Added integrations documentation
This commit is contained in:
@@ -179,6 +179,7 @@ include::../../../../spring-cloud-sleuth-core/src/test/java/org/springframework/
|
||||
|
||||
will lead in creating a span named `calculateTax`.
|
||||
|
||||
|
||||
== Span Data as Messages
|
||||
|
||||
You can accumulate and send span data over
|
||||
@@ -273,10 +274,111 @@ the number of dropped spans will get increased.
|
||||
|
||||
== Integrations
|
||||
|
||||
=== Runnable and Callable
|
||||
|
||||
If you're wrapping your logic in `Runnable` or `Callable` it's enough to wrap those classes in their Sleuth representative.
|
||||
|
||||
Example for `Runnable`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::../../../../spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=trace_runnable,indent=0]
|
||||
----
|
||||
|
||||
Example for `Callable`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::../../../../spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java[tags=trace_callable,indent=0]
|
||||
----
|
||||
|
||||
That way you will ensure that a new Span is created and closed for each execution.
|
||||
|
||||
=== Hystrix
|
||||
|
||||
==== Custom Concurrency Strategy
|
||||
|
||||
We're registering a custom https://github.com/Netflix/Hystrix/wiki/Plugins#concurrencystrategy[`HystrixConcurrencyStrategy`]
|
||||
that wraps all `Callable` instances into their Sleuth representative -
|
||||
the `TraceCallable`. The strategy either starts or continues a span depending on the fact whether tracing was already going
|
||||
on before the Hystrix command was called.
|
||||
|
||||
To disable the custom Hystrix Concurrency Strategy set the `spring.sleuth.hystrix.strategy.enabled` to `false`.
|
||||
|
||||
==== Manual Command setting
|
||||
|
||||
Assuming that you have the following `HystrixCommand`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::../../../../spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java[tags=hystrix_command,indent=0]
|
||||
----
|
||||
|
||||
In order to pass the tracing information you have to wrap the same logic in the Sleuth version of the `HystrixCommand` which is the
|
||||
`TraceCommand`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::../../../../spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java[tags=trace_hystrix_command,indent=0]
|
||||
----
|
||||
|
||||
=== HTTP integration
|
||||
|
||||
Features from this section can be disabled by providing the `spring.sleuth.web.enabled` property with value equal to `false`.
|
||||
|
||||
==== HTTP Filter
|
||||
|
||||
Via the `TraceFilter` all sampled incoming requests result in creation of a Span. That Span's name is `http:` + the path to which
|
||||
the request was sent. E.g. if the request was sent to `/foo/bar` then the name will be `http:/foo/bar`. You can configure which URIs you would
|
||||
like to skip via the `spring.sleuth.instrument.web.skipPattern` property.
|
||||
|
||||
==== Async Servlet support
|
||||
|
||||
If your controller returns a `Callable` or a `WebAsyncTask` Spring Cloud Sleuth will continue the existing span instead of creating a new one.
|
||||
|
||||
=== HTTP client integration
|
||||
|
||||
==== Synchronous Rest Template
|
||||
|
||||
We're injecting a `RestTemplate` interceptor that ensures that all the tracing information is passed to the requests. Each time a
|
||||
call is made a new Span is created. It gets closed upon receiving the response. In order to block the synchronous `RestTemplate` features
|
||||
just set `spring.sleuth.client.enabled` to `false`.
|
||||
|
||||
==== Asynchronous Rest Template
|
||||
|
||||
Custom instrumentation is set to create and close Spans upon sending and receiving requests. To block the `AsyncRestTemplate`
|
||||
features set `spring.sleuth.async.client.enabled` to `false`.
|
||||
|
||||
=== Feign
|
||||
|
||||
By default Spring Cloud Sleuth provides integration with feign via the `TraceFeignClientAutoConfiguration`. You can disable it
|
||||
By default Spring Cloud Sleuth provides integration with feign via the `TraceFeignClientAutoConfiguration`. You can disable it entirely
|
||||
by setting `spring.sleuth.feign.enabled` to false.
|
||||
|
||||
We're taking care of Feign instrumentation by means of a `FeignBeanPostProcessor`.
|
||||
You can disable the post processor by providing the `spring.sleuth.feign.processor.enabled` equal to `false`.
|
||||
Part of Feign instrumentation is done via a `FeignBeanPostProcessor`. You can disable it by providing the `spring.sleuth.feign.processor.enabled` equal to `false`.
|
||||
|
||||
=== Asynchronous communication
|
||||
|
||||
In Spring Cloud Sleuth we're instrumenting async related components so that the tracing information is passed between threads. You can disable this behaviour
|
||||
by setting the value of `spring.sleuth.async.enabled` to `false`.
|
||||
|
||||
==== @Async / @Scheduled annotated methods
|
||||
|
||||
If you annotate your method with `@Async` / `@Scheduled` then we'll automatically create a new Span with the following characteristics:
|
||||
|
||||
- the Span name will be the annotated method name
|
||||
- the Span will be tagged with that method's class name and the method name too
|
||||
|
||||
==== Executor, ExecutorService and ScheduledExecutorService
|
||||
|
||||
We're providing `LazyTraceExecutor`, `TraceableExecutorService` and `TraceableScheduledExecutorService`. Those implementations
|
||||
are creating Spans each time a new task is submitted, invoked or scheduled.
|
||||
|
||||
=== Messaging
|
||||
|
||||
All http://projects.spring.io/spring-integration/[Spring Integration] creates spans for publish and subscribe events.
|
||||
To disable Spring Integration instrumentation, set spring.sleuth.integration.enabled to false.
|
||||
|
||||
=== Zuul
|
||||
|
||||
We registering Zuul filters to propagate the tracing information (the request header is enriched with tracing data).
|
||||
To disable Zuul support set the `spring.sleuth.zuul.enabled` property to `false`.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.sleuth.documentation;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -30,6 +31,7 @@ import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.SpanNamer;
|
||||
import org.springframework.cloud.sleuth.TraceCallable;
|
||||
import org.springframework.cloud.sleuth.TraceRunnable;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
@@ -216,4 +218,66 @@ public class SpringCloudSleuthDocTests {
|
||||
assertThat(initialSpan.logs()).extracting("event").doesNotContain("commissionCalculated");
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_wrap_runnable_in_its_sleuth_representative() {
|
||||
SpanNamer spanNamer = new DefaultSpanNamer();
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, spanNamer);
|
||||
Span initialSpan = tracer.createSpan("initialSpan");
|
||||
// tag::trace_runnable[]
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// do some work
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "spanNameFromToStringMethod";
|
||||
}
|
||||
};
|
||||
// Manual `TraceRunnable` creation with explicit "calculateTax" Span name
|
||||
Runnable traceRunnable = new TraceRunnable(tracer, spanNamer, runnable, "calculateTax");
|
||||
// Wrapping `Runnable` with `Tracer`. The Span name will be taken either from the
|
||||
// `@SpanName` annotation or from `toString` method
|
||||
Runnable traceRunnableFromTracer = tracer.wrap(runnable);
|
||||
// end::trace_runnable[]
|
||||
|
||||
then(traceRunnable).isExactlyInstanceOf(TraceRunnable.class);
|
||||
then(traceRunnableFromTracer).isExactlyInstanceOf(TraceRunnable.class);
|
||||
tracer.close(initialSpan);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_wrap_callable_in_its_sleuth_representative() {
|
||||
SpanNamer spanNamer = new DefaultSpanNamer();
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, spanNamer);
|
||||
Span initialSpan = tracer.createSpan("initialSpan");
|
||||
// tag::trace_callable[]
|
||||
Callable<String> callable = new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return someLogic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "spanNameFromToStringMethod";
|
||||
}
|
||||
};
|
||||
// Manual `TraceCallable` creation with explicit "calculateTax" Span name
|
||||
Callable<String> traceCallable = new TraceCallable<>(tracer, spanNamer, callable, "calculateTax");
|
||||
// Wrapping `Callable` with `Tracer`. The Span name will be taken either from the
|
||||
// `@SpanName` annotation or from `toString` method
|
||||
Callable<String> traceCallableFromTracer = tracer.wrap(callable);
|
||||
// end::trace_callable[]
|
||||
|
||||
then(traceCallable).isExactlyInstanceOf(TraceCallable.class);
|
||||
then(traceCallableFromTracer).isExactlyInstanceOf(TraceCallable.class);
|
||||
tracer.close(initialSpan);
|
||||
}
|
||||
|
||||
private String someLogic() {
|
||||
return "some logic";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,15 @@ import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.DefaultSpanNamer;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.cloud.sleuth.trace.DefaultTracer;
|
||||
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixCommandKey;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
||||
@@ -22,6 +24,7 @@ import com.netflix.hystrix.strategy.HystrixPlugins;
|
||||
|
||||
import static com.netflix.hystrix.HystrixCommand.Setter.withGroupKey;
|
||||
import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
public class TraceCommandTests {
|
||||
@@ -79,6 +82,42 @@ public class TraceCommandTests {
|
||||
.hasATag("threadPoolKey", "group");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_pass_tracing_information_when_using_Hystrix_commands() {
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(),
|
||||
Mockito.mock(ApplicationEventPublisher.class), new DefaultSpanNamer());
|
||||
TraceKeys traceKeys = new TraceKeys();
|
||||
HystrixCommand.Setter setter = HystrixCommand.Setter
|
||||
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("group"))
|
||||
.andCommandKey(HystrixCommandKey.Factory.asKey("command"));
|
||||
// tag::hystrix_command[]
|
||||
HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
|
||||
@Override
|
||||
protected String run() throws Exception {
|
||||
return someLogic();
|
||||
}
|
||||
};
|
||||
// end::hystrix_command[]
|
||||
// tag::trace_hystrix_command[]
|
||||
TraceCommand<String> traceCommand = new TraceCommand<String>(tracer, traceKeys, setter) {
|
||||
@Override
|
||||
public String doRun() throws Exception {
|
||||
return someLogic();
|
||||
}
|
||||
};
|
||||
// end::trace_hystrix_command[]
|
||||
|
||||
String resultFromHystrixCommand = hystrixCommand.execute();
|
||||
String resultFromTraceCommand = traceCommand.execute();
|
||||
|
||||
then(resultFromHystrixCommand).isEqualTo(resultFromTraceCommand);
|
||||
then(tracer.getCurrentSpan()).isNull();
|
||||
}
|
||||
|
||||
private String someLogic(){
|
||||
return "some logic";
|
||||
}
|
||||
|
||||
private Span givenATraceIsPresentInTheCurrentThread() {
|
||||
return this.tracer.createSpan("http:test",
|
||||
Span.builder().traceId(EXPECTED_TRACE_ID).build());
|
||||
|
||||
@@ -182,6 +182,7 @@ public class DefaultTracerTests {
|
||||
|
||||
then(span).hasATag("key", "value").hasLoggedAnEvent("event");
|
||||
then(continuedSpan).hasATag("key", "value").hasLoggedAnEvent("event");
|
||||
then(span).isEqualTo(continuedSpan);
|
||||
}
|
||||
|
||||
private Span assertSpan(List<Span> spans, Long parentId, String name) {
|
||||
|
||||
Reference in New Issue
Block a user