auto-config for zipkin support for spring mvc and restTemplate
This commit is contained in:
11
pom.xml
11
pom.xml
@@ -58,6 +58,11 @@
|
||||
<artifactId>brave-client</artifactId>
|
||||
<version>${brave.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-impl</artifactId>
|
||||
<version>${brave.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-impl-spring</artifactId>
|
||||
@@ -72,6 +77,12 @@
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-tracefilters</artifactId>
|
||||
<version>${brave.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package org.springframework.cloud.sleuth.sample;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -17,19 +22,43 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@Slf4j
|
||||
public class SampleApplication {
|
||||
public class SampleApplication implements ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
|
||||
public static final String CLIENT_NAME = "testApp";
|
||||
|
||||
@Autowired
|
||||
Environment env;
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
private int port;
|
||||
|
||||
@RequestMapping("/")
|
||||
@SneakyThrows
|
||||
@RequestMapping("/")
|
||||
public String hi() {
|
||||
return "hi";
|
||||
final Random random = new Random();
|
||||
Thread.sleep(random.nextInt(1000));
|
||||
|
||||
String s = restTemplate.getForObject("http://localhost:" + port + "/hi2", String.class);
|
||||
return "hi/"+s;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@RequestMapping("/hi2")
|
||||
public String hi2() {
|
||||
final Random random = new Random();
|
||||
Thread.sleep(random.nextInt(1000));
|
||||
return "hi2";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SampleApplication.class, args);
|
||||
}
|
||||
|
||||
/*@Bean
|
||||
public SpanCollector spanCollector() {
|
||||
return new LoggingSpanCollectorImpl();
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
|
||||
port = event.getEmbeddedServletContainer().getPort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
server:
|
||||
port: 8080
|
||||
port: 3380
|
||||
|
||||
spring:
|
||||
application:
|
||||
|
||||
@@ -24,6 +24,27 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-impl-spring</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-tracefilters</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-zipkin-spancollector</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
||||
@@ -1,12 +1,86 @@
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.github.kristofa.brave.zipkin.ZipkinSpanCollector;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.github.kristofa.brave.AnnotationSubmitterConfig;
|
||||
import com.github.kristofa.brave.ClientTracer;
|
||||
import com.github.kristofa.brave.ClientTracerConfig;
|
||||
import com.github.kristofa.brave.EndPointSubmitterConfig;
|
||||
import com.github.kristofa.brave.FixedSampleRateTraceFilter;
|
||||
import com.github.kristofa.brave.LoggingSpanCollectorImpl;
|
||||
import com.github.kristofa.brave.ServerSpanThreadBinderConfig;
|
||||
import com.github.kristofa.brave.ServerTracerConfig;
|
||||
import com.github.kristofa.brave.SpanCollector;
|
||||
import com.github.kristofa.brave.TraceFilter;
|
||||
import com.github.kristofa.brave.TraceFilters;
|
||||
import com.github.kristofa.brave.client.ClientRequestInterceptor;
|
||||
import com.github.kristofa.brave.client.ClientResponseInterceptor;
|
||||
import com.github.kristofa.brave.client.spanfilter.SpanNameFilter;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(ServerTracerConfig.class)
|
||||
@Import({ AnnotationSubmitterConfig.class, ClientTracerConfig.class,
|
||||
EndPointSubmitterConfig.class, ServerSpanThreadBinderConfig.class,
|
||||
ServerTracerConfig.class })
|
||||
public class ZipkinAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SpanCollector spanCollector() {
|
||||
return new ZipkinSpanCollector(zipkinProperties().getHost(),
|
||||
zipkinProperties().getPort());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ZipkinProperties zipkinProperties() {
|
||||
return new ZipkinProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FixedSampleRateTraceFilter fixedSampleRateTraceFilter() {
|
||||
return new FixedSampleRateTraceFilter(zipkinProperties().getFixedSampleRate());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TraceFilters traceFilters(List<TraceFilter> traceFilters) {
|
||||
return new TraceFilters(traceFilters);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class InterceptorConfig {
|
||||
|
||||
@Autowired
|
||||
private ClientTracer clientTracer;
|
||||
|
||||
@Autowired(required = false)
|
||||
private SpanNameFilter spanNameFilter;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ClientRequestInterceptor clientRequestInterceptor() {
|
||||
return new ClientRequestInterceptor(clientTracer,
|
||||
Optional.fromNullable(spanNameFilter));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ClientResponseInterceptor clientResponseInterceptor() {
|
||||
return new ClientResponseInterceptor(clientTracer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import static com.github.kristofa.brave.BraveHttpHeaders.*;
|
||||
|
||||
import com.github.kristofa.brave.EndPointSubmitter;
|
||||
import com.github.kristofa.brave.IdConversion;
|
||||
import com.github.kristofa.brave.ServerTracer;
|
||||
import lombok.Data;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@CommonsLog
|
||||
public class ZipkinHandlerInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final EndPointSubmitter endPointSubmitter;
|
||||
private final ServerTracer serverTracer;
|
||||
|
||||
public ZipkinHandlerInterceptor(EndPointSubmitter endPointSubmitter, ServerTracer serverTracer) {
|
||||
this.endPointSubmitter = endPointSubmitter;
|
||||
this.serverTracer = serverTracer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
submitEndpoint(request);
|
||||
|
||||
serverTracer.clearCurrentSpan();
|
||||
final TraceData traceData = getTraceData(request);
|
||||
|
||||
if (Boolean.FALSE.equals(traceData.getShouldBeSampled())) {
|
||||
serverTracer.setStateNoTracing();
|
||||
log.debug("Received indication that we should NOT trace.");
|
||||
} else {
|
||||
final String spanName = getSpanName(request, traceData);
|
||||
if (traceData.getTraceId() != null && traceData.getSpanId() != null) {
|
||||
|
||||
log.debug("Received span information as part of request.");
|
||||
serverTracer.setStateCurrentTrace(traceData.getTraceId(), traceData.getSpanId(),
|
||||
traceData.getParentSpanId(), spanName);
|
||||
} else {
|
||||
log.debug("Received no span state.");
|
||||
serverTracer.setStateUnknown(spanName);
|
||||
}
|
||||
serverTracer.setServerReceived();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
|
||||
// We can submit this in any case. When server state is not set or
|
||||
// we should not trace this request nothing will happen.
|
||||
log.debug("Sending server send.");
|
||||
try {
|
||||
serverTracer.setServerSend();
|
||||
} finally {
|
||||
serverTracer.clearCurrentSpan();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
}
|
||||
|
||||
private void submitEndpoint(HttpServletRequest servletRequest) {
|
||||
if (!endPointSubmitter.endPointSubmitted()) {
|
||||
final String localAddr = servletRequest.getLocalAddr();
|
||||
final int localPort = servletRequest.getLocalPort();
|
||||
final String contextPath = servletRequest.getContextPath();
|
||||
log.debug("Setting endpoint: addr: "+localAddr+", port: "+localPort+", contextpath: "+ contextPath);
|
||||
endPointSubmitter.submit(localAddr, localPort, contextPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private TraceData getTraceData(final HttpServletRequest request) {
|
||||
ServletServerHttpRequest req = new ServletServerHttpRequest(request);
|
||||
HttpHeaders headers = req.getHeaders();
|
||||
|
||||
TraceData traceData = new TraceData();
|
||||
|
||||
for (Map.Entry<String, List<String>> headerEntry : headers.entrySet()) {
|
||||
log.debug(headerEntry.getKey() +" = "+ headerEntry.getValue());
|
||||
if (TraceId.getName().equalsIgnoreCase(headerEntry.getKey())) {
|
||||
traceData.setTraceId(getFirstLong(headerEntry));
|
||||
} else if (SpanId.getName().equalsIgnoreCase(headerEntry.getKey())) {
|
||||
traceData.setSpanId(getFirstLong(headerEntry));
|
||||
} else if (ParentSpanId.getName().equalsIgnoreCase(headerEntry.getKey())) {
|
||||
traceData.setParentSpanId(getFirstLong(headerEntry));
|
||||
} else if (Sampled.getName().equalsIgnoreCase(headerEntry.getKey())) {
|
||||
traceData.setShouldBeSampled(getFirstBoolean(headerEntry));
|
||||
} else if (SpanName.getName().equalsIgnoreCase(headerEntry.getKey())) {
|
||||
traceData.setSpanName(getFirstString(headerEntry));
|
||||
}
|
||||
}
|
||||
return traceData;
|
||||
}
|
||||
|
||||
private String getSpanName(final HttpServletRequest request, final TraceData traceData) {
|
||||
if (StringUtils.isNotBlank(traceData.getSpanName())) {
|
||||
return traceData.getSpanName();
|
||||
} else {
|
||||
//TODO: what is the functional equivalent of resteasy request.getPreprocessedPath();
|
||||
UriComponents components = UriComponentsBuilder.fromUriString(request.getRequestURL().toString()).build();
|
||||
StringBuilder preprocessedPath = new StringBuilder();
|
||||
for (String segment : components.getPathSegments()) {
|
||||
preprocessedPath.append("/").append(segment);
|
||||
}
|
||||
if (preprocessedPath.length() == 0) {
|
||||
preprocessedPath.append("/");
|
||||
}
|
||||
return preprocessedPath.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private Long getFirstLong(final Map.Entry<String, List<String>> headerEntry) {
|
||||
final String value = getFirstString(headerEntry);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return IdConversion.convertToLong(value);
|
||||
|
||||
}
|
||||
|
||||
private Boolean getFirstBoolean(final Map.Entry<String, List<String>> headerEntry) {
|
||||
final String firstStringValueFor = getFirstString(headerEntry);
|
||||
return firstStringValueFor == null ? null : Boolean.valueOf(firstStringValueFor);
|
||||
}
|
||||
|
||||
private String getFirstString(final Map.Entry<String, List<String>> headerEntry) {
|
||||
final List<String> values = headerEntry.getValue();
|
||||
if (values != null && values.size() > 0) {
|
||||
return headerEntry.getValue().get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Data
|
||||
class TraceData {
|
||||
private Long traceId;
|
||||
private Long spanId;
|
||||
private Long parentSpanId;
|
||||
private Boolean shouldBeSampled;
|
||||
private String spanName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.sleuth.zipkin")
|
||||
@Data
|
||||
public class ZipkinProperties {
|
||||
// Sample rate = 1 means every request will get traced.
|
||||
private int fixedSampleRate = 1;
|
||||
private String host = "localhost";
|
||||
private int port = 9410;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import com.github.kristofa.brave.BraveHttpHeaders;
|
||||
import com.github.kristofa.brave.ClientRequestAdapter;
|
||||
import com.github.kristofa.brave.ClientResponseAdapter;
|
||||
import com.github.kristofa.brave.client.ClientRequestInterceptor;
|
||||
import com.github.kristofa.brave.client.ClientResponseInterceptor;
|
||||
import com.google.common.base.Optional;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ZipkinRestTemplateInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private final ClientRequestInterceptor clientRequestInterceptor;
|
||||
private final ClientResponseInterceptor clientResponseInterceptor;
|
||||
|
||||
public ZipkinRestTemplateInterceptor(ClientRequestInterceptor clientRequestInterceptor, ClientResponseInterceptor clientResponseInterceptor) {
|
||||
this.clientRequestInterceptor = clientRequestInterceptor;
|
||||
//TODO: ClientResponseInterceptor assumes >= 300 is error
|
||||
this.clientResponseInterceptor = clientResponseInterceptor;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
|
||||
|
||||
clientRequestInterceptor.handle(new RequestAdapter(request), Optional.<String>absent());
|
||||
|
||||
ClientHttpResponse response = null;
|
||||
Exception exception = null;
|
||||
try {
|
||||
response = execution.execute(request, body);
|
||||
} catch (final Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
clientResponseInterceptor.handle(new ResponseAdapter(response));
|
||||
if(exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
class RequestAdapter implements ClientRequestAdapter {
|
||||
|
||||
HttpRequest request;
|
||||
|
||||
public RequestAdapter(HttpRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return request.getURI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return request.getMethod().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getSpanName() {
|
||||
String spanNameHeader = request.getHeaders().getFirst(BraveHttpHeaders.SpanName.getName());
|
||||
return Optional.fromNullable(spanNameHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHeader(String header, String value) {
|
||||
request.getHeaders().add(header, value);
|
||||
}
|
||||
}
|
||||
|
||||
class ResponseAdapter implements ClientResponseAdapter {
|
||||
ClientHttpResponse response;
|
||||
|
||||
public ResponseAdapter(ClientHttpResponse response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
if (response == null) {
|
||||
return 0;
|
||||
}
|
||||
return response.getRawStatusCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package org.springframework.cloud.sleuth.zipkin.web;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.cloud.sleuth.zipkin.ZipkinAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.zipkin.ZipkinHandlerInterceptor;
|
||||
import org.springframework.cloud.sleuth.zipkin.ZipkinRestTemplateInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
import com.github.kristofa.brave.EndPointSubmitter;
|
||||
import com.github.kristofa.brave.ServerTracer;
|
||||
import com.github.kristofa.brave.ServerTracerConfig;
|
||||
import com.github.kristofa.brave.client.ClientRequestInterceptor;
|
||||
import com.github.kristofa.brave.client.ClientResponseInterceptor;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(ServerTracerConfig.class)
|
||||
@ConditionalOnWebApplication
|
||||
@AutoConfigureAfter(ZipkinAutoConfiguration.class)
|
||||
public class ZipkinWebAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private EndPointSubmitter endPointSubmitter;
|
||||
|
||||
@Autowired
|
||||
private ServerTracer serverTracer;
|
||||
|
||||
@Bean
|
||||
public ZipkinHandlerInterceptor zipkinHandlerInterceptor() {
|
||||
return new ZipkinHandlerInterceptor(endPointSubmitter, serverTracer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
|
||||
return new ZipkinWebConfigurer(zipkinHandlerInterceptor());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class RestTemplateConfig {
|
||||
|
||||
@Autowired
|
||||
private ClientRequestInterceptor clientRequestInterceptor;
|
||||
|
||||
@Autowired
|
||||
private ClientResponseInterceptor clientResponseInterceptor;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RestTemplate restTemplate() {
|
||||
//TODO: howto add this to an existing restTemplate without circular dependencies
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.getInterceptors().add(zipkinRestTemplateInterceptor());
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ZipkinRestTemplateInterceptor zipkinRestTemplateInterceptor() {
|
||||
return new ZipkinRestTemplateInterceptor(clientRequestInterceptor,
|
||||
clientResponseInterceptor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class ZipkinWebConfigurer extends WebMvcConfigurerAdapter {
|
||||
private ZipkinHandlerInterceptor interceptor;
|
||||
|
||||
public ZipkinWebConfigurer(ZipkinHandlerInterceptor interceptor) {
|
||||
this.interceptor = interceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(interceptor).addPathPatterns("/**");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
# Auto Configuration
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.sleuth.zipkin.ZipkinAutoConfiguration
|
||||
org.springframework.cloud.sleuth.zipkin.ZipkinAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.zipkin.web.ZipkinWebAutoConfiguration
|
||||
|
||||
Reference in New Issue
Block a user