From 9dc626a873812953b79e04e2f214ee6713ee1c14 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 18 Apr 2017 14:45:07 +0200 Subject: [PATCH] Added docs for custom async rest template (#566) fixes #564 --- README.adoc | 12 +- .../main/asciidoc/spring-cloud-sleuth.adoc | 10 ++ .../async/MultipleAsyncRestTemplateTests.java | 122 ++++++++++++++++++ 3 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java diff --git a/README.adoc b/README.adoc index 6dba687a5..61e227793 100644 --- a/README.adoc +++ b/README.adoc @@ -2,8 +2,8 @@ :jdkversion: 1.8 -image::https://circleci.com/gh/spring-cloud/spring-cloud-sleuth/tree/1.0.x.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-sleuth/tree/1.0.x"] -image::https://codecov.io/gh/spring-cloud/spring-cloud-sleuth/branch/1.0.x/graph/badge.svg["codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-sleuth"] +image::https://circleci.com/gh/spring-cloud/spring-cloud-sleuth/tree/1.1.x.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-sleuth/tree/1.1.x"] +image::https://codecov.io/gh/spring-cloud/spring-cloud-sleuth/branch/1.1.x/graph/badge.svg["codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-sleuth"] image::https://badges.gitter.im/spring-cloud/spring-cloud-sleuth.svg[Gitter, link="https://gitter.im/spring-cloud/spring-cloud-sleuth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] == Spring Cloud Sleuth @@ -194,8 +194,9 @@ Below you can find an example of a Logback configuration (file named https://git ​ + + value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> @@ -256,7 +257,8 @@ Below you can find an example of a Logback configuration (file named https://git ​ - + + @@ -561,7 +563,7 @@ IMPORTANT: If using Zipkin or Stream, configure the percentage of spans exported NOTE: the SLF4J MDC is always set and logback users will immediately see the trace and span ids in logs per the example above. Other logging systems have to configure their own formatter to get the same result. The default is - `logging.pattern.level` set to `%clr(%5p) %clr([${spring.application.name:},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]){yellow}` + `logging.pattern.level` set to `%5p [${spring.zipkin.service.name:${spring.application.name:-}},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]` (this is a Spring Boot feature for logback users). *This means that if you're not using SLF4J this pattern WILL NOT be automatically applied*. diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc index b2219fb10..480d3427d 100644 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc @@ -536,6 +536,16 @@ To block the `AsyncRestTemplate` features set `spring.sleuth.web.async.client.en To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper` set `spring.sleuth.web.async.client.factory.enabled` to `false`. If you don't want to create `AsyncRestClient` at all set `spring.sleuth.web.async.client.template.enabled` to `false`. +===== Multiple Asynchronous Rest Templates + +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 `AsyncRestTemplate`. + +[source,java] +---- +include::../../../../spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java[tags=custom_async_rest_template,indent=0] +---- + === Feign By default Spring Cloud Sleuth provides integration with feign via the `TraceFeignClientAutoConfiguration`. You can disable it entirely diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java new file mode 100644 index 000000000..073b2ff6c --- /dev/null +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java @@ -0,0 +1,122 @@ +/* + * Copyright 2013-2016 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 + * + * http://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.instrument.async; + +import java.io.IOException; +import java.net.URI; +import java.util.concurrent.Executor; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.sleuth.SpanInjector; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; +import org.springframework.cloud.sleuth.instrument.web.client.TraceAsyncClientHttpRequestFactoryWrapper; +import org.springframework.cloud.sleuth.instrument.web.client.TraceAsyncRestTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.AsyncClientHttpRequest; +import org.springframework.http.client.AsyncClientHttpRequestFactory; +import org.springframework.http.client.ClientHttpRequest; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.AsyncRestTemplate; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = MultipleAsyncRestTemplateTests.Config.class, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class MultipleAsyncRestTemplateTests { + + @Autowired @Qualifier("customAsyncRestTemplate") AsyncRestTemplate asyncRestTemplate; + + @Test + public void should_start_context_with_custom_async_client() throws Exception { + then(this.asyncRestTemplate).isNotNull(); + } + + //tag::custom_async_rest_template[] + @Configuration + @EnableAutoConfiguration + static class Config { + @Autowired Tracer tracer; + @Autowired HttpTraceKeysInjector httpTraceKeysInjector; + @Autowired SpanInjector spanInjector; + + @Bean(name = "customAsyncRestTemplate") + public AsyncRestTemplate traceAsyncRestTemplate(@Qualifier("customHttpRequestFactoryWrapper") + TraceAsyncClientHttpRequestFactoryWrapper wrapper) { + return new TraceAsyncRestTemplate(wrapper, this.tracer); + } + + @Bean(name = "customHttpRequestFactoryWrapper") + public TraceAsyncClientHttpRequestFactoryWrapper traceAsyncClientHttpRequestFactory() { + return new TraceAsyncClientHttpRequestFactoryWrapper(this.tracer, + this.spanInjector, + asyncClientFactory(), + clientHttpRequestFactory(), + this.httpTraceKeysInjector); + } + + private ClientHttpRequestFactory clientHttpRequestFactory() { + ClientHttpRequestFactory clientHttpRequestFactory = new CustomClientHttpRequestFactory(); + //CUSTOMIZE HERE + return clientHttpRequestFactory; + } + + private AsyncClientHttpRequestFactory asyncClientFactory() { + AsyncClientHttpRequestFactory factory = new CustomAsyncClientHttpRequestFactory(); + //CUSTOMIZE HERE + return factory; + } + } + //end::custom_async_rest_template[] +} + +class CustomClientHttpRequestFactory implements ClientHttpRequestFactory { + + @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) + throws IOException { + return null; + } +} + +class CustomAsyncClientHttpRequestFactory implements AsyncClientHttpRequestFactory { + + @Override + public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) + throws IOException { + return null; + } +} + +class YourCustomThreadPoolTaskExecutor implements Executor { + + @Override public void execute(Runnable command) { + + } +} \ No newline at end of file