diff --git a/multi/multi__customizations.html b/multi/multi__customizations.html index 6c076f043..9018db978 100644 --- a/multi/multi__customizations.html +++ b/multi/multi__customizations.html @@ -17,7 +17,8 @@ an example of usage of SkipPatternProvider inside a Pattern pattern = provider.skipPattern(); return new HttpSampler() { - @Override public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) { + @Override + public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) { String url = adapter.path(request); boolean shouldSkip = pattern.matcher(url).matches(); if (shouldSkip) { @@ -38,7 +39,8 @@ You can customize the tags or modify the response headers by registering your ow this.tracer = tracer; } - @Override public void doFilter(ServletRequest request, ServletResponse response, + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Span currentSpan = this.tracer.currentSpan(); if (currentSpan == null) { @@ -46,32 +48,36 @@ You can customize the tags or modify the response headers by registering your ow return; } // for readability we're returning trace id in a hex form - ((HttpServletResponse) response) - .addHeader("ZIPKIN-TRACE-ID", - currentSpan.context().traceIdString()); + ((HttpServletResponse) response).addHeader("ZIPKIN-TRACE-ID", + currentSpan.context().traceIdString()); // we can also add some custom tags currentSpan.tag("custom", "tag"); chain.doFilter(request, response); } + } -//end::response_headers[]

12.3 Custom service name

By default, Sleuth assumes that, when you send a span to Zipkin, you want the span’s service name to be equal to the value of the spring.application.name property. +// end::response_headers[]

12.3 Custom service name

By default, Sleuth assumes that, when you send a span to Zipkin, you want the span’s service name to be equal to the value of the spring.application.name property. That is not always the case, though. There are situations in which you want to explicitly provide a different service name for all spans coming from your application. To achieve that, you can pass the following property to your application to override that value (the example is for a service named myService):

spring.zipkin.service.name: myService

12.4 Customization of Reported Spans

Before reporting spans (for example, to Zipkin) you may want to modify that span in some way. You can do so by using the FinishedSpanHandler interface.

In Sleuth, we generate spans with a fixed name. Some users want to modify the name depending on values of tags. -You can implement the FinishedSpanHandler interface to alter that name.

The following example shows how to register two beans that implement FinishedSpanHandler:

@Bean FinishedSpanHandler handlerOne() {
+You can implement the FinishedSpanHandler interface to alter that name.

The following example shows how to register two beans that implement FinishedSpanHandler:

@Bean
+FinishedSpanHandler handlerOne() {
 	return new FinishedSpanHandler() {
-		@Override public boolean handle(TraceContext traceContext, MutableSpan span) {
+		@Override
+		public boolean handle(TraceContext traceContext, MutableSpan span) {
 			span.name("foo");
 			return true; // keep this span
 		}
 	};
 }
 
-@Bean FinishedSpanHandler handlerTwo() {
+@Bean
+FinishedSpanHandler handlerTwo() {
 	return new FinishedSpanHandler() {
-		@Override public boolean handle(TraceContext traceContext, MutableSpan span) {
+		@Override
+		public boolean handle(TraceContext traceContext, MutableSpan span) {
 			span.name(span.name() + " bar");
 			return true; // keep this span
 		}
diff --git a/multi/multi__integrations.html b/multi/multi__integrations.html
index 03b3f2c12..285c4c2f5 100644
--- a/multi/multi__integrations.html
+++ b/multi/multi__integrations.html
@@ -34,7 +34,8 @@ Callable<String> traceCallable = "calculateTax");
 // Wrapping `Callable` with `Tracing`. That way the current span will be available
 // in the thread of `Callable`
-Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable);

That way, you ensure that a new span is created and closed for each execution.

15.3 Hystrix

15.3.1 Custom Concurrency Strategy

We register a custom HystrixConcurrencyStrategy called TraceCallable that wraps all Callable instances in their Sleuth representative. +Callable<String> traceCallableFromTracer = tracing.currentTraceContext() + .wrap(callable);

That way, you ensure that a new span is created and closed for each execution.

15.3 Hystrix

15.3.1 Custom Concurrency Strategy

We register a custom HystrixConcurrencyStrategy called TraceCallable that wraps all Callable instances in their Sleuth representative. The strategy either starts or continues a span, depending on 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.

15.3.2 Manual Command setting

Assume that you have the following HystrixCommand:

HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
 	@Override
@@ -90,20 +91,22 @@ In the following snippet, you can see an example of how to set up such a custom
 
 	@Bean(name = "customAsyncRestTemplate")
 	public AsyncRestTemplate traceAsyncRestTemplate() {
-		return new AsyncRestTemplate(asyncClientFactory(), clientHttpRequestFactory());
+		return new AsyncRestTemplate(asyncClientFactory(),
+				clientHttpRequestFactory());
 	}
 
 	private ClientHttpRequestFactory clientHttpRequestFactory() {
 		ClientHttpRequestFactory clientHttpRequestFactory = new CustomClientHttpRequestFactory();
-		//CUSTOMIZE HERE
+		// CUSTOMIZE HERE
 		return clientHttpRequestFactory;
 	}
 
 	private AsyncClientHttpRequestFactory asyncClientFactory() {
 		AsyncClientHttpRequestFactory factory = new CustomAsyncClientHttpRequestFactory();
-		//CUSTOMIZE HERE
+		// CUSTOMIZE HERE
 		return factory;
 	}
+
 }

15.6.3 WebClient

We inject a ExchangeFilterFunction implementation that creates a span and, through on-success and on-error callbacks, takes care of closing client-side spans.

To block this feature, set spring.sleuth.web.client.enabled to false.

[Important]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.

15.6.4 Traverson

If you use the 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 @@ -136,9 +139,11 @@ The following example shows how to set up such a custom Ex @EnableAsync static class CustomExecutorConfig extends AsyncConfigurerSupport { - @Autowired BeanFactory beanFactory; + @Autowired + BeanFactory beanFactory; - @Override public Executor getAsyncExecutor() { + @Override + public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // CUSTOMIZE HERE executor.setCorePoolSize(7); @@ -149,6 +154,7 @@ The following example shows how to set up such a custom Ex executor.initialize(); return new LazyTraceExecutor(this.beanFactory, executor); } + }

15.9 Messaging

Features from this section can be disabled by setting the spring.sleuth.messaging.enabled property with value equal to false.

15.9.1 Spring Integration and Spring Cloud Stream

Spring Cloud Sleuth integrates with Spring Integration. It creates spans for publish and subscribe events. To disable Spring Integration instrumentation, set spring.sleuth.integration.enabled to false.

You can provide the spring.sleuth.integration.patterns pattern to explicitly provide the names of channels that you want to include for tracing. diff --git a/multi/multi__introduction.html b/multi/multi__introduction.html index a06d05a27..3ea4a9260 100644 --- a/multi/multi__introduction.html +++ b/multi/multi__introduction.html @@ -137,7 +137,7 @@ Spring Cloud Sleuth understands that a header is baggage-related if the HTTP hea However, 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.

The following example shows setting baggage on a span:

Span initialSpan = this.tracer.nextSpan().name("span").start();
 ExtraFieldPropagation.set(initialSpan.context(), "foo", "bar");
-ExtraFieldPropagation.set(initialSpan.context(),"UPPER_CASE", "someValue");
+ExtraFieldPropagation.set(initialSpan.context(), "UPPER_CASE", "someValue");
 }

Baggage versus Span Tags

Baggage travels with the trace (every child span contains the baggage of its parent). Zipkin has no knowledge of baggage and does not receive that information.

[Important]Important

Starting from Sleuth 2.0.0 you have to pass the baggage key names explicitly in your project configuration. Read more about that setup here

Tags are attached to a specific span. In other words, they are presented only for that particular span. diff --git a/multi/multi__managing_spans_with_annotations.html b/multi/multi__managing_spans_with_annotations.html index ffce8c7e5..cd81acde9 100644 --- a/multi/multi__managing_spans_with_annotations.html +++ b/multi/multi__managing_spans_with_annotations.html @@ -31,12 +31,14 @@ 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.

  • If we do not find any expression to evaluate, return the toString() value of the parameter.
  • 11.4.1 Custom extractor

    The value of the tag for the following method is computed by an implementation of TagValueResolver interface. Its class name has to be passed as the value of the resolver attribute.

    Consider the following annotated method:

    @NewSpan
    -public void getAnnotationForTagValueResolver(@SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
    +public void getAnnotationForTagValueResolver(
    +		@SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
     }

    Now further consider the following TagValueResolver bean implementation:

    @Bean(name = "myCustomTagValueResolver")
     public TagValueResolver tagValueResolver() {
     	return parameter -> "Value from myCustomTagValueResolver";
     }

    The two preceding examples lead to setting a tag value equal to Value from myCustomTagValueResolver.

    11.4.2 Resolving Expressions for a Value

    Consider the following annotated method:

    @NewSpan
    -public void getAnnotationForTagValueExpression(@SpanTag(key = "test", expression = "'hello' + ' characters'") String test) {
    +public void getAnnotationForTagValueExpression(
    +		@SpanTag(key = "test", expression = "'hello' + ' characters'") String test) {
     }

    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. If you want to use some other expression resolution mechanism, you can create your own implementation of the bean.

    11.4.3 Using the toString() method

    Consider the following annotated method:

    @NewSpan
     public void getAnnotationForArgumentToString(@SpanTag("test") Long param) {
    diff --git a/multi/multi__naming_spans.html b/multi/multi__naming_spans.html
    index 7ba3a9dfd..de3accbe9 100644
    --- a/multi/multi__naming_spans.html
    +++ b/multi/multi__naming_spans.html
    @@ -4,9 +4,11 @@
     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:

    • controller-method-name when received by a Controller with a method name of controllerMethodName
    • async for asynchronous operations done with wrapped Callable and Runnable interfaces.
    • Methods annotated with @Scheduled return the simple name of the class.

    Fortunately, for asynchronous processing, you can provide explicit naming.

    10.1 @SpanName Annotation

    You can name the span explicitly by using the @SpanName annotation, as shown in the following example:

    @SpanName("calculateTax")
     class TaxCountingRunnable implements Runnable {
     
    -	@Override public void run() {
    +	@Override
    +	public void run() {
     		// perform logic
     	}
    +
     }

    In this case, when processed in the following manner, the span is named calculateTax:

    Runnable runnable = new TraceRunnable(tracing, spanNamer,
     		new TaxCountingRunnable());
     Future<?> future = executorService.submit(runnable);
    @@ -15,11 +17,13 @@ future.get();
    < Typically, one creates an anonymous instance of those classes. You cannot annotate such classes. To overcome that limitation, if there is no @SpanName annotation present, we check whether the class has a custom implementation of the toString() method.

    Running such code leads to creating a span named calculateTax, as shown in the following example:

    Runnable runnable = new TraceRunnable(tracing, spanNamer, new Runnable() {
    -	@Override public void run() {
    +	@Override
    +	public void run() {
     		// perform logic
     	}
     
    -	@Override public String toString() {
    +	@Override
    +	public String toString() {
     		return "calculateTax";
     	}
     });
    diff --git a/multi/multi__span_lifecycle.html b/multi/multi__span_lifecycle.html
    index 66dc72b91..2401e81e8 100644
    --- a/multi/multi__span_lifecycle.html
    +++ b/multi/multi__span_lifecycle.html
    @@ -12,7 +12,8 @@ Span newSpan = 
     	// ...
     	// You can log an event on a span
     	newSpan.annotate("taxCalculated");
    -} finally {
    +}
    +finally {
     	// Once done remember to finish the span. This will allow collecting
     	// the span to send it to Zipkin
     	newSpan.finish();
    @@ -30,7 +31,8 @@ Span continuedSpan = // ...
     	// You can log an event on a span
     	continuedSpan.annotate("taxCalculated");
    -} finally {
    +}
    +finally {
     	// Once done remember to flush the span. That means that
     	// it will get reported but the span itself is not yet finished
     	continuedSpan.flush();
    @@ -49,7 +51,8 @@ Span newSpan = null;
     	// ...
     	// You can log an event on a span
     	newSpan.annotate("commissionCalculated");
    -} finally {
    +}
    +finally {
     	// Once done remember to finish the span. This will allow collecting
     	// the span to send it to Zipkin. The tags and events set on the
     	// newSpan will not be present on the parent
    diff --git a/single/spring-cloud-sleuth.html b/single/spring-cloud-sleuth.html
    index f7eb90302..f2e2cde89 100644
    --- a/single/spring-cloud-sleuth.html
    +++ b/single/spring-cloud-sleuth.html
    @@ -137,7 +137,7 @@ Spring Cloud Sleuth understands that a header is baggage-related if the HTTP hea
     However, 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.

    The following example shows setting baggage on a span:

    Span initialSpan = this.tracer.nextSpan().name("span").start();
     ExtraFieldPropagation.set(initialSpan.context(), "foo", "bar");
    -ExtraFieldPropagation.set(initialSpan.context(),"UPPER_CASE", "someValue");
    +ExtraFieldPropagation.set(initialSpan.context(), "UPPER_CASE", "someValue");
     }

    Baggage versus Span Tags

    Baggage travels with the trace (every child span contains the baggage of its parent). Zipkin has no knowledge of baggage and does not receive that information.

    [Important]Important

    Starting from Sleuth 2.0.0 you have to pass the baggage key names explicitly in your project configuration. Read more about that setup here

    Tags are attached to a specific span. In other words, they are presented only for that particular span. @@ -557,7 +557,8 @@ Span newSpan = // ... // You can log an event on a span newSpan.annotate("taxCalculated"); -} finally { +} +finally { // Once done remember to finish the span. This will allow collecting // the span to send it to Zipkin newSpan.finish(); @@ -575,7 +576,8 @@ Span continuedSpan = // ... // You can log an event on a span continuedSpan.annotate("taxCalculated"); -} finally { +} +finally { // Once done remember to flush the span. That means that // it will get reported but the span itself is not yet finished continuedSpan.flush(); @@ -594,7 +596,8 @@ Span newSpan = null; // ... // You can log an event on a span newSpan.annotate("commissionCalculated"); -} finally { +} +finally { // Once done remember to finish the span. This will allow collecting // the span to send it to Zipkin. The tags and events set on the // newSpan will not be present on the parent @@ -605,9 +608,11 @@ Span newSpan = null; 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:

    • controller-method-name when received by a Controller with a method name of controllerMethodName
    • async for asynchronous operations done with wrapped Callable and Runnable interfaces.
    • Methods annotated with @Scheduled return the simple name of the class.

    Fortunately, for asynchronous processing, you can provide explicit naming.

    10.1 @SpanName Annotation

    You can name the span explicitly by using the @SpanName annotation, as shown in the following example:

    @SpanName("calculateTax")
     class TaxCountingRunnable implements Runnable {
     
    -	@Override public void run() {
    +	@Override
    +	public void run() {
     		// perform logic
     	}
    +
     }

    In this case, when processed in the following manner, the span is named calculateTax:

    Runnable runnable = new TraceRunnable(tracing, spanNamer,
     		new TaxCountingRunnable());
     Future<?> future = executorService.submit(runnable);
    @@ -616,11 +621,13 @@ future.get();
    < Typically, one creates an anonymous instance of those classes. You cannot annotate such classes. To overcome that limitation, if there is no @SpanName annotation present, we check whether the class has a custom implementation of the toString() method.

    Running such code leads to creating a span named calculateTax, as shown in the following example:

    Runnable runnable = new TraceRunnable(tracing, spanNamer, new Runnable() {
    -	@Override public void run() {
    +	@Override
    +	public void run() {
     		// perform logic
     	}
     
    -	@Override public String toString() {
    +	@Override
    +	public String toString() {
     		return "calculateTax";
     	}
     });
    @@ -657,12 +664,14 @@ 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.
  • If we do not find any expression to evaluate, return the toString() value of the parameter.
  • 11.4.1 Custom extractor

    The value of the tag for the following method is computed by an implementation of TagValueResolver interface. Its class name has to be passed as the value of the resolver attribute.

    Consider the following annotated method:

    @NewSpan
    -public void getAnnotationForTagValueResolver(@SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
    +public void getAnnotationForTagValueResolver(
    +		@SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
     }

    Now further consider the following TagValueResolver bean implementation:

    @Bean(name = "myCustomTagValueResolver")
     public TagValueResolver tagValueResolver() {
     	return parameter -> "Value from myCustomTagValueResolver";
     }

    The two preceding examples lead to setting a tag value equal to Value from myCustomTagValueResolver.

    11.4.2 Resolving Expressions for a Value

    Consider the following annotated method:

    @NewSpan
    -public void getAnnotationForTagValueExpression(@SpanTag(key = "test", expression = "'hello' + ' characters'") String test) {
    +public void getAnnotationForTagValueExpression(
    +		@SpanTag(key = "test", expression = "'hello' + ' characters'") String test) {
     }

    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. If you want to use some other expression resolution mechanism, you can create your own implementation of the bean.

    11.4.3 Using the toString() method

    Consider the following annotated method:

    @NewSpan
     public void getAnnotationForArgumentToString(@SpanTag("test") Long param) {
    @@ -683,7 +692,8 @@ an example of usage of SkipPatternProvider inside a
       	Pattern pattern = provider.skipPattern();
       	return new HttpSampler() {
     
    -  		@Override public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) {
    +  		@Override
    +  		public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) {
       			String url = adapter.path(request);
       			boolean shouldSkip = pattern.matcher(url).matches();
       			if (shouldSkip) {
    @@ -704,7 +714,8 @@ You can customize the tags or modify the response headers by registering your ow
     		this.tracer = tracer;
     	}
     
    -	@Override public void doFilter(ServletRequest request, ServletResponse response,
    +	@Override
    +	public void doFilter(ServletRequest request, ServletResponse response,
     			FilterChain chain) throws IOException, ServletException {
     		Span currentSpan = this.tracer.currentSpan();
     		if (currentSpan == null) {
    @@ -712,32 +723,36 @@ You can customize the tags or modify the response headers by registering your ow
     			return;
     		}
     		// for readability we're returning trace id in a hex form
    -		((HttpServletResponse) response)
    -				.addHeader("ZIPKIN-TRACE-ID",
    -						currentSpan.context().traceIdString());
    +		((HttpServletResponse) response).addHeader("ZIPKIN-TRACE-ID",
    +				currentSpan.context().traceIdString());
     		// we can also add some custom tags
     		currentSpan.tag("custom", "tag");
     		chain.doFilter(request, response);
     	}
    +
     }
    -//end::response_headers[]

    12.3 Custom service name

    By default, Sleuth assumes that, when you send a span to Zipkin, you want the span’s service name to be equal to the value of the spring.application.name property. +// end::response_headers[]

    12.3 Custom service name

    By default, Sleuth assumes that, when you send a span to Zipkin, you want the span’s service name to be equal to the value of the spring.application.name property. That is not always the case, though. There are situations in which you want to explicitly provide a different service name for all spans coming from your application. To achieve that, you can pass the following property to your application to override that value (the example is for a service named myService):

    spring.zipkin.service.name: myService

    12.4 Customization of Reported Spans

    Before reporting spans (for example, to Zipkin) you may want to modify that span in some way. You can do so by using the FinishedSpanHandler interface.

    In Sleuth, we generate spans with a fixed name. Some users want to modify the name depending on values of tags. -You can implement the FinishedSpanHandler interface to alter that name.

    The following example shows how to register two beans that implement FinishedSpanHandler:

    @Bean FinishedSpanHandler handlerOne() {
    +You can implement the FinishedSpanHandler interface to alter that name.

    The following example shows how to register two beans that implement FinishedSpanHandler:

    @Bean
    +FinishedSpanHandler handlerOne() {
     	return new FinishedSpanHandler() {
    -		@Override public boolean handle(TraceContext traceContext, MutableSpan span) {
    +		@Override
    +		public boolean handle(TraceContext traceContext, MutableSpan span) {
     			span.name("foo");
     			return true; // keep this span
     		}
     	};
     }
     
    -@Bean FinishedSpanHandler handlerTwo() {
    +@Bean
    +FinishedSpanHandler handlerTwo() {
     	return new FinishedSpanHandler() {
    -		@Override public boolean handle(TraceContext traceContext, MutableSpan span) {
    +		@Override
    +		public boolean handle(TraceContext traceContext, MutableSpan span) {
     			span.name(span.name() + " bar");
     			return true; // keep this span
     		}
    @@ -806,7 +821,8 @@ Callable<String> traceCallable = "calculateTax");
     // Wrapping `Callable` with `Tracing`. That way the current span will be available
     // in the thread of `Callable`
    -Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable);

    That way, you ensure that a new span is created and closed for each execution.

    15.3 Hystrix

    15.3.1 Custom Concurrency Strategy

    We register a custom HystrixConcurrencyStrategy called TraceCallable that wraps all Callable instances in their Sleuth representative. +Callable<String> traceCallableFromTracer = tracing.currentTraceContext() + .wrap(callable);

    That way, you ensure that a new span is created and closed for each execution.

    15.3 Hystrix

    15.3.1 Custom Concurrency Strategy

    We register a custom HystrixConcurrencyStrategy called TraceCallable that wraps all Callable instances in their Sleuth representative. The strategy either starts or continues a span, depending on 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.

    15.3.2 Manual Command setting

    Assume that you have the following HystrixCommand:

    HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
     	@Override
    @@ -862,20 +878,22 @@ In the following snippet, you can see an example of how to set up such a custom
     
     	@Bean(name = "customAsyncRestTemplate")
     	public AsyncRestTemplate traceAsyncRestTemplate() {
    -		return new AsyncRestTemplate(asyncClientFactory(), clientHttpRequestFactory());
    +		return new AsyncRestTemplate(asyncClientFactory(),
    +				clientHttpRequestFactory());
     	}
     
     	private ClientHttpRequestFactory clientHttpRequestFactory() {
     		ClientHttpRequestFactory clientHttpRequestFactory = new CustomClientHttpRequestFactory();
    -		//CUSTOMIZE HERE
    +		// CUSTOMIZE HERE
     		return clientHttpRequestFactory;
     	}
     
     	private AsyncClientHttpRequestFactory asyncClientFactory() {
     		AsyncClientHttpRequestFactory factory = new CustomAsyncClientHttpRequestFactory();
    -		//CUSTOMIZE HERE
    +		// CUSTOMIZE HERE
     		return factory;
     	}
    +
     }

    15.6.3 WebClient

    We inject a ExchangeFilterFunction implementation that creates a span and, through on-success and on-error callbacks, takes care of closing client-side spans.

    To block this feature, set spring.sleuth.web.client.enabled to false.

    [Important]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.

    15.6.4 Traverson

    If you use the 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 @@ -908,9 +926,11 @@ The following example shows how to set up such a custom Ex @EnableAsync static class CustomExecutorConfig extends AsyncConfigurerSupport { - @Autowired BeanFactory beanFactory; + @Autowired + BeanFactory beanFactory; - @Override public Executor getAsyncExecutor() { + @Override + public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // CUSTOMIZE HERE executor.setCorePoolSize(7); @@ -921,6 +941,7 @@ The following example shows how to set up such a custom Ex executor.initialize(); return new LazyTraceExecutor(this.beanFactory, executor); } + }

    15.9 Messaging

    Features from this section can be disabled by setting the spring.sleuth.messaging.enabled property with value equal to false.

    15.9.1 Spring Integration and Spring Cloud Stream

    Spring Cloud Sleuth integrates with Spring Integration. It creates spans for publish and subscribe events. To disable Spring Integration instrumentation, set spring.sleuth.integration.enabled to false.

    You can provide the spring.sleuth.integration.patterns pattern to explicitly provide the names of channels that you want to include for tracing. diff --git a/spring-cloud-sleuth.xml b/spring-cloud-sleuth.xml index 593c38b0d..702df06e6 100644 --- a/spring-cloud-sleuth.xml +++ b/spring-cloud-sleuth.xml @@ -365,7 +365,7 @@ In extreme cases, too much baggage can crash the application, due to exceeding t The following example shows setting baggage on a span: Span initialSpan = this.tracer.nextSpan().name("span").start(); ExtraFieldPropagation.set(initialSpan.context(), "foo", "bar"); -ExtraFieldPropagation.set(initialSpan.context(),"UPPER_CASE", "someValue"); +ExtraFieldPropagation.set(initialSpan.context(), "UPPER_CASE", "someValue"); }

    Baggage versus Span Tags @@ -1211,7 +1211,8 @@ try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(newSpan.start())) { // ... // You can log an event on a span newSpan.annotate("taxCalculated"); -} finally { +} +finally { // Once done remember to finish the span. This will allow collecting // the span to send it to Zipkin newSpan.finish(); @@ -1250,7 +1251,8 @@ try { // ... // You can log an event on a span continuedSpan.annotate("taxCalculated"); -} finally { +} +finally { // Once done remember to flush the span. That means that // it will get reported but the span itself is not yet finished continuedSpan.flush(); @@ -1274,7 +1276,8 @@ try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(initialSpan)) { // ... // You can log an event on a span newSpan.annotate("commissionCalculated"); -} finally { +} +finally { // Once done remember to finish the span. This will allow collecting // the span to send it to Zipkin. The tags and events set on the // newSpan will not be present on the parent @@ -1310,9 +1313,11 @@ The name should be low cardinality, so it should not include identifiers.@SpanName("calculateTax") class TaxCountingRunnable implements Runnable { - @Override public void run() { + @Override + public void run() { // perform logic } + } In this case, when processed in the following manner, the span is named calculateTax: Runnable runnable = new TraceRunnable(tracing, spanNamer, @@ -1329,11 +1334,13 @@ You cannot annotate such classes. To overcome that limitation, if there is no @SpanName annotation present, we check whether the class has a custom implementation of the toString() method. Running such code leads to creating a span named calculateTax, as shown in the following example: Runnable runnable = new TraceRunnable(tracing, spanNamer, new Runnable() { - @Override public void run() { + @Override + public void run() { // perform logic } - @Override public String toString() { + @Override + public String toString() { return "calculateTax"; } }); @@ -1440,7 +1447,8 @@ The default implementation uses SPEL expression resolution. Its class name has to be passed as the value of the resolver attribute. Consider the following annotated method: @NewSpan -public void getAnnotationForTagValueResolver(@SpanTag(key = "test", resolver = TagValueResolver.class) String test) { +public void getAnnotationForTagValueResolver( + @SpanTag(key = "test", resolver = TagValueResolver.class) String test) { } Now further consider the following TagValueResolver bean implementation: @Bean(name = "myCustomTagValueResolver") @@ -1453,7 +1461,8 @@ public TagValueResolver tagValueResolver() { Resolving Expressions for a Value Consider the following annotated method: @NewSpan -public void getAnnotationForTagValueExpression(@SpanTag(key = "test", expression = "'hello' + ' characters'") String test) { +public void getAnnotationForTagValueExpression( + @SpanTag(key = "test", expression = "'hello' + ' characters'") String test) { } 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. If you want to use some other expression resolution mechanism, you can create your own implementation of the bean. @@ -1492,7 +1501,8 @@ class Config { Pattern pattern = provider.skipPattern(); return new HttpSampler() { - @Override public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) { + @Override + public <Req> Boolean trySample(HttpAdapter<Req, ?> adapter, Req request) { String url = adapter.path(request); boolean shouldSkip = pattern.matcher(url).matches(); if (shouldSkip) { @@ -1519,7 +1529,8 @@ class MyFilter extends GenericFilterBean { this.tracer = tracer; } - @Override public void doFilter(ServletRequest request, ServletResponse response, + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Span currentSpan = this.tracer.currentSpan(); if (currentSpan == null) { @@ -1527,15 +1538,15 @@ class MyFilter extends GenericFilterBean { return; } // for readability we're returning trace id in a hex form - ((HttpServletResponse) response) - .addHeader("ZIPKIN-TRACE-ID", - currentSpan.context().traceIdString()); + ((HttpServletResponse) response).addHeader("ZIPKIN-TRACE-ID", + currentSpan.context().traceIdString()); // we can also add some custom tags currentSpan.tag("custom", "tag"); chain.doFilter(request, response); } + } -//end::response_headers[] +// end::response_headers[]
    Custom service name @@ -1553,18 +1564,22 @@ You can do so by using the FinishedSpanHandler interface.FinishedSpanHandler interface to alter that name. The following example shows how to register two beans that implement FinishedSpanHandler: -@Bean FinishedSpanHandler handlerOne() { +@Bean +FinishedSpanHandler handlerOne() { return new FinishedSpanHandler() { - @Override public boolean handle(TraceContext traceContext, MutableSpan span) { + @Override + public boolean handle(TraceContext traceContext, MutableSpan span) { span.name("foo"); return true; // keep this span } }; } -@Bean FinishedSpanHandler handlerTwo() { +@Bean +FinishedSpanHandler handlerTwo() { return new FinishedSpanHandler() { - @Override public boolean handle(TraceContext traceContext, MutableSpan span) { + @Override + public boolean handle(TraceContext traceContext, MutableSpan span) { span.name(span.name() + " bar"); return true; // keep this span } @@ -1680,7 +1695,8 @@ Callable<String> traceCallable = new TraceCallable<>(tracing, spanNa "calculateTax"); // Wrapping `Callable` with `Tracing`. That way the current span will be available // in the thread of `Callable` -Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable); +Callable<String> traceCallableFromTracer = tracing.currentTraceContext() + .wrap(callable); That way, you ensure that a new span is created and closed for each execution.
    @@ -1810,20 +1826,22 @@ static class Config { @Bean(name = "customAsyncRestTemplate") public AsyncRestTemplate traceAsyncRestTemplate() { - return new AsyncRestTemplate(asyncClientFactory(), clientHttpRequestFactory()); + return new AsyncRestTemplate(asyncClientFactory(), + clientHttpRequestFactory()); } private ClientHttpRequestFactory clientHttpRequestFactory() { ClientHttpRequestFactory clientHttpRequestFactory = new CustomClientHttpRequestFactory(); - //CUSTOMIZE HERE + // CUSTOMIZE HERE return clientHttpRequestFactory; } private AsyncClientHttpRequestFactory asyncClientFactory() { AsyncClientHttpRequestFactory factory = new CustomAsyncClientHttpRequestFactory(); - //CUSTOMIZE HERE + // CUSTOMIZE HERE return factory; } + }
    @@ -1940,9 +1958,11 @@ The following example shows how to set up such a custom Executor