diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
index 7fcba0caa..daa5f2101 100644
--- a/benchmarks/pom.xml
+++ b/benchmarks/pom.xml
@@ -34,7 +34,7 @@
1.8
1.8
2.1.7.RELEASE
- 5.7.0
+ 5.8.0
diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc
index 322e98dc1..64c226409 100644
--- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc
+++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc
@@ -845,21 +845,23 @@ Sleuth will search for beans of those types and automatically apply customizatio
=== HTTP
-If a customization of client / server parsing of the HTTP related spans is required,
-just register a bean of type `brave.http.HttpClientParser` or
+If a customization of client / server parsing of the HTTP related spans is
+required, just register a bean of type `brave.http.HttpClientParser` or
`brave.http.HttpServerParser`. If client /server sampling is required, just
-register a bean of type `brave.http.HttpSampler` and name the bean
- `sleuthClientSampler` for client sampler and `sleuthServerSampler` for server sampler.
- For your convenience the `@ClientSampler` and `@ServerSampler`
- annotations can be used to inject the proper beans or to
- reference the bean names via their static String `NAME` fields.
+register a bean of type `brave.sampler.SamplerFunction` and name
+the bean `sleuthHttpClientSampler` for client sampler and
+`sleuthHttpServerSampler` for server sampler.
+
+For your convenience the `@HttpClientSampler` and `@HttpServerSampler`
+annotations can be used to inject the proper beans or to reference the bean
+names via their static String `NAME` fields.
Check out Brave's code to see an example of how to make a path-based sampler
https://github.com/openzipkin/brave/tree/master/instrumentation/http#sampling-policy
If you want to completely rewrite the `HttpTracing` bean you can use the `SkipPatternProvider`
interface to retrieve the URL `Pattern` for spans that should be not sampled. Below you can see
-an example of usage of `SkipPatternProvider` inside a server side, `HttpSampler`.
+an example of usage of `SkipPatternProvider` inside a server side, `Sampler`.
[source,java]
----
@@ -881,6 +883,34 @@ In the following example, we register the `TracingFilter` bean, add the `ZIPKIN-
include::../../../..//spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterIntegrationTests.java[tags=response_headers,indent=0]
----
+=== RPC
+
+Sleuth automatically configures the `RpcTracing` bean which serves as a
+foundation for RPC instrumentation such as gRPC or Dubbo.
+
+If a customization of client / server sampling of the RPC traces is required,
+just register a bean of type `brave.sampler.SamplerFunction` and
+name the bean `sleuthRpcClientSampler` for client sampler and
+`sleuthRpcServerSampler` for server sampler.
+
+For your convenience the `@RpcClientSampler` and `@RpcServerSampler`
+annotations can be used to inject the proper beans or to reference the bean
+names via their static String `NAME` fields.
+
+Ex. Here's a sampler that traces 100 "GetUserToken" server requests per second.
+This doesn't start new traces for requests to the health check service. Other
+requests will use the global sampling configuration.
+
+[source,java]
+----
+@Configuration
+class Config {
+include::../../../../spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java[tags=custom_rpc_server_sampler,indent=2]
+}
+----
+
+For more, see https://github.com/openzipkin/brave/tree/master/instrumentation/rpc#sampling-policy
+
=== Custom service name
By default, Sleuth assumes that, when you send a span to Zipkin, you want the span's service name to be equal to the value of the `spring.application.name` property.
@@ -1119,13 +1149,13 @@ To change the order of tracing filter registration, please set the
==== Dubbo RPC support
Via the integration with Brave, Spring Cloud Sleuth supports https://dubbo.apache.org/[Dubbo].
-It's enough to add the `brave-instrumentation-dubbo-rpc` dependency:
+It's enough to add the `brave-instrumentation-dubbo` dependency:
[source,xml,indent=0]
----
io.zipkin.brave
- brave-instrumentation-dubbo-rpc
+ brave-instrumentation-dubbo
----
diff --git a/pom.xml b/pom.xml
index 29a90743b..12c897c6c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -265,7 +265,7 @@
2.1.4.BUILD-SNAPSHOT
2.1.4.BUILD-SNAPSHOT
- 5.7.0
+ 5.8.0
2.1.2.RELEASE
diff --git a/spring-cloud-sleuth-core/pom.xml b/spring-cloud-sleuth-core/pom.xml
index 5ca597e02..b101ad3ef 100644
--- a/spring-cloud-sleuth-core/pom.xml
+++ b/spring-cloud-sleuth-core/pom.xml
@@ -197,6 +197,10 @@
io.zipkin.brave
brave-context-log4j2
+
+ io.zipkin.brave
+ brave-instrumentation-rpc
+
io.zipkin.brave
brave-instrumentation-spring-web
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java
index 9cf02eb5d..4b333dee1 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/TraceGrpcAutoConfiguration.java
@@ -19,15 +19,17 @@ package org.springframework.cloud.sleuth.instrument.grpc;
import java.util.List;
import java.util.Optional;
-import brave.Tracing;
import brave.grpc.GrpcTracing;
+import brave.rpc.RpcTracing;
import io.grpc.ServerInterceptor;
import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.sleuth.instrument.rpc.TraceRpcAutoConfiguration;
import org.springframework.context.annotation.Bean;
/**
@@ -41,12 +43,13 @@ import org.springframework.context.annotation.Bean;
*/
@ConditionalOnClass({ GrpcTracing.class, GRpcGlobalInterceptor.class })
@ConditionalOnProperty(value = "spring.sleuth.grpc.enabled", matchIfMissing = true)
-@ConditionalOnBean(Tracing.class)
+@ConditionalOnBean(RpcTracing.class)
+@AutoConfigureAfter(TraceRpcAutoConfiguration.class)
public class TraceGrpcAutoConfiguration {
@Bean
- public GrpcTracing grpcTracing(Tracing tracing) {
- return GrpcTracing.create(tracing);
+ public GrpcTracing grpcTracing(RpcTracing rpcTracing) {
+ return GrpcTracing.create(rpcTracing);
}
// Register a global interceptor for both the server
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcClientSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcClientSampler.java
new file mode 100644
index 000000000..689eef752
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcClientSampler.java
@@ -0,0 +1,50 @@
+/*
+ * 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.rpc;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import brave.sampler.SamplerFunction;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * Annotate a client {@link brave.sampler.SamplerFunction} that should be injected to
+ * {@link brave.rpc.RpcTracing.Builder#clientSampler(SamplerFunction)}.
+ *
+ * @since 2.2.0
+ * @see Qualifier
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
+ ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@Qualifier(RpcClientSampler.NAME)
+public @interface RpcClientSampler {
+
+ /**
+ * Default name for RPC client sampler.
+ */
+ String NAME = "sleuthRpcClientSampler";
+
+}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcServerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcServerSampler.java
new file mode 100644
index 000000000..195116410
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/RpcServerSampler.java
@@ -0,0 +1,50 @@
+/*
+ * 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.rpc;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import brave.sampler.SamplerFunction;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * Annotate a server {@link brave.sampler.SamplerFunction} that should be injected to
+ * {@link brave.rpc.RpcTracing.Builder#serverSampler(SamplerFunction)}.
+ *
+ * @since 2.2.0
+ * @see Qualifier
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
+ ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@Qualifier(RpcServerSampler.NAME)
+public @interface RpcServerSampler {
+
+ /**
+ * Default name for RPC server sampler.
+ */
+ String NAME = "sleuthRpcServerSampler";
+
+}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java
new file mode 100644
index 000000000..77e775219
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfiguration.java
@@ -0,0 +1,73 @@
+/*
+ * 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.rpc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import brave.Tracing;
+import brave.rpc.RpcRequest;
+import brave.rpc.RpcTracing;
+import brave.rpc.RpcTracingCustomizer;
+import brave.sampler.SamplerFunction;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.lang.Nullable;
+
+/**
+ * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
+ * Auto-configuration} related to RPC based communication.
+ *
+ * @since 2.2.0
+ */
+@Configuration
+@ConditionalOnProperty(name = "spring.sleuth.rpc.enabled", havingValue = "true", matchIfMissing = true)
+@ConditionalOnBean(Tracing.class)
+@AutoConfigureAfter(TraceAutoConfiguration.class)
+public class TraceRpcAutoConfiguration {
+
+ @Autowired(required = false)
+ List rpcTracingCustomizers = new ArrayList<>();
+
+ @Bean
+ @ConditionalOnMissingBean
+ // NOTE: stable bean name as might be used outside sleuth
+ RpcTracing rpcTracing(Tracing tracing,
+ @Nullable @RpcClientSampler SamplerFunction clientSampler,
+ @Nullable @RpcServerSampler SamplerFunction serverSampler) {
+
+ RpcTracing.Builder builder = RpcTracing.newBuilder(tracing);
+ if (clientSampler != null) {
+ builder.clientSampler(clientSampler);
+ }
+ if (serverSampler != null) {
+ builder.serverSampler(serverSampler);
+ }
+ for (RpcTracingCustomizer customizer : this.rpcTracingCustomizers) {
+ customizer.customize(builder);
+ }
+ return builder.build();
+ }
+
+}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java
index 7b58cc5df..21bb50cd5 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ClientSampler.java
@@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
* @author Marcin Grzejszczak
* @since 2.0.0
* @see Qualifier
+ * @deprecated Since 2.2.0, please use {@link HttpClientSampler}
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
ElementType.ANNOTATION_TYPE })
@@ -39,6 +40,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
@Inherited
@Documented
@Qualifier(ClientSampler.NAME)
+@Deprecated
public @interface ClientSampler {
/**
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java
new file mode 100644
index 000000000..fbf748196
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpClientSampler.java
@@ -0,0 +1,50 @@
+/*
+ * 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.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import brave.sampler.SamplerFunction;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * Annotate a client {@link brave.sampler.SamplerFunction} that should be injected to
+ * {@link brave.http.HttpTracing.Builder#clientSampler(SamplerFunction)}.
+ *
+ * @since 2.2.0
+ * @see Qualifier
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
+ ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@Qualifier(HttpClientSampler.NAME)
+public @interface HttpClientSampler {
+
+ /**
+ * Default name for Sleuth HTTP client sampler.
+ */
+ String NAME = "sleuthHttpClientSampler";
+
+}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java
new file mode 100644
index 000000000..a725de02d
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/HttpServerSampler.java
@@ -0,0 +1,50 @@
+/*
+ * 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.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import brave.sampler.SamplerFunction;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * Annotate a client {@link brave.sampler.SamplerFunction} that should be injected to
+ * {@link brave.http.HttpTracing.Builder#serverSampler(SamplerFunction)}.
+ *
+ * @since 2.2.0
+ * @see Qualifier
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
+ ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@Qualifier(HttpServerSampler.NAME)
+public @interface HttpServerSampler {
+
+ /**
+ * Default name for the Sleuth HTTP server sampler.
+ */
+ String NAME = "sleuthHttpServerSampler";
+
+}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java
index f0a807f4f..fccf26a3b 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ServerSampler.java
@@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
* @author Marcin Grzejszczak
* @since 2.0.0
* @see Qualifier
+ * @deprecated Since 2.2.0, please use {@link HttpServerSampler}
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
ElementType.ANNOTATION_TYPE })
@@ -39,6 +40,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
@Inherited
@Documented
@Qualifier(ServerSampler.NAME)
+@Deprecated
public @interface ServerSampler {
/**
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpSampler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternHttpServerSampler.java
similarity index 80%
rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpSampler.java
rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternHttpServerSampler.java
index 35e5f736c..4e00022f0 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpSampler.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternHttpServerSampler.java
@@ -18,8 +18,8 @@ package org.springframework.cloud.sleuth.instrument.web;
import java.util.regex.Pattern;
-import brave.http.HttpAdapter;
-import brave.http.HttpSampler;
+import brave.http.HttpRequest;
+import brave.sampler.SamplerFunction;
/**
* Doesn't sample a span if skip pattern is matched.
@@ -27,19 +27,19 @@ import brave.http.HttpSampler;
* @author Marcin Grzejszczak
* @since 2.0.0
*/
-class SleuthHttpSampler extends HttpSampler {
+class SkipPatternHttpServerSampler implements SamplerFunction {
private final SkipPatternProvider provider;
private Pattern pattern;
- SleuthHttpSampler(SkipPatternProvider provider) {
+ SkipPatternHttpServerSampler(SkipPatternProvider provider) {
this.provider = provider;
}
@Override
- public Boolean trySample(HttpAdapter adapter, Req request) {
- String url = adapter.path(request);
+ public Boolean trySample(HttpRequest request) {
+ String url = request.path();
boolean shouldSkip = pattern().matcher(url).matches();
if (shouldSkip) {
return false;
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java
index 7a9166c8f..6075139d5 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfiguration.java
@@ -21,12 +21,13 @@ import java.util.List;
import brave.ErrorParser;
import brave.Tracing;
-import brave.http.HttpAdapter;
import brave.http.HttpClientParser;
+import brave.http.HttpRequest;
import brave.http.HttpSampler;
import brave.http.HttpServerParser;
import brave.http.HttpTracing;
import brave.http.HttpTracingCustomizer;
+import brave.sampler.SamplerFunction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -63,22 +64,28 @@ public class TraceHttpAutoConfiguration {
// NOTE: stable bean name as might be used outside sleuth
HttpTracing httpTracing(Tracing tracing, SkipPatternProvider provider,
HttpClientParser clientParser, HttpServerParser serverParser,
- @ClientSampler HttpSampler clientSampler,
- @Nullable @ServerSampler HttpSampler serverSampler) {
- HttpSampler combinedSampler = combineUserProvidedSamplerWithSkipPatternSampler(
- serverSampler, provider);
+ @HttpClientSampler SamplerFunction httpClientSampler,
+ @Nullable @ServerSampler HttpSampler serverSampler,
+ @Nullable @HttpServerSampler SamplerFunction httpServerSampler) {
+ if (httpServerSampler == null) {
+ httpServerSampler = serverSampler;
+ }
+ SamplerFunction combinedSampler = combineUserProvidedSamplerWithSkipPatternSampler(
+ httpServerSampler, provider);
HttpTracing.Builder builder = HttpTracing.newBuilder(tracing)
.clientParser(clientParser).serverParser(serverParser)
- .clientSampler(clientSampler).serverSampler(combinedSampler);
+ .clientSampler(httpClientSampler).serverSampler(combinedSampler);
for (HttpTracingCustomizer customizer : this.httpTracingCustomizers) {
customizer.customize(builder);
}
return builder.build();
}
- private HttpSampler combineUserProvidedSamplerWithSkipPatternSampler(
- HttpSampler serverSampler, SkipPatternProvider provider) {
- SleuthHttpSampler skipPatternSampler = new SleuthHttpSampler(provider);
+ private SamplerFunction combineUserProvidedSamplerWithSkipPatternSampler(
+ @Nullable SamplerFunction serverSampler,
+ SkipPatternProvider provider) {
+ SkipPatternHttpServerSampler skipPatternSampler = new SkipPatternHttpServerSampler(
+ provider);
if (serverSampler == null) {
return skipPatternSampler;
}
@@ -118,9 +125,14 @@ public class TraceHttpAutoConfiguration {
}
@Bean
- @ConditionalOnMissingBean(name = ClientSampler.NAME)
- HttpSampler sleuthClientSampler(SleuthWebProperties sleuthWebProperties) {
- return new PathMatchingHttpSampler(sleuthWebProperties);
+ @ConditionalOnMissingBean(name = HttpClientSampler.NAME)
+ SamplerFunction sleuthHttpClientSampler(
+ @Nullable @ClientSampler HttpSampler sleuthClientSampler,
+ SleuthWebProperties sleuthWebProperties) {
+ if (sleuthClientSampler != null) {
+ return sleuthClientSampler;
+ }
+ return new SkipPatternHttpClientSampler(sleuthWebProperties);
}
}
@@ -130,25 +142,26 @@ public class TraceHttpAutoConfiguration {
*
* @author Adrian Cole
*/
-class CompositeHttpSampler extends HttpSampler {
+class CompositeHttpSampler implements SamplerFunction {
- private final HttpSampler left;
+ final SamplerFunction left;
- private final HttpSampler right;
+ final SamplerFunction right;
- CompositeHttpSampler(HttpSampler left, HttpSampler right) {
+ CompositeHttpSampler(SamplerFunction left,
+ SamplerFunction right) {
this.left = left;
this.right = right;
}
@Override
- public Boolean trySample(HttpAdapter adapter, Req request) {
+ public Boolean trySample(HttpRequest request) {
// If either decision is false, return false
- Boolean leftDecision = this.left.trySample(adapter, request);
+ Boolean leftDecision = this.left.trySample(request);
if (Boolean.FALSE.equals(leftDecision)) {
return false;
}
- Boolean rightDecision = this.right.trySample(adapter, request);
+ Boolean rightDecision = this.right.trySample(request);
if (Boolean.FALSE.equals(rightDecision)) {
return false;
}
@@ -160,7 +173,7 @@ class CompositeHttpSampler extends HttpSampler {
return leftDecision;
}
// Neither are null and at least one is true
- return leftDecision && rightDecision;
+ return rightDecision;
}
}
@@ -170,17 +183,17 @@ class CompositeHttpSampler extends HttpSampler {
*
* @author Marcin Grzejszczak
*/
-class PathMatchingHttpSampler extends HttpSampler {
+class SkipPatternHttpClientSampler implements SamplerFunction {
private final SleuthWebProperties properties;
- PathMatchingHttpSampler(SleuthWebProperties properties) {
+ SkipPatternHttpClientSampler(SleuthWebProperties properties) {
this.properties = properties;
}
@Override
- public Boolean trySample(HttpAdapter adapter, Req request) {
- String path = adapter.path(request);
+ public Boolean trySample(HttpRequest request) {
+ String path = request.path();
if (path == null) {
return null;
}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java
index 916b589b4..3028c6f90 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java
@@ -237,7 +237,8 @@ class RestTemplateInterceptorInjector {
private boolean hasTraceInterceptor(RestTemplate restTemplate) {
for (ClientHttpRequestInterceptor interceptor : restTemplate.getInterceptors()) {
- if (interceptor instanceof TracingClientHttpRequestInterceptor || interceptor instanceof LazyTracingClientHttpRequestInterceptor) {
+ if (interceptor instanceof TracingClientHttpRequestInterceptor
+ || interceptor instanceof LazyTracingClientHttpRequestInterceptor) {
return true;
}
}
diff --git a/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories b/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories
index db0e76446..4544463d5 100644
--- a/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories
@@ -20,6 +20,7 @@ org.springframework.cloud.sleuth.instrument.rxjava.RxJavaAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.web.TraceWebFluxAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.zuul.TraceZuulAutoConfiguration,\
+org.springframework.cloud.sleuth.instrument.rpc.TraceRpcAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.grpc.TraceGrpcAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.messaging.TraceMessagingAutoConfiguration,\
org.springframework.cloud.sleuth.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java
index dd767eb52..ee357b0c8 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationCustomizersTests.java
@@ -20,12 +20,14 @@ import brave.TracingCustomizer;
import brave.http.HttpTracingCustomizer;
import brave.propagation.CurrentTraceContextCustomizer;
import brave.propagation.ExtraFieldCustomizer;
+import brave.rpc.RpcTracingCustomizer;
import brave.sampler.Sampler;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.sleuth.instrument.rpc.TraceRpcAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration;
import org.springframework.context.annotation.Bean;
@@ -38,7 +40,8 @@ public class TraceAutoConfigurationCustomizersTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.sleuth.baggage-keys=my-baggage")
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
- TraceWebAutoConfiguration.class, TraceHttpAutoConfiguration.class))
+ TraceWebAutoConfiguration.class, TraceHttpAutoConfiguration.class,
+ TraceRpcAutoConfiguration.class))
.withUserConfiguration(Customizers.class);
@Test
@@ -60,6 +63,7 @@ public class TraceAutoConfigurationCustomizersTests {
then(bean.contextCustomizerApplied).isTrue();
then(bean.extraFieldCustomizerApplied).isTrue();
then(bean.httpCustomizerApplied).isTrue();
+ then(bean.rpcCustomizerApplied).isTrue();
}
@Configuration
@@ -73,6 +77,8 @@ public class TraceAutoConfigurationCustomizersTests {
boolean httpCustomizerApplied;
+ boolean rpcCustomizerApplied;
+
@Bean
TracingCustomizer sleuthTracingCustomizer() {
return builder -> tracingCustomizerApplied = true;
@@ -93,6 +99,11 @@ public class TraceAutoConfigurationCustomizersTests {
return builder -> httpCustomizerApplied = true;
}
+ @Bean
+ RpcTracingCustomizer sleuthRpcTracingCustomizer() {
+ return builder -> rpcCustomizerApplied = true;
+ }
+
@Bean
Sampler sampler() {
return Sampler.ALWAYS_SAMPLE;
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java
new file mode 100644
index 000000000..d5d9dbbe7
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java
@@ -0,0 +1,76 @@
+/*
+ * 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.rpc;
+
+import brave.rpc.RpcRequest;
+import brave.rpc.RpcRuleSampler;
+import brave.sampler.Matcher;
+import brave.sampler.RateLimitingSampler;
+import brave.sampler.Sampler;
+import brave.sampler.SamplerFunction;
+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.util.ArrayListSpanReporter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static brave.rpc.RpcRequestMatchers.methodEquals;
+import static brave.rpc.RpcRequestMatchers.serviceEquals;
+import static brave.sampler.Matchers.and;
+import static org.assertj.core.api.BDDAssertions.then;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = TraceRpcAutoConfigurationIntegrationTests.Config.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
+public class TraceRpcAutoConfigurationIntegrationTests {
+
+ @Autowired
+ @RpcServerSampler
+ SamplerFunction sampler;
+
+ @Test
+ public void should_inject_rpc_sampler() {
+ then(this.sampler).isNotNull();
+ }
+
+ @EnableAutoConfiguration
+ @Configuration
+ public static class Config {
+
+ @Bean
+ ArrayListSpanReporter reporter() {
+ return new ArrayListSpanReporter();
+ }
+
+ // tag::custom_rpc_server_sampler[]
+ @Bean(name = RpcServerSampler.NAME)
+ SamplerFunction myRpcSampler() {
+ Matcher userAuth = and(serviceEquals("users.UserService"),
+ methodEquals("GetUserToken"));
+ return RpcRuleSampler.newBuilder()
+ .putRule(serviceEquals("grpc.health.v1.Health"), Sampler.NEVER_SAMPLE)
+ .putRule(userAuth, RateLimitingSampler.create(100)).build();
+ }
+ // end::custom_rpc_server_sampler[]
+
+ }
+
+}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java
new file mode 100644
index 000000000..ba71b65ae
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationTests.java
@@ -0,0 +1,108 @@
+/*
+ * 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.rpc;
+
+import brave.rpc.RpcRequest;
+import brave.rpc.RpcTracing;
+import brave.sampler.SamplerFunction;
+import brave.sampler.SamplerFunctions;
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import static org.assertj.core.api.BDDAssertions.then;
+
+public class TraceRpcAutoConfigurationTests {
+
+ @Test
+ public void defaultsToBraveRpcClientSampler() {
+ contextRunner().run((context) -> {
+ SamplerFunction clientSampler = context.getBean(RpcTracing.class)
+ .clientSampler();
+
+ then(clientSampler).isSameAs(SamplerFunctions.deferDecision());
+ });
+ }
+
+ @Test
+ public void configuresUserProvidedRpcClientSampler() {
+ contextRunner().withUserConfiguration(RpcClientSamplerConfig.class)
+ .run((context) -> {
+ SamplerFunction clientSampler = context
+ .getBean(RpcTracing.class).clientSampler();
+
+ then(clientSampler).isSameAs(RpcClientSamplerConfig.INSTANCE);
+ });
+ }
+
+ @Test
+ public void defaultsToBraveRpcServerSampler() {
+ contextRunner().run((context) -> {
+ SamplerFunction serverSampler = context.getBean(RpcTracing.class)
+ .serverSampler();
+
+ then(serverSampler).isSameAs(SamplerFunctions.deferDecision());
+ });
+ }
+
+ @Test
+ public void configuresUserProvidedRpcServerSampler() {
+ contextRunner().withUserConfiguration(RpcServerSamplerConfig.class)
+ .run((context) -> {
+ SamplerFunction serverSampler = context
+ .getBean(RpcTracing.class).serverSampler();
+
+ then(serverSampler).isSameAs(RpcServerSamplerConfig.INSTANCE);
+ });
+ }
+
+ private ApplicationContextRunner contextRunner(String... propertyValues) {
+ return new ApplicationContextRunner().withPropertyValues(propertyValues)
+ .withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
+ TraceRpcAutoConfiguration.class,
+ TraceRpcAutoConfiguration.class));
+ }
+
+}
+
+@Configuration
+class RpcClientSamplerConfig {
+
+ static final SamplerFunction INSTANCE = request -> null;
+
+ @Bean(RpcClientSampler.NAME)
+ SamplerFunction sleuthRpcClientSampler() {
+ return INSTANCE;
+ }
+
+}
+
+@Configuration
+class RpcServerSamplerConfig {
+
+ static final SamplerFunction INSTANCE = request -> null;
+
+ @Bean(RpcServerSampler.NAME)
+ SamplerFunction sleuthRpcServerSampler() {
+ return INSTANCE;
+ }
+
+}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java
index 66bf56f65..51ce2c4cf 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/CompositeHttpSamplerTests.java
@@ -16,8 +16,8 @@
package org.springframework.cloud.sleuth.instrument.web;
-import brave.http.HttpAdapter;
-import brave.http.HttpSampler;
+import brave.http.HttpRequest;
+import brave.sampler.SamplerFunction;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,17 +31,15 @@ import static org.mockito.BDDMockito.given;
public class CompositeHttpSamplerTests {
@Mock
- HttpAdapter adapter;
+ SamplerFunction left;
@Mock
- HttpSampler left;
+ SamplerFunction right;
@Mock
- HttpSampler right;
+ HttpRequest request;
- HttpSampler sampler;
-
- Object request = new Object();
+ SamplerFunction sampler;
@Before
public void init() {
@@ -50,41 +48,41 @@ public class CompositeHttpSamplerTests {
@Test
public void should_return_null_on_both_null() {
- given(this.left.trySample(this.adapter, this.request)).willReturn(null);
- given(this.right.trySample(this.adapter, this.request)).willReturn(null);
+ given(this.left.trySample(this.request)).willReturn(null);
+ given(this.right.trySample(this.request)).willReturn(null);
- then(this.sampler.trySample(this.adapter, this.request)).isNull();
+ then(this.sampler.trySample(this.request)).isNull();
}
@Test
public void should_return_false_on_any_false() {
- given(this.left.trySample(this.adapter, this.request)).willReturn(false);
- given(this.right.trySample(this.adapter, this.request)).willReturn(null);
+ given(this.left.trySample(this.request)).willReturn(false);
+ given(this.right.trySample(this.request)).willReturn(null);
- then(this.sampler.trySample(this.adapter, this.request)).isFalse();
+ then(this.sampler.trySample(this.request)).isFalse();
- given(this.left.trySample(this.adapter, this.request)).willReturn(null);
- given(this.right.trySample(this.adapter, this.request)).willReturn(false);
+ given(this.left.trySample(this.request)).willReturn(null);
+ given(this.right.trySample(this.request)).willReturn(false);
- then(this.sampler.trySample(this.adapter, this.request)).isFalse();
+ then(this.sampler.trySample(this.request)).isFalse();
- given(this.left.trySample(this.adapter, this.request)).willReturn(false);
- given(this.right.trySample(this.adapter, this.request)).willReturn(true);
+ given(this.left.trySample(this.request)).willReturn(false);
+ given(this.right.trySample(this.request)).willReturn(true);
- then(this.sampler.trySample(this.adapter, this.request)).isFalse();
+ then(this.sampler.trySample(this.request)).isFalse();
- given(this.left.trySample(this.adapter, this.request)).willReturn(true);
- given(this.right.trySample(this.adapter, this.request)).willReturn(false);
+ given(this.left.trySample(this.request)).willReturn(true);
+ given(this.right.trySample(this.request)).willReturn(false);
- then(this.sampler.trySample(this.adapter, this.request)).isFalse();
+ then(this.sampler.trySample(this.request)).isFalse();
}
@Test
public void should_return_true_on_both_true() {
- given(this.left.trySample(this.adapter, this.request)).willReturn(true);
- given(this.right.trySample(this.adapter, this.request)).willReturn(true);
+ given(this.left.trySample(this.request)).willReturn(true);
+ given(this.right.trySample(this.request)).willReturn(true);
- then(this.sampler.trySample(this.adapter, this.request)).isTrue();
+ then(this.sampler.trySample(this.request)).isTrue();
}
}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpSamplerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternHttpServerSamplerTests.java
similarity index 72%
rename from spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpSamplerTests.java
rename to spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternHttpServerSamplerTests.java
index decbded42..49389a872 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SleuthHttpSamplerTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternHttpServerSamplerTests.java
@@ -18,7 +18,7 @@ package org.springframework.cloud.sleuth.instrument.web;
import java.util.regex.Pattern;
-import brave.http.HttpAdapter;
+import brave.http.HttpRequest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
@@ -31,27 +31,27 @@ import static org.assertj.core.api.BDDAssertions.then;
* @author Marcin Grzejszczak
*/
@RunWith(MockitoJUnitRunner.class)
-public class SleuthHttpSamplerTests {
+public class SkipPatternHttpServerSamplerTests {
@Mock
- HttpAdapter adapter;
+ HttpRequest request;
@Test
public void should_delegate_sampling_decision_if_pattern_is_not_matched() {
SkipPatternProvider provider = () -> Pattern.compile("foo");
- BDDMockito.given(this.adapter.path(BDDMockito.any())).willReturn("url");
- SleuthHttpSampler sampler = new SleuthHttpSampler(provider);
+ BDDMockito.given(this.request.path()).willReturn("url");
+ SkipPatternHttpServerSampler sampler = new SkipPatternHttpServerSampler(provider);
- then(sampler.trySample(this.adapter, new Object())).isNull();
+ then(sampler.trySample(this.request)).isNull();
}
@Test
public void should_not_sample_if_pattern_is_matched() {
SkipPatternProvider provider = () -> Pattern.compile(".*");
- BDDMockito.given(this.adapter.path(BDDMockito.any())).willReturn("url");
- SleuthHttpSampler sampler = new SleuthHttpSampler(provider);
+ BDDMockito.given(this.request.path()).willReturn("url");
+ SkipPatternHttpServerSampler sampler = new SkipPatternHttpServerSampler(provider);
- then(sampler.trySample(this.adapter, new Object())).isFalse();
+ then(sampler.trySample(this.request)).isFalse();
}
}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java
index 5447472a6..09498b586 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java
@@ -75,7 +75,8 @@ public class TraceFilterTests {
HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing)
.clientParser(new SleuthHttpClientParser(this.traceKeys))
.serverParser(new SleuthHttpServerParser(this.traceKeys, new ErrorParser()))
- .serverSampler(new SleuthHttpSampler(() -> Pattern.compile(""))).build();
+ .serverSampler(new SkipPatternHttpServerSampler(() -> Pattern.compile("")))
+ .build();
Filter filter = TracingFilter.create(this.httpTracing);
@@ -124,7 +125,9 @@ public class TraceFilterTests {
.clientParser(new SleuthHttpClientParser(this.traceKeys))
.serverParser(
new SleuthHttpServerParser(this.traceKeys, new ErrorParser()))
- .serverSampler(new SleuthHttpSampler(() -> Pattern.compile(""))).build();
+ .serverSampler(
+ new SkipPatternHttpServerSampler(() -> Pattern.compile("")))
+ .build();
return TracingFilter.create(httpTracing);
}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java
index 78e13db15..0e480a9e1 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java
@@ -23,9 +23,9 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import brave.Tracing;
-import brave.http.HttpAdapter;
-import brave.http.HttpSampler;
+import brave.http.HttpRequest;
import brave.sampler.Sampler;
+import brave.sampler.SamplerFunction;
import org.assertj.core.api.BDDAssertions;
import org.junit.After;
import org.junit.Before;
@@ -72,8 +72,8 @@ public class TraceFilterWebIntegrationTests {
ArrayListSpanReporter accumulator;
@Autowired
- @ServerSampler
- HttpSampler sampler;
+ @HttpServerSampler
+ SamplerFunction sampler;
@Autowired
Environment environment;
@@ -161,20 +161,16 @@ public class TraceFilterWebIntegrationTests {
}
// tag::custom_server_sampler[]
- @Bean(name = ServerSampler.NAME)
- HttpSampler myHttpSampler(SkipPatternProvider provider) {
+ @Bean(name = HttpServerSampler.NAME)
+ SamplerFunction myHttpSampler(SkipPatternProvider provider) {
Pattern pattern = provider.skipPattern();
- return new HttpSampler() {
-
- @Override
- public Boolean trySample(HttpAdapter adapter, Req request) {
- String url = adapter.path(request);
- boolean shouldSkip = pattern.matcher(url).matches();
- if (shouldSkip) {
- return false;
- }
- return null;
+ return request -> {
+ String url = request.path();
+ boolean shouldSkip = pattern.matcher(url).matches();
+ if (shouldSkip) {
+ return false;
}
+ return null;
};
}
// end::custom_server_sampler[]
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfigurationTests.java
new file mode 100644
index 000000000..a5206db89
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceHttpAutoConfigurationTests.java
@@ -0,0 +1,190 @@
+/*
+ * 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 brave.http.HttpAdapter;
+import brave.http.HttpRequest;
+import brave.http.HttpSampler;
+import brave.http.HttpTracing;
+import brave.sampler.SamplerFunction;
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.boot.test.context.runner.ContextConsumer;
+import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import static org.assertj.core.api.BDDAssertions.then;
+
+public class TraceHttpAutoConfigurationTests {
+
+ @Test
+ public void defaultsToSkipPatternHttpClientSampler() {
+ contextRunner().run((context) -> {
+ SamplerFunction clientSampler = context
+ .getBean(HttpTracing.class).clientRequestSampler();
+
+ then(clientSampler).isInstanceOf(SkipPatternHttpClientSampler.class);
+ });
+ }
+
+ @Test
+ public void configuresUserProvidedDeprecatedClientSampler() {
+ contextRunner().withUserConfiguration(DeprecatedClientSamplerConfig.class)
+ .run((context) -> {
+ SamplerFunction clientSampler = context
+ .getBean(HttpTracing.class).clientRequestSampler();
+
+ then(clientSampler).isSameAs(DeprecatedClientSamplerConfig.INSTANCE);
+ });
+ }
+
+ @Test
+ public void configuresUserProvidedHttpClientSampler() {
+ contextRunner().withUserConfiguration(HttpClientSamplerConfig.class)
+ .run((context) -> {
+ SamplerFunction clientSampler = context
+ .getBean(HttpTracing.class).clientRequestSampler();
+
+ then(clientSampler).isSameAs(HttpClientSamplerConfig.INSTANCE);
+ });
+ }
+
+ @Test
+ public void prefersUserProvidedHttpClientSampler() {
+ contextRunner().withUserConfiguration(DeprecatedClientSamplerConfig.class)
+ .withUserConfiguration(HttpClientSamplerConfig.class).run((context) -> {
+ SamplerFunction clientSampler = context
+ .getBean(HttpTracing.class).clientRequestSampler();
+
+ then(clientSampler).isSameAs(HttpClientSamplerConfig.INSTANCE);
+ });
+ }
+
+ @Test
+ public void defaultsToSkipPatternHttpServerSampler() {
+ contextRunner().run((context) -> {
+ SamplerFunction serverSampler = context
+ .getBean(HttpTracing.class).serverRequestSampler();
+
+ then(serverSampler).isInstanceOf(SkipPatternHttpServerSampler.class);
+ });
+ }
+
+ @Test
+ public void wrapsUserProvidedDeprecatedServerSampler() {
+ contextRunner().withUserConfiguration(DeprecatedServerSamplerConfig.class).run(
+ thenCompositeHttpServerSamplerOf(DeprecatedServerSamplerConfig.INSTANCE));
+ }
+
+ @Test
+ public void wrapsUserProvidedHttpServerSampler() {
+ contextRunner().withUserConfiguration(HttpServerSamplerConfig.class)
+ .run(thenCompositeHttpServerSamplerOf(HttpServerSamplerConfig.INSTANCE));
+ }
+
+ @Test
+ public void prefersUserProvidedUserProvidedHttpServerSampler() {
+ contextRunner().withUserConfiguration(HttpServerSamplerConfig.class)
+ .withUserConfiguration(DeprecatedServerSamplerConfig.class)
+ .run(thenCompositeHttpServerSamplerOf(HttpServerSamplerConfig.INSTANCE));
+ }
+
+ private ContextConsumer thenCompositeHttpServerSamplerOf(
+ SamplerFunction instance) {
+ return (context) -> {
+
+ SamplerFunction serverSampler = context
+ .getBean(HttpTracing.class).serverRequestSampler();
+
+ then(serverSampler).isInstanceOf(CompositeHttpSampler.class);
+
+ then(((CompositeHttpSampler) serverSampler).left)
+ .isInstanceOf(SkipPatternHttpServerSampler.class);
+ then(((CompositeHttpSampler) serverSampler).right).isSameAs(instance);
+ };
+ }
+
+ private ApplicationContextRunner contextRunner(String... propertyValues) {
+ return new ApplicationContextRunner().withPropertyValues(propertyValues)
+ .withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
+ TraceHttpAutoConfiguration.class,
+ TraceWebAutoConfiguration.class));
+ }
+
+}
+
+@Configuration
+class HttpClientSamplerConfig {
+
+ static final SamplerFunction INSTANCE = request -> null;
+
+ @Bean(HttpClientSampler.NAME)
+ SamplerFunction sleuthHttpClientSampler() {
+ return INSTANCE;
+ }
+
+}
+
+@Configuration
+class DeprecatedClientSamplerConfig {
+
+ static final HttpSampler INSTANCE = new HttpSampler() {
+ @Override
+ public Boolean trySample(HttpAdapter httpAdapter, Req req) {
+ return null;
+ }
+ };
+
+ @Bean(ClientSampler.NAME)
+ HttpSampler sleuthClientSampler() {
+ return INSTANCE;
+ }
+
+}
+
+@Configuration
+class HttpServerSamplerConfig {
+
+ static final SamplerFunction INSTANCE = request -> null;
+
+ @Bean(HttpServerSampler.NAME)
+ SamplerFunction sleuthHttpServerSampler() {
+ return INSTANCE;
+ }
+
+}
+
+@Configuration
+class DeprecatedServerSamplerConfig {
+
+ static final HttpSampler INSTANCE = new HttpSampler() {
+ @Override
+ public Boolean trySample(HttpAdapter httpAdapter, Req req) {
+ return null;
+ }
+ };
+
+ @Bean(ServerSampler.NAME)
+ HttpSampler sleuthServerSampler() {
+ return INSTANCE;
+ }
+
+}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java
index 3bf6ba104..a8f81a8ed 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java
@@ -104,7 +104,8 @@ public class TraceWebClientAutoConfigurationTests {
.containsOnlyElementsOf(Collections.singletonList(1));
}
- private void incrementNumberOfInstances(Map numberOfInstances, ClientHttpRequestInterceptor interceptor) {
+ private void incrementNumberOfInstances(Map numberOfInstances,
+ ClientHttpRequestInterceptor interceptor) {
Integer no = numberOfInstances.get(interceptor.getClass());
if (no == null) {
numberOfInstances.put(interceptor.getClass(), 1);
diff --git a/spring-cloud-sleuth-samples/pom.xml b/spring-cloud-sleuth-samples/pom.xml
index 6b2427694..2f144c023 100644
--- a/spring-cloud-sleuth-samples/pom.xml
+++ b/spring-cloud-sleuth-samples/pom.xml
@@ -73,7 +73,7 @@
io.zipkin.zipkin2
zipkin
- 2.16.0
+ 2.17.0