185 lines
34 KiB
HTML
185 lines
34 KiB
HTML
<html><head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>13. Integrations</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="multi_spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="multi__metrics.html" title="12. Metrics"><link rel="next" href="multi__running_examples.html" title="14. Running examples"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">13. Integrations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__metrics.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__running_examples.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_integrations" href="#_integrations"></a>13. Integrations</h1></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_runnable_and_callable" href="#_runnable_and_callable"></a>13.1 Runnable and Callable</h2></div></div></div><p>If you’re wrapping your logic in <code class="literal">Runnable</code> or <code class="literal">Callable</code> it’s enough to wrap those classes in their Sleuth representative.</p><p>Example for <code class="literal">Runnable</code>:</p><pre class="programlisting">Runnable runnable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Runnable() {
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> run() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// do some work</span>
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String toString() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"spanNameFromToStringMethod"</span>;
|
|
}
|
|
};
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Manual `TraceRunnable` creation with explicit "calculateTax" Span name</span>
|
|
Runnable traceRunnable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceRunnable(tracer, spanNamer, runnable, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Wrapping `Runnable` with `Tracer`. The Span name will be taken either from the</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// `@SpanName` annotation or from `toString` method</span>
|
|
Runnable traceRunnableFromTracer = tracer.wrap(runnable);</pre><p>Example for <code class="literal">Callable</code>:</p><pre class="programlisting">Callable<String> callable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Callable<String>() {
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String call() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> someLogic();
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String toString() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"spanNameFromToStringMethod"</span>;
|
|
}
|
|
};
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Manual `TraceCallable` creation with explicit "calculateTax" Span name</span>
|
|
Callable<String> traceCallable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceCallable<>(tracer, spanNamer, callable, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Wrapping `Callable` with `Tracer`. The Span name will be taken either from the</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// `@SpanName` annotation or from `toString` method</span>
|
|
Callable<String> traceCallableFromTracer = tracer.wrap(callable);</pre><p>That way you will ensure that a new Span is created and closed for each execution.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_hystrix" href="#_hystrix"></a>13.2 Hystrix</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_custom_concurrency_strategy" href="#_custom_concurrency_strategy"></a>13.2.1 Custom Concurrency Strategy</h3></div></div></div><p>We’re registering a custom <a class="link" href="https://github.com/Netflix/Hystrix/wiki/Plugins#concurrencystrategy" target="_top"><code class="literal">HystrixConcurrencyStrategy</code></a>
|
|
that wraps all <code class="literal">Callable</code> instances into their Sleuth representative -
|
|
the <code class="literal">TraceCallable</code>. 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 <code class="literal">spring.sleuth.hystrix.strategy.enabled</code> to <code class="literal">false</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_manual_command_setting" href="#_manual_command_setting"></a>13.2.2 Manual Command setting</h3></div></div></div><p>Assuming that you have the following <code class="literal">HystrixCommand</code>:</p><pre class="programlisting">HystrixCommand<String> hystrixCommand = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> HystrixCommand<String>(setter) {
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">protected</span> String run() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> someLogic();
|
|
}
|
|
};</pre><p>In order to pass the tracing information you have to wrap the same logic in the Sleuth version of the <code class="literal">HystrixCommand</code> which is the
|
|
<code class="literal">TraceCommand</code>:</p><pre class="programlisting">TraceCommand<String> traceCommand = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceCommand<String>(tracer, traceKeys, setter) {
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String doRun() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> someLogic();
|
|
}
|
|
};</pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_rxjava" href="#_rxjava"></a>13.3 RxJava</h2></div></div></div><p>We’re registering a custom <a class="link" href="https://github.com/ReactiveX/RxJava/wiki/Plugins#rxjavaschedulershook" target="_top"><code class="literal">RxJavaSchedulersHook</code></a>
|
|
that wraps all <code class="literal">Action0</code> instances into their Sleuth representative -
|
|
the <code class="literal">TraceAction</code>. The hook either starts or continues a span depending on the fact whether tracing was already going
|
|
on before the Action was scheduled. To disable the custom RxJavaSchedulersHook set the <code class="literal">spring.sleuth.rxjava.schedulers.hook.enabled</code> to <code class="literal">false</code>.</p><p>You can define a list of regular expressions for thread names, for which you don’t want a Span to be created. Just provide a comma separated list
|
|
of regular expressions in the <code class="literal">spring.sleuth.rxjava.schedulers.ignoredthreads</code> property.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_http_integration" href="#_http_integration"></a>13.4 HTTP integration</h2></div></div></div><p>Features from this section can be disabled by providing the <code class="literal">spring.sleuth.web.enabled</code> property with value equal to <code class="literal">false</code>.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_http_filter" href="#_http_filter"></a>13.4.1 HTTP Filter</h3></div></div></div><p>Via the <code class="literal">TraceFilter</code> all sampled incoming requests result in creation of a Span. That Span’s name is <code class="literal">http:</code> + the path to which
|
|
the request was sent. E.g. if the request was sent to <code class="literal">/foo/bar</code> then the name will be <code class="literal">http:/foo/bar</code>. You can configure which URIs you would
|
|
like to skip via the <code class="literal">spring.sleuth.web.skipPattern</code> property. If you have <code class="literal">ManagementServerProperties</code> on classpath then
|
|
its value of <code class="literal">contextPath</code> gets appended to the provided skip pattern.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_handlerinterceptor" href="#_handlerinterceptor"></a>13.4.2 HandlerInterceptor</h3></div></div></div><p>Since we want the span names to be precise we’re using a <code class="literal">TraceHandlerInterceptor</code> that either wraps an
|
|
existing <code class="literal">HandlerInterceptor</code> or is added directly to the list of existing <code class="literal">HandlerInterceptors</code>. The
|
|
<code class="literal">TraceHandlerInterceptor</code> adds a special request attribute to the given <code class="literal">HttpServletRequest</code>. If the
|
|
the <code class="literal">TraceFilter</code> doesn’t see this attribute set it will create a "fallback" span which is an additional
|
|
span created on the server side so that the trace is presented properly in the UI. Seeing that most likely
|
|
signifies that there is a missing instrumentation. In that case please file an issue in Spring Cloud Sleuth.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_async_servlet_support" href="#_async_servlet_support"></a>13.4.3 Async Servlet support</h3></div></div></div><p>If your controller returns a <code class="literal">Callable</code> or a <code class="literal">WebAsyncTask</code> Spring Cloud Sleuth will continue the existing span instead of creating a new one.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_http_client_integration" href="#_http_client_integration"></a>13.5 HTTP client integration</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_synchronous_rest_template" href="#_synchronous_rest_template"></a>13.5.1 Synchronous Rest Template</h3></div></div></div><p>We’re injecting a <code class="literal">RestTemplate</code> 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 <code class="literal">RestTemplate</code> features
|
|
just set <code class="literal">spring.sleuth.web.client.enabled</code> to <code class="literal">false</code>.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>You have to register <code class="literal">RestTemplate</code> as a bean so that the interceptors will get injected.
|
|
If you create a <code class="literal">RestTemplate</code> instance with a <code class="literal">new</code> keyword then the instrumentation WILL NOT work.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_asynchronous_rest_template" href="#_asynchronous_rest_template"></a>13.5.2 Asynchronous Rest Template</h3></div></div></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>A traced version of an <code class="literal">AsyncRestTemplate</code> bean is registered for you out of the box. If you
|
|
have your own bean you have to wrap it in a <code class="literal">TraceAsyncRestTemplate</code> representation. The best solution
|
|
is to only customize the <code class="literal">ClientHttpRequestFactory</code> and / or <code class="literal">AsyncClientHttpRequestFactory</code>.
|
|
<span class="strong"><strong>If you have your own <code class="literal">AsyncRestTemplate</code> and you don’t wrap it your calls WILL NOT GET TRACED</strong></span>.</p></td></tr></table></div><p>Custom instrumentation is set to create and close Spans upon sending and receiving requests. You can customize the <code class="literal">ClientHttpRequestFactory</code>
|
|
and the <code class="literal">AsyncClientHttpRequestFactory</code> by registering your beans. Remember to use tracing compatible implementations (e.g. don’t forget to
|
|
wrap <code class="literal">ThreadPoolTaskScheduler</code> in a <code class="literal">TraceAsyncListenableTaskExecutor</code>). Example of custom request factories:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@EnableAutoConfiguration</span></em>
|
|
<em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> TestConfiguration {
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
|
ClientHttpRequestFactory mySyncClientFactory() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> MySyncClientHttpRequestFactory();
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
|
AsyncClientHttpRequestFactory myAsyncClientFactory() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> MyAsyncClientHttpRequestFactory();
|
|
}
|
|
}</pre><p>To block the <code class="literal">AsyncRestTemplate</code> features set <code class="literal">spring.sleuth.web.async.client.enabled</code> to <code class="literal">false</code>.
|
|
To disable creation of the default <code class="literal">TraceAsyncClientHttpRequestFactoryWrapper</code> set <code class="literal">spring.sleuth.web.async.client.factory.enabled</code>
|
|
to <code class="literal">false</code>. If you don’t want to create <code class="literal">AsyncRestClient</code> at all set <code class="literal">spring.sleuth.web.async.client.template.enabled</code> to <code class="literal">false</code>.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_multiple_asynchronous_rest_templates" href="#_multiple_asynchronous_rest_templates"></a>Multiple Asynchronous Rest Templates</h4></div></div></div><p>Sometimes you need to use multiple implementations of Asynchronous Rest Template. In the following snippet you
|
|
can see an example of how to set up such a custom <code class="literal">AsyncRestTemplate</code>.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
|
<em><span class="hl-annotation" style="color: gray">@EnableAutoConfiguration</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> Config {
|
|
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> Tracer tracer;
|
|
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> HttpTraceKeysInjector httpTraceKeysInjector;
|
|
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> HttpSpanInjector spanInjector;
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Bean(name = "customAsyncRestTemplate")</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> AsyncRestTemplate traceAsyncRestTemplate(<em><span class="hl-annotation" style="color: gray">@Qualifier("customHttpRequestFactoryWrapper")</span></em>
|
|
TraceAsyncClientHttpRequestFactoryWrapper wrapper, ErrorParser errorParser) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceAsyncRestTemplate(wrapper, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer, errorParser);
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Bean(name = "customHttpRequestFactoryWrapper")</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> TraceAsyncClientHttpRequestFactoryWrapper traceAsyncClientHttpRequestFactory() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceAsyncClientHttpRequestFactoryWrapper(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.spanInjector,
|
|
asyncClientFactory(),
|
|
clientHttpRequestFactory(),
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.httpTraceKeysInjector);
|
|
}
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> ClientHttpRequestFactory clientHttpRequestFactory() {
|
|
ClientHttpRequestFactory clientHttpRequestFactory = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CustomClientHttpRequestFactory();
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//CUSTOMIZE HERE</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> clientHttpRequestFactory;
|
|
}
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> AsyncClientHttpRequestFactory asyncClientFactory() {
|
|
AsyncClientHttpRequestFactory factory = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CustomAsyncClientHttpRequestFactory();
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//CUSTOMIZE HERE</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> factory;
|
|
}
|
|
}</pre></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_traverson" href="#_traverson"></a>13.5.3 Traverson</h3></div></div></div><p>If you’re using the <a class="link" href="http://docs.spring.io/spring-hateoas/docs/current/reference/html/#client.traverson" target="_top">Traverson</a> library
|
|
it’s enough for you to inject a <code class="literal">RestTemplate</code> as a bean into your Traverson object. Since <code class="literal">RestTemplate</code>
|
|
is already intercepted, you will get full support of tracing in your client. Below you can find a pseudo code
|
|
of how to do that:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Autowired</span></em> RestTemplate restTemplate;
|
|
|
|
Traverson traverson = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Traverson(URI.create(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"http://some/address"</span>),
|
|
MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// use Traverson</span></pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_feign" href="#_feign"></a>13.6 Feign</h2></div></div></div><p>By default Spring Cloud Sleuth provides integration with feign via the <code class="literal">TraceFeignClientAutoConfiguration</code>. You can disable it entirely
|
|
by setting <code class="literal">spring.sleuth.feign.enabled</code> to false. If you do so then no Feign related instrumentation will take place.</p><p>Part of Feign instrumentation is done via a <code class="literal">FeignBeanPostProcessor</code>. You can disable it by providing the <code class="literal">spring.sleuth.feign.processor.enabled</code> equal to <code class="literal">false</code>.
|
|
If you set it like this then Spring Cloud Sleuth will not instrument any of your custom Feign components. All the default instrumentation
|
|
however will be still there.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_asynchronous_communication" href="#_asynchronous_communication"></a>13.7 Asynchronous communication</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="__async_annotated_methods" href="#__async_annotated_methods"></a>13.7.1 @Async annotated methods</h3></div></div></div><p>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 <code class="literal">spring.sleuth.async.enabled</code> to <code class="literal">false</code>.</p><p>If you annotate your method with <code class="literal">@Async</code> then we’ll automatically create a new Span with the following characteristics:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">if the method is annotated with <code class="literal">@SpanName</code> then the value of the annotation will be the Span’s name</li><li class="listitem">if the method is <span class="strong"><strong>not</strong></span> annotated with <code class="literal">@SpanName</code> the Span name will be the annotated method name</li><li class="listitem">the Span will be tagged with that method’s class name and the method name too</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="__scheduled_annotated_methods" href="#__scheduled_annotated_methods"></a>13.7.2 @Scheduled annotated methods</h3></div></div></div><p>In Spring Cloud Sleuth we’re instrumenting scheduled method execution so that the tracing information is passed between threads. You can disable this behaviour
|
|
by setting the value of <code class="literal">spring.sleuth.scheduled.enabled</code> to <code class="literal">false</code>.</p><p>If you annotate your method with <code class="literal">@Scheduled</code> then we’ll automatically create a new Span with the following characteristics:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">the Span name will be the annotated method name</li><li class="listitem">the Span will be tagged with that method’s class name and the method name too</li></ul></div><p>If you want to skip Span creation for some <code class="literal">@Scheduled</code> annotated classes you can set the
|
|
<code class="literal">spring.sleuth.scheduled.skipPattern</code> with a regular expression that will match the fully qualified name of the
|
|
<code class="literal">@Scheduled</code> annotated class.</p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>If you are using <code class="literal">spring-cloud-sleuth-stream</code> and <code class="literal">spring-cloud-netflix-hystrix-stream</code> together, Span will be created for each Hystrix metrics and sent to Zipkin. This may be annoying. You can prevent this by setting <code class="literal">spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask</code></p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_executor_executorservice_and_scheduledexecutorservice" href="#_executor_executorservice_and_scheduledexecutorservice"></a>13.7.3 Executor, ExecutorService and ScheduledExecutorService</h3></div></div></div><p>We’re providing <code class="literal">LazyTraceExecutor</code>, <code class="literal">TraceableExecutorService</code> and <code class="literal">TraceableScheduledExecutorService</code>. Those implementations
|
|
are creating Spans each time a new task is submitted, invoked or scheduled.</p><p>Here you can see an example of how to pass tracing information with <code class="literal">TraceableExecutorService</code> when working with <code class="literal">CompletableFuture</code>:</p><pre class="programlisting">CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// perform some logic</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span class="hl-number">1</span>_<span class="hl-number">000</span>_<span class="hl-number">000L</span>;
|
|
}, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceableExecutorService(executorService,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// 'calculateTax' explicitly names the span - this param is optional</span>
|
|
tracer, traceKeys, spanNamer, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>));</pre><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>Sleuth doesn’t work with <code class="literal">parallelStream()</code> out of the box. If you want
|
|
to have the tracing information propagated through the stream you have to use the
|
|
approach with <code class="literal">supplyAsync(...)</code> as presented above.</p></td></tr></table></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_customization_of_executors" href="#_customization_of_executors"></a>Customization of Executors</h4></div></div></div><p>Sometimes you need to set up a custom instance of the <code class="literal">AsyncExecutor</code>. In the following snippet you
|
|
can see an example of how to set up such a custom <code class="literal">Executor</code>.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
|
<em><span class="hl-annotation" style="color: gray">@EnableAutoConfiguration</span></em>
|
|
<em><span class="hl-annotation" style="color: gray">@EnableAsync</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomExecutorConfig <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">extends</span> AsyncConfigurerSupport {
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> BeanFactory beanFactory;
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Executor getAsyncExecutor() {
|
|
ThreadPoolTaskExecutor executor = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> ThreadPoolTaskExecutor();
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// CUSTOMIZE HERE</span>
|
|
executor.setCorePoolSize(<span class="hl-number">7</span>);
|
|
executor.setMaxPoolSize(<span class="hl-number">42</span>);
|
|
executor.setQueueCapacity(<span class="hl-number">11</span>);
|
|
executor.setThreadNamePrefix(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"MyExecutor-"</span>);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// DON'T FORGET TO INITIALIZE</span>
|
|
executor.initialize();
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> LazyTraceExecutor(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.beanFactory, executor);
|
|
}
|
|
}</pre></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_messaging" href="#_messaging"></a>13.8 Messaging</h2></div></div></div><p>Spring Cloud Sleuth integrates with <a class="link" href="http://projects.spring.io/spring-integration/" target="_top">Spring Integration</a>. It creates spans for publish and
|
|
subscribe events. To disable Spring Integration instrumentation, set <code class="literal">spring.sleuth.integration.enabled</code> to false.</p><p>You can provide the <code class="literal">spring.sleuth.integration.patterns</code> pattern to explicitly
|
|
provide the names of channels that you want to include for tracing. By default all channels
|
|
are included.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>When using the <code class="literal">Executor</code> to build a Spring Integration <code class="literal">IntegrationFlow</code> remember to use the <span class="strong"><strong>untraced</strong></span> version of the <code class="literal">Executor</code>.
|
|
Decorating Spring Integration Executor Channel with <code class="literal">TraceableExecutorService</code> will cause the spans to be improperly closed.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_zuul" href="#_zuul"></a>13.9 Zuul</h2></div></div></div><p>We’re registering Zuul filters to propagate the tracing information (the request header is enriched with tracing data).
|
|
To disable Zuul support set the <code class="literal">spring.sleuth.zuul.enabled</code> property to <code class="literal">false</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_spring_cloud_function" href="#_spring_cloud_function"></a>13.10 Spring Cloud Function</h2></div></div></div><p>Sleuth works out of the box with Spring Cloud Function. Since functions
|
|
might be short living, it’s best to make the Zipkin span reporting synchronous.
|
|
Just define a <code class="literal">Reporter<Span></code> bean as presented below:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> ReporterConfiguration {
|
|
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Reporter<Span> reporter(
|
|
SpanMetricReporter spanMetricReporter,
|
|
ZipkinProperties zipkin,
|
|
Sender sender
|
|
) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> AsyncReporter<Span> reporter = AsyncReporter.builder(sender)
|
|
.queuedMaxSpans(<span class="hl-number">1000</span>)
|
|
.messageTimeout(zipkin.getMessageTimeout(), TimeUnit.SECONDS)
|
|
.metrics(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> ReporterMetricsAdapter(spanMetricReporter))
|
|
.build(zipkin.getEncoder());
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Reporter<Span>() {
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> report(Span span) {
|
|
reporter.report(span);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// make the reporter synchronous</span>
|
|
reporter.flush();
|
|
}
|
|
};
|
|
}
|
|
}</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__metrics.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__running_examples.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12. Metrics </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 14. Running examples</td></tr></table></div></body></html> |