committed by
GitHub
parent
e9ee0ba686
commit
e6b78d267f
1
pom.xml
1
pom.xml
@@ -47,6 +47,7 @@
|
||||
<modules>
|
||||
<module>spring-cloud-sleuth-dependencies</module>
|
||||
<module>spring-cloud-sleuth-core</module>
|
||||
<module>tests</module>
|
||||
<module>spring-cloud-sleuth-zipkin</module>
|
||||
<module>spring-cloud-starter-sleuth</module>
|
||||
<module>spring-cloud-starter-zipkin</module>
|
||||
|
||||
@@ -96,6 +96,12 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
@@ -151,6 +157,12 @@
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
@@ -252,13 +264,19 @@
|
||||
<groupId>io.github.lognet</groupId>
|
||||
<artifactId>grpc-spring-boot-starter</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.brave</groupId>
|
||||
<artifactId>brave-instrumentation-grpc</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Instrumentation of Lettcuce -->
|
||||
<!-- Instrumentation of Lettuce -->
|
||||
<dependency>
|
||||
<groupId>io.lettuce</groupId>
|
||||
<artifactId>lettuce-core</artifactId>
|
||||
@@ -279,6 +297,12 @@
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
@@ -301,50 +325,11 @@
|
||||
<artifactId>JUnitParams</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-activemq</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- to test DefaultJcaListenerContainerFactory -->
|
||||
<dependency>
|
||||
<groupId>javax.resource</groupId>
|
||||
<artifactId>javax.resource-api</artifactId>
|
||||
<version>1.7.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-ra</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- This forces the guava version to 20 within the test scope, which is required by GRPC -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>20.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
|
||||
@@ -18,10 +18,12 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import brave.http.HttpTracing;
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
/**
|
||||
@@ -33,18 +35,36 @@ class LazyClient implements Client {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
private final Client delegate;
|
||||
private Client delegate;
|
||||
|
||||
private TraceFeignObjectWrapper wrapper;
|
||||
|
||||
LazyClient(BeanFactory beanFactory, Client delegate) {
|
||||
LazyClient(BeanFactory beanFactory, Client client) {
|
||||
this.beanFactory = beanFactory;
|
||||
this.delegate = client;
|
||||
}
|
||||
|
||||
LazyClient(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
return ((Client) wrapper().wrap(this.delegate)).execute(request, options);
|
||||
return ((Client) wrapper().wrap(delegate())).execute(request, options);
|
||||
}
|
||||
|
||||
private Client delegate() {
|
||||
if (this.delegate == null) {
|
||||
try {
|
||||
this.delegate = this.beanFactory.getBean(Client.class);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
this.delegate = TracingFeignClient.create(
|
||||
beanFactory.getBean(HttpTracing.class),
|
||||
new Client.Default(null, null));
|
||||
}
|
||||
}
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
private TraceFeignObjectWrapper wrapper() {
|
||||
|
||||
@@ -42,8 +42,7 @@ final class SleuthFeignBuilder {
|
||||
|
||||
private static Client client(BeanFactory beanFactory) {
|
||||
try {
|
||||
Client client = beanFactory.getBean(Client.class);
|
||||
return new LazyClient(beanFactory, client);
|
||||
return new LazyClient(beanFactory);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
return TracingFeignClient.create(beanFactory.getBean(HttpTracing.class),
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.springframework.cloud.sleuth.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
@@ -40,7 +43,6 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@@ -712,3 +714,52 @@ public class SleuthSpanCreatorAspectMonoTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from Spring Data
|
||||
*/
|
||||
final class Pair<S, T> {
|
||||
|
||||
private final S first;
|
||||
|
||||
private final T second;
|
||||
|
||||
Pair(S first, T second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public static <S, T> Pair<S, T> of(S first, T second) {
|
||||
return new Pair<>(first, second);
|
||||
}
|
||||
|
||||
public S getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public T getSecond() {
|
||||
return second;
|
||||
}
|
||||
|
||||
public static <S, T> Collector<Pair<S, T>, ?, Map<S, T>> toMap() {
|
||||
return Collectors.toMap(Pair::getFirst, Pair::getSecond);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Pair<?, ?> pair = (Pair<?, ?>) o;
|
||||
return Objects.equals(first, pair.first) && Objects.equals(second, pair.second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(first, second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.messaging;
|
||||
|
||||
import brave.Tracing;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.support.ChannelInterceptor;
|
||||
|
||||
public class TracingChannelInterceptorAutowireTest {
|
||||
|
||||
@Test
|
||||
public void autowiredWithBeanConfig() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(TracingConfiguration.class);
|
||||
ctx.register(TracingChannelInterceptor.class);
|
||||
ctx.refresh();
|
||||
|
||||
ctx.getBean(ChannelInterceptor.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
Tracing.current().close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TracingConfiguration {
|
||||
|
||||
@Bean
|
||||
Tracing tracing() {
|
||||
return Tracing.newBuilder().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,571 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.web;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import brave.Span;
|
||||
import brave.Tracer;
|
||||
import brave.sampler.Sampler;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.actuate.trace.http.HttpTrace;
|
||||
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.sleuth.DisableWebFluxSecurity;
|
||||
import org.springframework.cloud.sleuth.annotation.ContinueSpan;
|
||||
import org.springframework.cloud.sleuth.annotation.NewSpan;
|
||||
import org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfigurationAccessorConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.web.client.TraceWebClientAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
@NotThreadSafe
|
||||
public class TraceWebFluxTests {
|
||||
|
||||
public static final String EXPECTED_TRACE_ID = "b919095138aa4c6e";
|
||||
|
||||
@Test
|
||||
public void should_instrument_web_filter() throws Exception {
|
||||
// setup
|
||||
TraceReactorAutoConfigurationAccessorConfiguration.close();
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder(
|
||||
TraceWebFluxTests.Config.class)
|
||||
.web(WebApplicationType.REACTIVE)
|
||||
.properties("server.port=0", "spring.jmx.enabled=false",
|
||||
"spring.sleuth.web.skipPattern=/skipped",
|
||||
"spring.application.name=TraceWebFluxTests",
|
||||
"security.basic.enabled=false",
|
||||
"management.security.enabled=false")
|
||||
.run();
|
||||
ArrayListSpanReporter accumulator = context.getBean(ArrayListSpanReporter.class);
|
||||
int port = context.getBean(Environment.class).getProperty("local.server.port",
|
||||
Integer.class);
|
||||
Controller2 controller2 = context.getBean(Controller2.class);
|
||||
clean(accumulator, controller2);
|
||||
|
||||
// when
|
||||
ClientResponse response = whenRequestIsSent(port);
|
||||
// then
|
||||
thenSpanWasReportedWithTags(accumulator, response);
|
||||
clean(accumulator, controller2);
|
||||
|
||||
// when
|
||||
ClientResponse functionResponse = whenRequestIsSentToFunction(port);
|
||||
// then
|
||||
thenSpanWasReportedForFunction(accumulator, functionResponse);
|
||||
accumulator.clear();
|
||||
|
||||
// when
|
||||
ClientResponse nonSampledResponse = whenNonSampledRequestIsSent(port);
|
||||
// then
|
||||
thenNoSpanWasReported(accumulator, nonSampledResponse, controller2);
|
||||
accumulator.clear();
|
||||
|
||||
// when
|
||||
ClientResponse skippedPatternResponse = whenRequestIsSentToSkippedPattern(port);
|
||||
// then
|
||||
thenNoSpanWasReported(accumulator, skippedPatternResponse, controller2);
|
||||
|
||||
// some other tests
|
||||
SleuthSpanCreatorAspectWebFlux bean = context
|
||||
.getBean(SleuthSpanCreatorAspectWebFlux.class);
|
||||
bean.setPort(port);
|
||||
|
||||
// then
|
||||
bean.shouldContinueSpanInWebFlux();
|
||||
bean.shouldCreateNewSpanInWebFlux();
|
||||
bean.shouldCreateNewSpanInWebFluxInSubscriberContext();
|
||||
bean.shouldReturnSpanFromWebFluxSubscriptionContext();
|
||||
bean.shouldReturnSpanFromWebFluxTraceContext();
|
||||
bean.shouldSetupCorrectSpanInHttpTrace();
|
||||
|
||||
// cleanup
|
||||
context.close();
|
||||
TraceReactorAutoConfigurationAccessorConfiguration.close();
|
||||
}
|
||||
|
||||
private void clean(ArrayListSpanReporter accumulator, Controller2 controller2) {
|
||||
accumulator.clear();
|
||||
controller2.span = null;
|
||||
}
|
||||
|
||||
private void thenSpanWasReportedWithTags(ArrayListSpanReporter accumulator,
|
||||
ClientResponse response) {
|
||||
Awaitility.await()
|
||||
.untilAsserted(() -> then(response.statusCode().value()).isEqualTo(200));
|
||||
List<zipkin2.Span> spans = accumulator.getSpans().stream()
|
||||
.filter(span -> "get /api/c2/{id}".equals(span.name()))
|
||||
.collect(Collectors.toList());
|
||||
then(spans).hasSize(1);
|
||||
then(spans.get(0).name()).isEqualTo("get /api/c2/{id}");
|
||||
then(spans.get(0).tags()).containsEntry("mvc.controller.method", "successful")
|
||||
.containsEntry("mvc.controller.class", "Controller2");
|
||||
}
|
||||
|
||||
private void thenSpanWasReportedForFunction(ArrayListSpanReporter accumulator,
|
||||
ClientResponse response) {
|
||||
Awaitility.await()
|
||||
.untilAsserted(() -> then(response.statusCode().value()).isEqualTo(200));
|
||||
List<zipkin2.Span> spans = accumulator.getSpans().stream()
|
||||
.filter(span -> "get".equals(span.name())).collect(Collectors.toList());
|
||||
then(spans).hasSize(1);
|
||||
}
|
||||
|
||||
private void thenNoSpanWasReported(ArrayListSpanReporter accumulator,
|
||||
ClientResponse response, Controller2 controller2) {
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
then(response.statusCode().value()).isEqualTo(200);
|
||||
then(accumulator.getSpans()).isEmpty();
|
||||
});
|
||||
then(controller2.span).isNotNull();
|
||||
then(controller2.span.context().traceIdString()).isEqualTo(EXPECTED_TRACE_ID);
|
||||
}
|
||||
|
||||
private ClientResponse whenRequestIsSent(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/api/c2/10").exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
private ClientResponse whenRequestIsSentToFunction(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/function").exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
private ClientResponse whenRequestIsSentToSkippedPattern(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/skipped").exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
private ClientResponse whenNonSampledRequestIsSent(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/api/c2/10")
|
||||
.header("X-B3-SpanId", EXPECTED_TRACE_ID)
|
||||
.header("X-B3-TraceId", EXPECTED_TRACE_ID).header("X-B3-Sampled", "0")
|
||||
.exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = { TraceWebClientAutoConfiguration.class })
|
||||
@DisableWebFluxSecurity
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
WebClient webClient() {
|
||||
return WebClient.create();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Sampler sampler() {
|
||||
return Sampler.ALWAYS_SAMPLE;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ArrayListSpanReporter spanReporter() {
|
||||
return new ArrayListSpanReporter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Controller2 controller2(Tracer tracer) {
|
||||
return new Controller2(tracer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
TestEndpoint testEndpoint() {
|
||||
return new TestEndpoint();
|
||||
}
|
||||
|
||||
@Bean
|
||||
RouterFunction<ServerResponse> function() {
|
||||
return RouterFunctions.route(RequestPredicates.GET("/function"), r -> {
|
||||
then(MDC.get("X-B3-TraceId")).isNotEmpty();
|
||||
return ServerResponse.ok().syncBody("functionOk");
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
TestBean testBean(Tracer tracer) {
|
||||
return new TestBean(tracer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
SleuthSpanCreatorAspectWebFlux.AccessLoggingHttpTraceRepository accessLoggingHttpTraceRepository() {
|
||||
return new SleuthSpanCreatorAspectWebFlux.AccessLoggingHttpTraceRepository();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SleuthSpanCreatorAspectWebFlux sleuthSpanCreatorAspectWebFlux(Tracer tracer,
|
||||
SleuthSpanCreatorAspectWebFlux.AccessLoggingHttpTraceRepository repository,
|
||||
ArrayListSpanReporter reporter) {
|
||||
return new SleuthSpanCreatorAspectWebFlux(tracer, repository, reporter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
static class Controller2 {
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
Span span;
|
||||
|
||||
Controller2(Tracer tracer) {
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
@GetMapping("/api/c2/{id}")
|
||||
public Flux<String> successful(@PathVariable Long id) {
|
||||
// #786
|
||||
then(MDC.get("X-B3-TraceId")).isNotEmpty();
|
||||
this.span = this.tracer.currentSpan();
|
||||
return Flux.just(id.toString());
|
||||
}
|
||||
|
||||
@GetMapping("/skipped")
|
||||
public Flux<String> skipped() {
|
||||
Boolean sampled = this.tracer.currentSpan().context().sampled();
|
||||
then(sampled).isFalse();
|
||||
return Flux.just(sampled.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/test")
|
||||
static class TestEndpoint {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TestEndpoint.class);
|
||||
|
||||
@Autowired
|
||||
Tracer tracer;
|
||||
|
||||
@Autowired
|
||||
TestBean testBean;
|
||||
|
||||
@GetMapping("/ping")
|
||||
Mono<Long> ping() {
|
||||
log.info("ping");
|
||||
return Mono.just(this.tracer.currentSpan().context().spanId());
|
||||
}
|
||||
|
||||
@GetMapping("/pingFromContext")
|
||||
Mono<Long> pingFromContext() {
|
||||
log.info("pingFromContext");
|
||||
return Mono.subscriberContext()
|
||||
.doOnSuccess(context -> log.info("Ping from context"))
|
||||
.flatMap(context -> Mono
|
||||
.just(this.tracer.currentSpan().context().spanId()));
|
||||
}
|
||||
|
||||
@GetMapping("/continueSpan")
|
||||
Mono<Long> continueSpan() {
|
||||
log.info("continueSpan");
|
||||
return this.testBean.continueSpanInTraceContext();
|
||||
}
|
||||
|
||||
@GetMapping("/newSpan1")
|
||||
Mono<Long> newSpan1() {
|
||||
log.info("newSpan1");
|
||||
return this.testBean.newSpanInTraceContext();
|
||||
}
|
||||
|
||||
@GetMapping("/newSpan2")
|
||||
Mono<Long> newSpan2() {
|
||||
log.info("newSpan2");
|
||||
return this.testBean.newSpanInSubscriberContext();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SleuthSpanCreatorAspectWebFlux {
|
||||
|
||||
private static final Log log = LogFactory
|
||||
.getLog(SleuthSpanCreatorAspectWebFlux.class);
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
private final SleuthSpanCreatorAspectWebFlux.AccessLoggingHttpTraceRepository repository;
|
||||
|
||||
private final ArrayListSpanReporter reporter;
|
||||
|
||||
int port;
|
||||
|
||||
private WebTestClient webClient;
|
||||
|
||||
SleuthSpanCreatorAspectWebFlux(Tracer tracer,
|
||||
AccessLoggingHttpTraceRepository repository, ArrayListSpanReporter reporter) {
|
||||
this.tracer = tracer;
|
||||
this.repository = repository;
|
||||
this.reporter = reporter;
|
||||
}
|
||||
|
||||
private static String toHexString(Long value) {
|
||||
BDDAssertions.then(value).isNotNull();
|
||||
return StringUtils.leftPad(Long.toHexString(value), 16, '0');
|
||||
}
|
||||
|
||||
void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
this.reporter.clear();
|
||||
this.repository.clear();
|
||||
log.info("Running app on port [" + this.port + "]");
|
||||
this.webClient = WebTestClient.bindToServer()
|
||||
.baseUrl("http://localhost:" + this.port).build();
|
||||
}
|
||||
|
||||
public void shouldReturnSpanFromWebFluxTraceContext() {
|
||||
setup();
|
||||
Mono<Object> mono = this.webClient.get().uri("/test/ping").exchange()
|
||||
.returnResult(Object.class).getResponseBody().single();
|
||||
|
||||
Object object = mono.block();
|
||||
log.info("Received [" + object + "]");
|
||||
Long newSpanId = (Long) object;
|
||||
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
List<zipkin2.Span> spans = getSpans();
|
||||
zipkin2.Span spanToFind = spans.stream()
|
||||
.filter(span -> "get /test/ping".equals(span.name())).findFirst()
|
||||
.orElseThrow(() -> new AssertionError(
|
||||
"No span with name [get /test/ping] found"));
|
||||
then(spanToFind.kind()).isEqualTo(zipkin2.Span.Kind.SERVER);
|
||||
then(spanToFind.name()).isEqualTo("get /test/ping");
|
||||
then(spanToFind.id()).isEqualTo(toHexString(newSpanId));
|
||||
then(this.tracer.currentSpan()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
private List<zipkin2.Span> getSpans() {
|
||||
List<zipkin2.Span> spans = this.reporter.getSpans();
|
||||
log.info("Reported the following spans: \n\n" + spans);
|
||||
return spans;
|
||||
}
|
||||
|
||||
public void shouldReturnSpanFromWebFluxSubscriptionContext() {
|
||||
setup();
|
||||
Mono<Object> mono = this.webClient.get().uri("/test/pingFromContext").exchange()
|
||||
.returnResult(Object.class).getResponseBody().single();
|
||||
|
||||
Object object = mono.block();
|
||||
log.info("Received [" + object + "]");
|
||||
Long newSpanId = (Long) object;
|
||||
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
List<zipkin2.Span> spans = getSpans();
|
||||
zipkin2.Span pingFromContext = spans.stream()
|
||||
.filter(span -> "get /test/pingfromcontext".equals(span.name()))
|
||||
.findFirst().orElseThrow(() -> new AssertionError(
|
||||
"No span with name [get /test/pingfromcontext] found"));
|
||||
then(pingFromContext.name()).isEqualTo("get /test/pingfromcontext");
|
||||
then(pingFromContext.kind()).isEqualTo(zipkin2.Span.Kind.SERVER);
|
||||
then(pingFromContext.id()).isEqualTo(toHexString(newSpanId));
|
||||
then(this.tracer.currentSpan()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
public void shouldContinueSpanInWebFlux() {
|
||||
setup();
|
||||
Mono<Object> mono = this.webClient.get().uri("/test/continueSpan").exchange()
|
||||
.returnResult(Object.class).getResponseBody().single();
|
||||
|
||||
Object object = mono.block();
|
||||
log.info("Received [" + object + "]");
|
||||
Long newSpanId = (Long) object;
|
||||
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
List<zipkin2.Span> spans = getSpans();
|
||||
zipkin2.Span spanToFind = spans.stream()
|
||||
.filter(span -> "get /test/continuespan".equals(span.name()))
|
||||
.findFirst().orElseThrow(() -> new AssertionError(
|
||||
"No span with name [get /test/continuespan] found"));
|
||||
then(spanToFind.kind()).isEqualTo(zipkin2.Span.Kind.SERVER);
|
||||
then(spanToFind.name()).isEqualTo("get /test/continuespan");
|
||||
then(spanToFind.id()).isEqualTo(toHexString(newSpanId));
|
||||
then(this.tracer.currentSpan()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
public void shouldCreateNewSpanInWebFlux() {
|
||||
setup();
|
||||
Mono<Object> mono = this.webClient.get().uri("/test/newSpan1").exchange()
|
||||
.returnResult(Object.class).getResponseBody().single();
|
||||
|
||||
Object object = mono.block();
|
||||
log.info("Received [" + object + "]");
|
||||
Long newSpanId = (Long) object;
|
||||
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
then(spanWithName("new-span-in-trace-context").id())
|
||||
.isEqualTo(toHexString(newSpanId));
|
||||
then(spanWithName("get /test/newspan1").kind())
|
||||
.isEqualTo(zipkin2.Span.Kind.SERVER);
|
||||
then(this.tracer.currentSpan()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
private zipkin2.Span spanWithName(String name) {
|
||||
return getSpans().stream().filter(span -> name.equals(span.name())).findFirst()
|
||||
.orElseThrow(() -> new AssertionError(
|
||||
"Span with name [" + name + "] not found"));
|
||||
}
|
||||
|
||||
public void shouldCreateNewSpanInWebFluxInSubscriberContext() {
|
||||
setup();
|
||||
Mono<Object> mono = this.webClient.get().uri("/test/newSpan2").exchange()
|
||||
.returnResult(Object.class).getResponseBody().single();
|
||||
|
||||
Object object = mono.block();
|
||||
log.info("Received [" + object + "]");
|
||||
Long newSpanId = (Long) object;
|
||||
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
then(spanWithName("new-span-in-subscriber-context").id())
|
||||
.isEqualTo(toHexString(newSpanId));
|
||||
then(spanWithName("get /test/newspan2").kind())
|
||||
.isEqualTo(zipkin2.Span.Kind.SERVER);
|
||||
then(this.tracer.currentSpan()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
public void shouldSetupCorrectSpanInHttpTrace() {
|
||||
setup();
|
||||
|
||||
Mono<Object> mono = this.webClient.get().uri("/test/ping").exchange()
|
||||
.returnResult(Object.class).getResponseBody().single();
|
||||
|
||||
Object object = mono.block();
|
||||
log.info("Received [" + object + "]");
|
||||
Long newSpanId = (Long) object;
|
||||
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
then(spanWithName("get /test/ping").kind())
|
||||
.isEqualTo(zipkin2.Span.Kind.SERVER);
|
||||
then(this.repository.getSpan()).isNotNull();
|
||||
then(spanWithName("get /test/ping").id()).isEqualTo(toHexString(newSpanId))
|
||||
.isEqualTo(this.repository.getSpan().context().traceIdString());
|
||||
then(this.tracer.currentSpan()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
static class AccessLoggingHttpTraceRepository implements HttpTraceRepository {
|
||||
|
||||
private static final Log log = LogFactory.getLog(
|
||||
SleuthSpanCreatorAspectWebFlux.AccessLoggingHttpTraceRepository.class);
|
||||
|
||||
@Autowired
|
||||
Tracer tracer;
|
||||
|
||||
brave.Span span;
|
||||
|
||||
@Override
|
||||
public List<HttpTrace> findAll() {
|
||||
log.info("Find all executed");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(HttpTrace trace) {
|
||||
this.span = this.tracer.currentSpan();
|
||||
log.info("Setting span [" + this.span + "]");
|
||||
}
|
||||
|
||||
public brave.Span getSpan() {
|
||||
return this.span;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.span = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestBean {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TestBean.class);
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
TestBean(Tracer tracer) {
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
@ContinueSpan
|
||||
public Mono<Long> continueSpanInTraceContext() {
|
||||
log.info("Continue");
|
||||
Long span = this.tracer.currentSpan().context().spanId();
|
||||
return Mono.defer(() -> Mono.just(span));
|
||||
}
|
||||
|
||||
@NewSpan(name = "newSpanInTraceContext")
|
||||
public Mono<Long> newSpanInTraceContext() {
|
||||
log.info("New Span in Trace Context");
|
||||
return Mono.defer(() -> Mono.just(this.tracer.currentSpan().context().spanId()));
|
||||
}
|
||||
|
||||
@NewSpan(name = "newSpanInSubscriberContext")
|
||||
public Mono<Long> newSpanInSubscriberContext() {
|
||||
log.info("New Span in Subscriber Context");
|
||||
return Mono.subscriberContext()
|
||||
.doOnSuccess(context -> log.info("New Span in deferred Trace Context"))
|
||||
.flatMap(context -> Mono.defer(
|
||||
() -> Mono.just(this.tracer.currentSpan().context().spanId())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
spring.autoconfigure.exclude:
|
||||
spring.data.jdbc.repositories.enabled: true
|
||||
spring.data.jpa.repositories.enabled: true
|
||||
@@ -13,14 +13,9 @@ eureka.client.enabled: false
|
||||
ribbon.eureka.enabled: false
|
||||
|
||||
spring.sleuth.scheduled.skipPattern: "^org.*TestBeanWithScheduledMethodToBeIgnored$"
|
||||
# comma separated list of matchers
|
||||
spring.sleuth.rxjava.schedulers.ignoredthreads: HystixMetricPoller,^MyCustomThread.*$,^RxComputation.*$
|
||||
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
|
||||
#disable hibernate by default
|
||||
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.cloud.gateway.config.GatewayAutoConfiguration, org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration
|
||||
spring.data.jdbc.repositories.enabled: false
|
||||
spring.data.jpa.repositories.enabled: false
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
<logger name="feign" level="DEBUG"/>
|
||||
<logger name="com.netflix.discovery.InstanceInfoReplicator" level="ERROR"/>
|
||||
<logger name="org.springframework" level="INFO"/>
|
||||
<logger name="org.springframework.cloud.sleuth" level="TRACE"/>
|
||||
<logger name="org.springframework.boot.autoconfigure.logging" level="INFO"/>
|
||||
<logger name="org.springframework.cloud.sleuth.log" level="DEBUG"/>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<properties>
|
||||
<brave.version>5.6.7</brave.version>
|
||||
<brave.opentracing.version>0.34.1</brave.opentracing.version>
|
||||
<grpc.spring.boot.version>3.0.1</grpc.spring.boot.version>
|
||||
<grpc.spring.boot.version>3.3.0</grpc.spring.boot.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
66
tests/pom.xml
Normal file
66
tests/pom.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Sleuth Tests</name>
|
||||
<description>Spring Cloud Sleuth Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-sleuth-instrumentation-async-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-grpc-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-hystrix-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-messaging-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-reactor-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-lettuce-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-rxjava-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-scheduling-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-mvc-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-webflux-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-feign-tests</module>
|
||||
<module>spring-cloud-sleuth-instrumentation-zuul-tests</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy (this is just a test module) -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-async-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Async Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Async Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@EnableAutoConfiguration(
|
||||
exclude = { LoadBalancerAutoConfiguration.class, JmxAutoConfiguration.class })
|
||||
@Configuration
|
||||
public @interface DefaultTestAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -20,6 +20,7 @@ import java.lang.invoke.MethodHandles;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -59,7 +60,8 @@ import static org.assertj.core.api.BDDAssertions.then;
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
@SpringBootTest(classes = { AppConfig.class, Application.class },
|
||||
webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "ribbon.eureka.enabled=false", "feign.hystrix.enabled=false" })
|
||||
public class Issue410Tests {
|
||||
|
||||
@@ -250,6 +252,11 @@ class AppConfig {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@Bean("taskScheduler")
|
||||
public Executor myScheduler() {
|
||||
return Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Executor poolTaskExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-feign-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Feign Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Feign Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-okhttp</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web.client.feign.issues.issue307;
|
||||
package org.springframework.cloud.sleuth.instrument.feign.issues.issue307;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web.client.feign.issues.issue350;
|
||||
package org.springframework.cloud.sleuth.instrument.feign.issues.issue350;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web.client.feign.issues.issue362;
|
||||
package org.springframework.cloud.sleuth.instrument.feign.issues.issue362;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web.client.feign.issues.issue393;
|
||||
package org.springframework.cloud.sleuth.instrument.feign.issues.issue393;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web.client.feign.issues.issue502;
|
||||
package org.springframework.cloud.sleuth.instrument.feign.issues.issue502;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -0,0 +1,17 @@
|
||||
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
|
||||
ribbon:
|
||||
ConnectTimeout: 3000
|
||||
ReadTimeout: 5000
|
||||
|
||||
exceptionService.ribbon:
|
||||
MaxAutoRetries: 3
|
||||
OkToRetryOnAllOperations: true
|
||||
ConnectTimeout: 1
|
||||
ReadTimeout: 1
|
||||
|
||||
eureka.client.enabled: false
|
||||
ribbon.eureka.enabled: false
|
||||
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
92
tests/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml
Normal file
92
tests/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-grpc-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Grpc Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Grpc Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- This forces the guava version to 20 within the test scope, which is required by GRPC -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>20.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- GRPC Optional Dependencies -->
|
||||
<dependency>
|
||||
<groupId>io.github.lognet</groupId>
|
||||
<artifactId>grpc-spring-boot-starter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.brave</groupId>
|
||||
<artifactId>brave-instrumentation-grpc</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2019 the original author or authors.
|
||||
* Copyright 2013-2019 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.
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-hystrix-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Hystrix Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Hystrix Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.hystrix;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@EnableAutoConfiguration(
|
||||
exclude = { LoadBalancerAutoConfiguration.class, JmxAutoConfiguration.class })
|
||||
// ,TraceSpringIntegrationAutoConfiguration.class,
|
||||
// TraceWebSocketAutoConfiguration.class })
|
||||
@Configuration
|
||||
public @interface DefaultTestAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-lettuce-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Lettuce Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Lettuce Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.lettuce</groupId>
|
||||
<artifactId>lettuce-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd
|
||||
https://www.w3.org/2001/XMLSchema-instance ">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-messaging-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Messaging Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Messaging Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.brave</groupId>
|
||||
<artifactId>brave-instrumentation-spring-rabbit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.brave</groupId>
|
||||
<artifactId>brave-instrumentation-kafka-clients</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.brave</groupId>
|
||||
<artifactId>brave-instrumentation-kafka-streams</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.brave</groupId>
|
||||
<artifactId>brave-instrumentation-jms</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.jms</groupId>
|
||||
<artifactId>javax.jms-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jms</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.amqp</groupId>
|
||||
<artifactId>spring-rabbit</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-streams</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-activemq</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- to test DefaultJcaListenerContainerFactory -->
|
||||
<dependency>
|
||||
<groupId>javax.resource</groupId>
|
||||
<artifactId>javax.resource-api</artifactId>
|
||||
<version>1.7.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-ra</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -51,9 +51,6 @@ import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfigura
|
||||
import org.springframework.boot.jms.XAConnectionFactoryWrapper;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.gateway.config.GatewayAutoConfiguration;
|
||||
import org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jca.support.ResourceAdapterFactoryBean;
|
||||
@@ -69,6 +66,7 @@ import org.springframework.jms.listener.endpoint.JmsMessageEndpointManager;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
// inspired by org.springframework.boot.autoconfigure.jms.JmsAutoConfigurationTests
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@@ -303,9 +301,7 @@ public class JmsTracingConfigurationTest {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = { GatewayAutoConfiguration.class,
|
||||
GatewayClassPathWarningAutoConfiguration.class,
|
||||
EurekaClientAutoConfiguration.class })
|
||||
@EnableAutoConfiguration
|
||||
class JmsTestTracingConfiguration {
|
||||
|
||||
static final String CONTEXT_LEAK = "context.leak";
|
||||
@@ -28,8 +28,8 @@ 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.instrument.util.SpanUtil;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.cloud.sleuth.util.SpanUtil;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.util;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
* @since
|
||||
*/
|
||||
public final class SpanUtil {
|
||||
|
||||
private SpanUtil() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
// Represents given long id as 16-character lower-hex string
|
||||
public static String idToHex(long id) {
|
||||
char[] data = new char[16];
|
||||
writeHexLong(data, 0, id);
|
||||
return new String(data);
|
||||
}
|
||||
|
||||
// Inspired by {@code okio.Buffer.writeLong}
|
||||
static void writeHexLong(char[] data, int pos, long v) {
|
||||
writeHexByte(data, pos + 0, (byte) ((v >>> 56L) & 0xff));
|
||||
writeHexByte(data, pos + 2, (byte) ((v >>> 48L) & 0xff));
|
||||
writeHexByte(data, pos + 4, (byte) ((v >>> 40L) & 0xff));
|
||||
writeHexByte(data, pos + 6, (byte) ((v >>> 32L) & 0xff));
|
||||
writeHexByte(data, pos + 8, (byte) ((v >>> 24L) & 0xff));
|
||||
writeHexByte(data, pos + 10, (byte) ((v >>> 16L) & 0xff));
|
||||
writeHexByte(data, pos + 12, (byte) ((v >>> 8L) & 0xff));
|
||||
writeHexByte(data, pos + 14, (byte) (v & 0xff));
|
||||
}
|
||||
|
||||
static void writeHexByte(char[] data, int pos, byte b) {
|
||||
data[pos + 0] = HEX_DIGITS[(b >> 4) & 0xf];
|
||||
data[pos + 1] = HEX_DIGITS[b & 0xf];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 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
|
||||
~
|
||||
~ https://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.
|
||||
-->
|
||||
|
||||
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
https://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/task https://www.springframework.org/schema/task/spring-task.xsd">
|
||||
|
||||
<int:channel id="messagingChannel"/>
|
||||
|
||||
<int:channel id="splitterOutChannel">
|
||||
<int:queue capacity="10"/>
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="messagingProcessedChannel">
|
||||
<int:queue capacity="10"/>
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="messagingOutputChannel">
|
||||
<int:queue capacity="10"/>
|
||||
</int:channel>
|
||||
|
||||
<int:service-activator input-channel="splitterOutChannel"
|
||||
method="invokeProcessor"
|
||||
output-channel="messagingProcessedChannel"
|
||||
ref="helloWorldImpl">
|
||||
<int:poller max-messages-per-poll="1" fixed-rate="1"
|
||||
task-executor="requestExecutor"/>
|
||||
</int:service-activator>
|
||||
|
||||
<int:aggregator input-channel="messagingProcessedChannel"
|
||||
output-channel="messagingOutputChannel"
|
||||
message-store="messageStore"
|
||||
send-partial-result-on-expiry="true">
|
||||
<int:poller max-messages-per-poll="1" fixed-rate="1"
|
||||
task-executor="requestExecutor"/>
|
||||
</int:aggregator>
|
||||
|
||||
<!-- Define a store for our search results and set up a reaper that will
|
||||
periodically expire those results. -->
|
||||
<bean id="messageStore"
|
||||
class="org.springframework.integration.store.SimpleMessageStore"/>
|
||||
|
||||
<bean id="messageStoreReaper"
|
||||
class="org.springframework.integration.store.MessageGroupStoreReaper">
|
||||
<property name="messageGroupStore" ref="messageStore"/>
|
||||
<property name="timeout" value="2000"/>
|
||||
</bean>
|
||||
|
||||
<int:gateway id="messagingGateway"
|
||||
service-interface="org.springframework.cloud.sleuth.instrument.messaging.issues.issue_943.MessagingGateway"
|
||||
default-request-channel="messagingChannel" default-reply-timeout="10000"
|
||||
default-reply-channel="splitterOutChannel"/>
|
||||
|
||||
<task:executor id="requestExecutor" pool-size="10"/>
|
||||
|
||||
<int:splitter ref="helloWorldImpl" method="splitMessage"
|
||||
input-channel="messagingChannel" output-channel="splitterOutChannel"/>
|
||||
|
||||
<bean id="helloWorldImpl"
|
||||
class="org.springframework.cloud.sleuth.instrument.messaging.issues.issue_943.HelloWorldImpl"/>
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 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
|
||||
~
|
||||
~ https://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.
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
<logger name="feign" level="DEBUG"/>
|
||||
<logger name="com.netflix.discovery.InstanceInfoReplicator" level="ERROR"/>
|
||||
<logger name="org.springframework.cloud.sleuth" level="TRACE"/>
|
||||
<logger name="org.springframework.boot.autoconfigure.logging" level="INFO"/>
|
||||
<logger name="org.springframework.cloud.sleuth.log" level="DEBUG"/>
|
||||
<logger name="org.springframework.cloud.sleuth.trace" level="DEBUG"/>
|
||||
<logger name="org.springframework.cloud.sleuth.instrument.rxjava" level="DEBUG"/>
|
||||
<logger name="org.springframework.cloud.sleuth.instrument.reactor" level="TRACE"/>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE"/>
|
||||
</root>
|
||||
</configuration>
|
||||
79
tests/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml
Normal file
79
tests/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-mvc-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Mvc Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Mvc Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -29,9 +29,9 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -172,7 +172,7 @@ public class TraceAsyncIntegrationTests {
|
||||
this.reporter.clear();
|
||||
}
|
||||
|
||||
@DefaultTestAutoConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableAsync
|
||||
@Configuration
|
||||
static class TraceAsyncITestConfiguration {
|
||||
@@ -42,8 +42,8 @@ import org.slf4j.MDC;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.cloud.sleuth.util.SpanUtil;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -316,7 +316,7 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest {
|
||||
return "0".equals(mvcResult.getResponse().getHeader(SAMPLED_NAME));
|
||||
}
|
||||
|
||||
@DefaultTestAutoConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@Configuration
|
||||
protected static class Config {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.util;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
* @since
|
||||
*/
|
||||
public final class SpanUtil {
|
||||
|
||||
private SpanUtil() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
// Represents given long id as 16-character lower-hex string
|
||||
public static String idToHex(long id) {
|
||||
char[] data = new char[16];
|
||||
writeHexLong(data, 0, id);
|
||||
return new String(data);
|
||||
}
|
||||
|
||||
// Inspired by {@code okio.Buffer.writeLong}
|
||||
static void writeHexLong(char[] data, int pos, long v) {
|
||||
writeHexByte(data, pos + 0, (byte) ((v >>> 56L) & 0xff));
|
||||
writeHexByte(data, pos + 2, (byte) ((v >>> 48L) & 0xff));
|
||||
writeHexByte(data, pos + 4, (byte) ((v >>> 40L) & 0xff));
|
||||
writeHexByte(data, pos + 6, (byte) ((v >>> 32L) & 0xff));
|
||||
writeHexByte(data, pos + 8, (byte) ((v >>> 24L) & 0xff));
|
||||
writeHexByte(data, pos + 10, (byte) ((v >>> 16L) & 0xff));
|
||||
writeHexByte(data, pos + 12, (byte) ((v >>> 8L) & 0xff));
|
||||
writeHexByte(data, pos + 14, (byte) (v & 0xff));
|
||||
}
|
||||
|
||||
static void writeHexByte(char[] data, int pos, byte b) {
|
||||
data[pos + 0] = HEX_DIGITS[(b >> 4) & 0xf];
|
||||
data[pos + 1] = HEX_DIGITS[b & 0xf];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-reactor-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Reactor Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Reactor Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor.netty</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reactivestreams</groupId>
|
||||
<artifactId>reactive-streams</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.reactor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public final class TraceReactorAutoConfigurationAccessorConfiguration {
|
||||
|
||||
private TraceReactorAutoConfigurationAccessorConfiguration() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
private static final Log log = LogFactory
|
||||
.getLog(TraceReactorAutoConfigurationAccessorConfiguration.class);
|
||||
|
||||
public static void close() {
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Cleaning up hooks");
|
||||
}
|
||||
new TraceReactorAutoConfiguration.TraceReactorConfiguration().cleanupHooks();
|
||||
}
|
||||
|
||||
public static void setup(ConfigurableApplicationContext context) {
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Setting up hooks");
|
||||
}
|
||||
TraceReactorAutoConfiguration.TraceReactorConfiguration
|
||||
.traceHookRegisteringBeanDefinitionRegistryPostProcessor(context)
|
||||
.setupHooks(context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,6 @@ import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.rule.OutputCapture;
|
||||
import org.springframework.cloud.sleuth.DisableWebFluxSecurity;
|
||||
import org.springframework.cloud.sleuth.instrument.reactor.Issue866Configuration;
|
||||
import org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfigurationAccessorConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
@@ -159,7 +158,6 @@ public class FlatMapTests {
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@DisableWebFluxSecurity
|
||||
static class TestConfiguration {
|
||||
|
||||
brave.Span spanInFoo;
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-rxjava-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth RxJava Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth RxJava Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,6 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
|
||||
# comma separated list of matchers
|
||||
spring.sleuth.rxjava.schedulers.ignoredthreads: HystixMetricPoller,^MyCustomThread.*$,^RxComputation.*$
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-scheduling-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Scheduling Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Scheduling Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -19,8 +19,6 @@ package org.springframework.cloud.sleuth.instrument.scheduling;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import brave.Span;
|
||||
import brave.Tracing;
|
||||
import brave.sampler.Sampler;
|
||||
@@ -32,8 +30,8 @@ import org.junit.runner.RunWith;
|
||||
import zipkin2.reporter.Reporter;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -49,7 +47,6 @@ import static org.awaitility.Awaitility.await;
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = { ScheduledTestConfiguration.class })
|
||||
@DirtiesContext
|
||||
@NotThreadSafe
|
||||
public class TracingOnScheduledTests {
|
||||
|
||||
@Autowired
|
||||
@@ -143,7 +140,7 @@ public class TracingOnScheduledTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@DefaultTestAutoConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableScheduling
|
||||
class ScheduledTestConfiguration {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
|
||||
spring.sleuth.scheduled.skipPattern: "^org.*TestBeanWithScheduledMethodToBeIgnored$"
|
||||
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-webflux-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth WebFlux Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth WebFlux Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web.client;
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import brave.ScopedSpan;
|
||||
import brave.Tracer;
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.web;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import brave.Span;
|
||||
import brave.Tracer;
|
||||
import brave.sampler.Sampler;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.sleuth.instrument.web.client.TraceWebClientAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
public class TraceWebFluxTests {
|
||||
|
||||
public static final String EXPECTED_TRACE_ID = "b919095138aa4c6e";
|
||||
|
||||
@Test
|
||||
public void should_instrument_web_filter() throws Exception {
|
||||
// setup
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder(
|
||||
TraceWebFluxTests.Config.class)
|
||||
.web(WebApplicationType.REACTIVE)
|
||||
.properties("server.port=0", "spring.jmx.enabled=false",
|
||||
"spring.sleuth.web.skipPattern=/skipped",
|
||||
"spring.application.name=TraceWebFluxTests",
|
||||
"security.basic.enabled=false",
|
||||
"management.security.enabled=false")
|
||||
.run();
|
||||
ArrayListSpanReporter accumulator = context.getBean(ArrayListSpanReporter.class);
|
||||
int port = context.getBean(Environment.class).getProperty("local.server.port",
|
||||
Integer.class);
|
||||
Controller2 controller2 = context.getBean(Controller2.class);
|
||||
clean(accumulator, controller2);
|
||||
|
||||
// when
|
||||
ClientResponse response = whenRequestIsSent(port);
|
||||
// then
|
||||
thenSpanWasReportedWithTags(accumulator, response);
|
||||
clean(accumulator, controller2);
|
||||
|
||||
// when
|
||||
ClientResponse nonSampledResponse = whenNonSampledRequestIsSent(port);
|
||||
// then
|
||||
thenNoSpanWasReported(accumulator, nonSampledResponse, controller2);
|
||||
accumulator.clear();
|
||||
|
||||
// when
|
||||
ClientResponse skippedPatternResponse = whenRequestIsSentToSkippedPattern(port);
|
||||
// then
|
||||
thenNoSpanWasReported(accumulator, skippedPatternResponse, controller2);
|
||||
|
||||
// cleanup
|
||||
context.close();
|
||||
}
|
||||
|
||||
private void clean(ArrayListSpanReporter accumulator, Controller2 controller2) {
|
||||
accumulator.clear();
|
||||
controller2.span = null;
|
||||
}
|
||||
|
||||
private void thenSpanWasReportedWithTags(ArrayListSpanReporter accumulator,
|
||||
ClientResponse response) {
|
||||
Awaitility.await()
|
||||
.untilAsserted(() -> then(response.statusCode().value()).isEqualTo(200));
|
||||
List<zipkin2.Span> spans = accumulator.getSpans().stream()
|
||||
.filter(span -> "get /api/c2/{id}".equals(span.name()))
|
||||
.collect(Collectors.toList());
|
||||
then(spans).hasSize(1);
|
||||
then(spans.get(0).name()).isEqualTo("get /api/c2/{id}");
|
||||
then(spans.get(0).tags()).containsEntry("mvc.controller.method", "successful")
|
||||
.containsEntry("mvc.controller.class", "Controller2");
|
||||
}
|
||||
|
||||
private void thenNoSpanWasReported(ArrayListSpanReporter accumulator,
|
||||
ClientResponse response, Controller2 controller2) {
|
||||
Awaitility.await().untilAsserted(() -> {
|
||||
then(response.statusCode().value()).isEqualTo(200);
|
||||
then(accumulator.getSpans()).isEmpty();
|
||||
});
|
||||
then(controller2.span).isNotNull();
|
||||
then(controller2.span.context().traceIdString()).isEqualTo(EXPECTED_TRACE_ID);
|
||||
}
|
||||
|
||||
private ClientResponse whenRequestIsSent(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/api/c2/10").exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
private ClientResponse whenRequestIsSentToSkippedPattern(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/skipped").exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
private ClientResponse whenNonSampledRequestIsSent(int port) {
|
||||
Mono<ClientResponse> exchange = WebClient.create().get()
|
||||
.uri("http://localhost:" + port + "/api/c2/10")
|
||||
.header("X-B3-SpanId", EXPECTED_TRACE_ID)
|
||||
.header("X-B3-TraceId", EXPECTED_TRACE_ID).header("X-B3-Sampled", "0")
|
||||
.exchange();
|
||||
return exchange.block();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = { TraceWebClientAutoConfiguration.class })
|
||||
static class Config {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Config.class);
|
||||
|
||||
@Bean
|
||||
WebClient webClient() {
|
||||
return WebClient.create();
|
||||
}
|
||||
|
||||
@Bean
|
||||
Sampler sampler() {
|
||||
return Sampler.ALWAYS_SAMPLE;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ArrayListSpanReporter spanReporter() {
|
||||
return new ArrayListSpanReporter() {
|
||||
@Override
|
||||
public List<zipkin2.Span> getSpans() {
|
||||
List<zipkin2.Span> spans = super.getSpans();
|
||||
log.info("Reported the following spans: \n\n" + spans);
|
||||
return spans;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
Controller2 controller2(Tracer tracer) {
|
||||
return new Controller2(tracer);
|
||||
}
|
||||
}
|
||||
|
||||
@RestController
|
||||
static class Controller2 {
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
Span span;
|
||||
|
||||
Controller2(Tracer tracer) {
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
@GetMapping("/api/c2/{id}")
|
||||
public Flux<String> successful(@PathVariable Long id) {
|
||||
// #786
|
||||
then(MDC.get("X-B3-TraceId")).isNotEmpty();
|
||||
this.span = this.tracer.currentSpan();
|
||||
return Flux.just(id.toString());
|
||||
}
|
||||
|
||||
@GetMapping("/skipped")
|
||||
public Flux<String> skipped() {
|
||||
Boolean sampled = this.tracer.currentSpan().context().sampled();
|
||||
then(sampled).isFalse();
|
||||
return Flux.just(sampled.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.util;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
* @since
|
||||
*/
|
||||
public final class SpanUtil {
|
||||
|
||||
private SpanUtil() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
// Represents given long id as 16-character lower-hex string
|
||||
public static String idToHex(long id) {
|
||||
char[] data = new char[16];
|
||||
writeHexLong(data, 0, id);
|
||||
return new String(data);
|
||||
}
|
||||
|
||||
// Inspired by {@code okio.Buffer.writeLong}
|
||||
static void writeHexLong(char[] data, int pos, long v) {
|
||||
writeHexByte(data, pos + 0, (byte) ((v >>> 56L) & 0xff));
|
||||
writeHexByte(data, pos + 2, (byte) ((v >>> 48L) & 0xff));
|
||||
writeHexByte(data, pos + 4, (byte) ((v >>> 40L) & 0xff));
|
||||
writeHexByte(data, pos + 6, (byte) ((v >>> 32L) & 0xff));
|
||||
writeHexByte(data, pos + 8, (byte) ((v >>> 24L) & 0xff));
|
||||
writeHexByte(data, pos + 10, (byte) ((v >>> 16L) & 0xff));
|
||||
writeHexByte(data, pos + 12, (byte) ((v >>> 8L) & 0xff));
|
||||
writeHexByte(data, pos + 14, (byte) (v & 0xff));
|
||||
}
|
||||
|
||||
static void writeHexByte(char[] data, int pos, byte b) {
|
||||
data[pos + 0] = HEX_DIGITS[(b >> 4) & 0xf];
|
||||
data[pos + 1] = HEX_DIGITS[b & 0xf];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 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
|
||||
~
|
||||
~ https://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.
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
<logger name="feign" level="DEBUG"/>
|
||||
<logger name="com.netflix.discovery.InstanceInfoReplicator" level="ERROR"/>
|
||||
<logger name="org.springframework" level="INFO"/>
|
||||
<logger name="org.springframework.cloud.sleuth" level="TRACE"/>
|
||||
<logger name="org.springframework.boot.autoconfigure.logging" level="INFO"/>
|
||||
<logger name="org.springframework.cloud.sleuth.log" level="DEBUG"/>
|
||||
<logger name="org.springframework.cloud.sleuth.trace" level="DEBUG"/>
|
||||
<logger name="org.springframework.cloud.sleuth.instrument.rxjava" level="DEBUG"/>
|
||||
<logger name="org.springframework.cloud.sleuth.instrument.reactor" level="TRACE"/>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE"/>
|
||||
</root>
|
||||
</configuration>
|
||||
74
tests/spring-cloud-sleuth-instrumentation-zuul-tests/pom.xml
Normal file
74
tests/spring-cloud-sleuth-instrumentation-zuul-tests/pom.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2019 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
|
||||
~
|
||||
~ https://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.
|
||||
~
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-sleuth-instrumentation-zuul-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Sleuth Zuul Instrumentation Tests</name>
|
||||
<description>Spring Cloud Sleuth Zuul Instrumentation Tests</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-tests</artifactId>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<sonar.skip>true</sonar.skip>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
logging.level.com.netflix.discovery.InstanceInfoReplicator: ERROR
|
||||
logging.level.org.springframework.cloud.sleuth.instrument.web.client.feign: TRACE
|
||||
Reference in New Issue
Block a user