Merge branch '2.2.x'
This commit is contained in:
@@ -68,15 +68,15 @@ Here are the most relevant links from the OpenZipkin Brave project:
|
||||
|
||||
== Sampling
|
||||
|
||||
By default Spring Cloud Sleuth doesn't sample spans.
|
||||
That means that traces appear in logs but not in any remote store.
|
||||
For testing the default is often enough, and it probably is all you need if you use only the logs (for example, with an ELK aggregator).
|
||||
If you export span data to Zipkin, there is also an `Sampler.ALWAYS_SAMPLE` setting that exports everything, `RateLimitingSampler` setting that samples X transactions per second (defaults to `1000`) or `ProbabilityBasedSampler` setting that samples a fixed fraction of spans.
|
||||
Sampling only applies to tracing backends, such as Zipkin. Trace IDs appear in logs regardless of
|
||||
sample rate. Sampling is a way to prevent overloading the system, by consistently tracing some, but
|
||||
not all requests.
|
||||
|
||||
NOTE: The `RateLimitingSampler` is the default if you use `spring-cloud-sleuth-zipkin`.
|
||||
You can configure the rate limit by setting `spring.sleuth.sampler.rate`.
|
||||
The default rate of 10 traces per second is controlled by the `spring.sleuth.sampler.rate`
|
||||
property and applies when we know Sleuth is used for reasons besides logging. Use a rate above 100
|
||||
traces per second with extreme caution as it can overload your tracing system.
|
||||
|
||||
A sampler can be installed by creating a bean definition, as shown in the following example:
|
||||
The sampler can be set by Java Config also, as shown in the following example:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -86,8 +86,6 @@ include::{project-root}/spring-cloud-sleuth-core/src/test/java/org/springframewo
|
||||
TIP: You can set the HTTP header `b3` to `1`, or, when doing messaging, you can set the `spanFlags` header to `1`.
|
||||
Doing so forces the current request to be sampled regardless of configuration.
|
||||
|
||||
In order to use the rate-limited sampler set the `spring.sleuth.sampler.rate` property to choose an amount of traces to accept on a per-second interval. The minimum number is 0 and the max is 2,147,483,647 (max int).
|
||||
|
||||
== Baggage
|
||||
Baggage are fields that are propagated with the trace, optionally out of process. You can use
|
||||
properties to define fields that have no special configuration such as name mapping:
|
||||
|
||||
@@ -42,7 +42,6 @@ import zipkin2.reporter.ReporterMetrics;
|
||||
import zipkin2.reporter.metrics.micrometer.MicrometerReporterMetrics;
|
||||
|
||||
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.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -52,7 +51,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.cloud.sleuth.DefaultSpanNamer;
|
||||
import org.springframework.cloud.sleuth.LocalServiceName;
|
||||
import org.springframework.cloud.sleuth.SpanNamer;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageConfiguration;
|
||||
import org.springframework.cloud.sleuth.sampler.SamplerAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -72,8 +71,7 @@ import org.springframework.util.StringUtils;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
|
||||
@EnableConfigurationProperties(SleuthProperties.class)
|
||||
@AutoConfigureAfter(TraceBaggageAutoConfiguration.class)
|
||||
@Import(SamplerAutoConfiguration.class)
|
||||
@Import({ TraceBaggageConfiguration.class, SamplerAutoConfiguration.class })
|
||||
public class TraceAutoConfiguration {
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,20 +38,20 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
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.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
* Auto-configuration} for {@link BaggagePropagation}.
|
||||
* {@link Configuration} for {@link BaggagePropagation}.
|
||||
* <p>
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
@@ -59,12 +59,43 @@ import org.springframework.context.annotation.Configuration;
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
|
||||
@AutoConfigureBefore(TraceAutoConfiguration.class)
|
||||
@EnableConfigurationProperties(SleuthBaggageProperties.class)
|
||||
public class TraceBaggageAutoConfiguration {
|
||||
public class TraceBaggageConfiguration {
|
||||
|
||||
static final Log logger = LogFactory.getLog(TraceBaggageAutoConfiguration.class);
|
||||
static final Log logger = LogFactory.getLog(TraceBaggageConfiguration.class);
|
||||
|
||||
static final String LOCAL_KEYS = "spring.sleuth.local-keys";
|
||||
static final String BAGGAGE_KEYS = "spring.sleuth.baggage-keys";
|
||||
static final String PROPAGATION_KEYS = "spring.sleuth.propagation-keys";
|
||||
static final String WHITELISTED_KEYS = "spring.sleuth.propagation.tag.whitelisted-keys";
|
||||
static final String WHITELISTED_MDC_KEYS = "spring.sleuth.log.slf4j.whitelisted-mdc-keys";
|
||||
|
||||
// These List<String> beans allow us to get deprecated property values, regardless of
|
||||
// if they were comma or yaml encoded. This keeps them out of SleuthBaggageProperties
|
||||
|
||||
@Bean(BAGGAGE_KEYS)
|
||||
@ConfigurationProperties(BAGGAGE_KEYS)
|
||||
List<String> baggageKeys() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Bean(LOCAL_KEYS)
|
||||
@ConfigurationProperties(LOCAL_KEYS)
|
||||
List<String> localKeys() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Bean(PROPAGATION_KEYS)
|
||||
@ConfigurationProperties(PROPAGATION_KEYS)
|
||||
List<String> propagationKeys() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Bean(WHITELISTED_MDC_KEYS)
|
||||
@ConfigurationProperties(WHITELISTED_MDC_KEYS)
|
||||
List<String> whiteListedMDCKeys() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
List<BaggagePropagationCustomizer> baggagePropagationCustomizers = new ArrayList<>();
|
||||
@@ -92,35 +123,31 @@ public class TraceBaggageAutoConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
Propagation.Factory sleuthPropagation(
|
||||
BaggagePropagation.FactoryBuilder factoryBuilder,
|
||||
@Value("${spring.sleuth.baggage-keys:}") String baggageKeys,
|
||||
@Value("${spring.sleuth.local-keys:}") String localKeys,
|
||||
@Value("${spring.sleuth.propagation-keys:}") String propagationKeys,
|
||||
@Qualifier(BAGGAGE_KEYS) List<String> baggageKeys,
|
||||
@Qualifier(LOCAL_KEYS) List<String> localKeys,
|
||||
@Qualifier(PROPAGATION_KEYS) List<String> propagationKeys,
|
||||
SleuthBaggageProperties sleuthBaggageProperties) {
|
||||
|
||||
Set<String> localFields = redirectOldPropertyToNew("spring.sleuth.local-keys",
|
||||
collectFieldsFromProperty(localKeys),
|
||||
Set<String> localFields = redirectOldPropertyToNew(LOCAL_KEYS, localKeys,
|
||||
"spring.sleuth.baggage.local-fields",
|
||||
sleuthBaggageProperties.getLocalFields());
|
||||
for (String fieldName : localFields) {
|
||||
factoryBuilder.add(SingleBaggageField.local(BaggageField.create(fieldName)));
|
||||
}
|
||||
|
||||
Set<String> remoteFields = redirectOldPropertyToNew(
|
||||
"spring.sleuth.propagation-keys",
|
||||
collectFieldsFromProperty(propagationKeys),
|
||||
"spring.sleuth.baggage.remote-fields",
|
||||
Set<String> remoteFields = redirectOldPropertyToNew(PROPAGATION_KEYS,
|
||||
propagationKeys, "spring.sleuth.baggage.remote-fields",
|
||||
sleuthBaggageProperties.getRemoteFields());
|
||||
for (String fieldName : remoteFields) {
|
||||
factoryBuilder.add(SingleBaggageField.remote(BaggageField.create(fieldName)));
|
||||
}
|
||||
|
||||
if (!baggageKeys.isEmpty()) {
|
||||
logger.warn(
|
||||
"'spring.sleuth.baggage-keys' will be removed in a future release.\n"
|
||||
+ "To change header names define a @Bean of type "
|
||||
+ SingleBaggageField.class.getName());
|
||||
logger.warn("'" + BAGGAGE_KEYS + "' will be removed in a future release.\n"
|
||||
+ "To change header names define a @Bean of type "
|
||||
+ SingleBaggageField.class.getName());
|
||||
|
||||
for (String key : collectFieldsFromProperty(baggageKeys)) {
|
||||
for (String key : baggageKeys) {
|
||||
factoryBuilder.add(SingleBaggageField.newBuilder(BaggageField.create(key))
|
||||
.addKeyName("baggage-" + key) // for HTTP
|
||||
.addKeyName("baggage_" + key) // for messaging
|
||||
@@ -134,26 +161,7 @@ public class TraceBaggageAutoConfiguration {
|
||||
return factoryBuilder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
FinishedSpanHandler baggageTagFinishedSpanHandler(
|
||||
@Value("${spring.sleuth.propagation.tag.whitelisted-keys:}") String whitelistedKeys,
|
||||
SleuthBaggageProperties sleuthBaggageProperties) {
|
||||
|
||||
Set<String> tagFields = redirectOldPropertyToNew(
|
||||
"spring.sleuth.propagation.tag.whitelisted-keys",
|
||||
collectFieldsFromProperty(whitelistedKeys),
|
||||
"spring.sleuth.baggage.tag-fields",
|
||||
sleuthBaggageProperties.getTagFields());
|
||||
|
||||
if (tagFields.isEmpty()) {
|
||||
return FinishedSpanHandler.NOOP; // Brave ignores these
|
||||
}
|
||||
|
||||
return new BaggageTagFinishedSpanHandler(tagFields.stream()
|
||||
.map(BaggageField::create).toArray(BaggageField[]::new));
|
||||
}
|
||||
|
||||
static Set<String> redirectOldPropertyToNew(String oldProperty, Set<String> oldValue,
|
||||
static Set<String> redirectOldPropertyToNew(String oldProperty, List<String> oldValue,
|
||||
String newProperty, List<String> newValue) {
|
||||
Set<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
|
||||
result.addAll(newValue);
|
||||
@@ -178,13 +186,11 @@ public class TraceBaggageAutoConfiguration {
|
||||
@ConditionalOnProperty(value = "spring.sleuth.baggage.correlation-enabled",
|
||||
matchIfMissing = true)
|
||||
ScopeDecorator correlationScopeDecorator(
|
||||
@Value("${spring.sleuth.log.slf4j.whitelisted-mdc-keys:}") String whitelistedKeys,
|
||||
@Qualifier(WHITELISTED_MDC_KEYS) List<String> whiteListedMDCKeys,
|
||||
SleuthBaggageProperties sleuthBaggageProperties) {
|
||||
|
||||
Set<String> correlationFields = redirectOldPropertyToNew(
|
||||
"spring.sleuth.log.slf4j.whitelisted-mdc-keys",
|
||||
collectFieldsFromProperty(whitelistedKeys),
|
||||
"spring.sleuth.baggage.correlation-fields",
|
||||
Set<String> correlationFields = redirectOldPropertyToNew(WHITELISTED_MDC_KEYS,
|
||||
whiteListedMDCKeys, "spring.sleuth.baggage.correlation-fields",
|
||||
sleuthBaggageProperties.getCorrelationFields());
|
||||
|
||||
// Add fields from properties
|
||||
@@ -201,19 +207,74 @@ public class TraceBaggageAutoConfiguration {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static Set<String> collectFieldsFromProperty(String value) {
|
||||
Set<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
|
||||
for (String fieldName : value.split(",")) {
|
||||
if (fieldName == null) {
|
||||
continue;
|
||||
}
|
||||
fieldName = fieldName.trim();
|
||||
if (fieldName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
result.add(fieldName);
|
||||
/**
|
||||
* This has to be conditional as it creates a bean of type
|
||||
* {@link FinishedSpanHandler}.
|
||||
*
|
||||
* <p>
|
||||
* {@link FinishedSpanHandler} beans, even if {@link FinishedSpanHandler#NOOP}, can
|
||||
* trigger {@code org.springframework.cloud.sleuth.sampler.SamplerCondition}
|
||||
*/
|
||||
@Configuration
|
||||
@Conditional(BaggageTagFinishedSpanHandlerCondition.class)
|
||||
@EnableConfigurationProperties(SleuthBaggageProperties.class)
|
||||
static class BaggageTagFinishedSpanHandlerConfiguration {
|
||||
|
||||
@Bean(WHITELISTED_KEYS)
|
||||
@ConfigurationProperties(WHITELISTED_KEYS)
|
||||
List<String> whiteListedKeys() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return result;
|
||||
|
||||
@Bean
|
||||
FinishedSpanHandler baggageTagFinishedSpanHandler(
|
||||
@Qualifier(WHITELISTED_KEYS) List<String> whiteListedKeys,
|
||||
SleuthBaggageProperties sleuthBaggageProperties) {
|
||||
|
||||
Set<String> tagFields = redirectOldPropertyToNew(WHITELISTED_KEYS,
|
||||
whiteListedKeys, "spring.sleuth.baggage.tag-fields",
|
||||
sleuthBaggageProperties.getTagFields());
|
||||
|
||||
if (tagFields.isEmpty()) {
|
||||
return FinishedSpanHandler.NOOP; // Brave ignores these
|
||||
}
|
||||
|
||||
return new BaggageTagFinishedSpanHandler(tagFields.stream()
|
||||
.map(BaggageField::create).toArray(BaggageField[]::new));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* We need a special condition as it users could use either comma or yaml encoding,
|
||||
* possibly with a deprecated prefix.
|
||||
*/
|
||||
static class BaggageTagFinishedSpanHandlerCondition extends AnyNestedCondition {
|
||||
|
||||
BaggageTagFinishedSpanHandlerCondition() {
|
||||
super(ConfigurationPhase.PARSE_CONFIGURATION);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty("spring.sleuth.baggage.tag-fields")
|
||||
static class TagFieldsProperty {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty("spring.sleuth.baggage.tag-fields[0]")
|
||||
static class TagFieldsYamlListProperty {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(WHITELISTED_KEYS)
|
||||
static class WhitelistedKeysProperty {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(WHITELISTED_KEYS + "[0]")
|
||||
static class WhitelistedKeysYamlListProperty {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.sampler;
|
||||
|
||||
import brave.sampler.CountingSampler;
|
||||
import brave.sampler.Sampler;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -23,12 +24,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* {@linkplain Configuration configuration} for {@link Sampler}.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @see SamplerCondition
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -44,14 +47,17 @@ public class SamplerAutoConfiguration {
|
||||
return Sampler.NEVER_SAMPLE;
|
||||
}
|
||||
|
||||
// NOTE: Brave's default samplers return Sampler.NEVER_SAMPLE if the config implies
|
||||
// that
|
||||
static Sampler samplerFromProps(SamplerProperties config) {
|
||||
if (config.getProbability() != null) {
|
||||
return new ProbabilityBasedSampler(config);
|
||||
return CountingSampler.create(config.getProbability());
|
||||
}
|
||||
return new RateLimitingSampler(config);
|
||||
return brave.sampler.RateLimitingSampler.create(config.getRate());
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(SamplerCondition.class)
|
||||
@ConditionalOnBean(
|
||||
type = "org.springframework.cloud.context.scope.refresh.RefreshScope")
|
||||
protected static class RefreshScopedSamplerConfiguration {
|
||||
@@ -60,12 +66,18 @@ public class SamplerAutoConfiguration {
|
||||
@RefreshScope
|
||||
@ConditionalOnMissingBean
|
||||
public Sampler defaultTraceSampler(SamplerProperties config) {
|
||||
return samplerFromProps(config);
|
||||
// TODO: Rewrite: refresh should replace the sampler, not change its state
|
||||
// internally
|
||||
if (config.getProbability() != null) {
|
||||
return new ProbabilityBasedSampler(config);
|
||||
}
|
||||
return new RateLimitingSampler(config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(SamplerCondition.class)
|
||||
@ConditionalOnMissingBean(
|
||||
type = "org.springframework.cloud.context.scope.refresh.RefreshScope")
|
||||
protected static class NonRefreshScopeSamplerConfiguration {
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.sampler;
|
||||
|
||||
import brave.TracingCustomizer;
|
||||
import brave.handler.FinishedSpanHandler;
|
||||
import brave.sampler.Sampler;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
|
||||
/**
|
||||
* Sleuth 1.x optimized for log-correlation only. Unless "spring-cloud-sleuth-zipkin" was
|
||||
* present, the sampler defaulted to {@link Sampler#NEVER_SAMPLE}. This was to ensure the
|
||||
* log only nodes never set the sampled flag.
|
||||
*
|
||||
* <p>
|
||||
* "spring-cloud-sleuth-zipkin" obviated the {@link Sampler#NEVER_SAMPLE} default by
|
||||
* importing {@link SamplerAutoConfiguration}. Nothing else did, so sampling properties
|
||||
* were effectively ignored unless "spring-cloud-sleuth-zipkin" was in use, or something
|
||||
* else similarly imported {@link SamplerAutoConfiguration}.
|
||||
*
|
||||
* <p>
|
||||
* During a review of Wavefront integration, it was considered not correct to have other
|
||||
* code import {@link SamplerAutoConfiguration}. To avoid that, retain the old behaviour
|
||||
* about log only nodes, and also not pin configuration to Zipkin involves a more complex
|
||||
* condition.
|
||||
*
|
||||
* <p>
|
||||
* This condition looks for signs of non-default setup which likely requires sampling
|
||||
* configuration. It passes on one of the following beans exist:
|
||||
*
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>{@code zipkin2.reporter.Reporter} - what's used by Zipkin or others like
|
||||
* Stackdriver</li>
|
||||
* <li>{@link FinishedSpanHandler} - only accepts sampled data</li>
|
||||
* <li>{@link TracingCustomizer} - can configure one of the above</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* An integrated test that shows {@link Sampler#NEVER_SAMPLE} is default on fail exists in
|
||||
* {@code TraceAutoConfigurationTests} intentionally, as users now needn't import
|
||||
* {@link SamplerAutoConfiguration} directly.
|
||||
*/
|
||||
final class SamplerCondition extends AnyNestedCondition {
|
||||
|
||||
SamplerCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
// zipkin2.reporter.Reporter is in the classpath here, but technically it is optional
|
||||
@ConditionalOnBean(type = "zipkin2.reporter.Reporter")
|
||||
static final class ReporterAvailable {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnBean(FinishedSpanHandler.class)
|
||||
static final class FinishedSpanHandlerAvailable {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnBean(TracingCustomizer.class)
|
||||
static final class TracingCustomizerAvailable {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
# Auto Configuration
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration,\
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.junit.jupiter.api.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.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.messaging.TraceMessagingAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.rpc.TraceRpcAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration;
|
||||
@@ -44,8 +43,8 @@ public class TraceAutoConfigurationCustomizersTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, TraceWebAutoConfiguration.class,
|
||||
TraceHttpAutoConfiguration.class, TraceRpcAutoConfiguration.class,
|
||||
TraceWebAutoConfiguration.class, TraceHttpAutoConfiguration.class,
|
||||
TraceRpcAutoConfiguration.class,
|
||||
FakeSpringMessagingAutoConfiguration.class,
|
||||
TraceMessagingAutoConfiguration.class))
|
||||
.withUserConfiguration(Customizers.class);
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -36,8 +35,7 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||
public class TraceAutoConfigurationPropagationCustomizationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class));
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void stillCreatesDefault() {
|
||||
|
||||
@@ -26,11 +26,14 @@ import brave.baggage.BaggagePropagationCustomizer;
|
||||
import brave.propagation.B3SinglePropagation;
|
||||
import brave.propagation.Propagation;
|
||||
import brave.propagation.TraceContextOrSamplingFlags;
|
||||
import brave.sampler.RateLimitingSampler;
|
||||
import brave.sampler.Sampler;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import zipkin2.reporter.InMemoryReporterMetrics;
|
||||
import zipkin2.reporter.Reporter;
|
||||
import zipkin2.reporter.ReporterMetrics;
|
||||
import zipkin2.reporter.metrics.micrometer.MicrometerReporterMetrics;
|
||||
|
||||
@@ -38,18 +41,16 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
public class TraceAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class));
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void should_apply_micrometer_reporter_metrics_when_meter_registry_bean_present() {
|
||||
void should_apply_micrometer_reporter_metrics_when_meter_registry_bean_present() {
|
||||
this.contextRunner.withUserConfiguration(WithMeterRegistry.class)
|
||||
.run((context) -> {
|
||||
ReporterMetrics bean = context.getBean(ReporterMetrics.class);
|
||||
@@ -60,7 +61,7 @@ public class TraceAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_apply_in_memory_metrics_when_meter_registry_bean_missing() {
|
||||
void should_apply_in_memory_metrics_when_meter_registry_bean_missing() {
|
||||
this.contextRunner.run((context) -> {
|
||||
ReporterMetrics bean = context.getBean(ReporterMetrics.class);
|
||||
|
||||
@@ -69,7 +70,7 @@ public class TraceAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_apply_in_memory_metrics_when_meter_registry_class_missing() {
|
||||
void should_apply_in_memory_metrics_when_meter_registry_class_missing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(MeterRegistry.class))
|
||||
.run((context) -> {
|
||||
ReporterMetrics bean = context.getBean(ReporterMetrics.class);
|
||||
@@ -78,8 +79,48 @@ public class TraceAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates
|
||||
* {@link org.springframework.cloud.sleuth.sampler.SamplerAutoConfigurationTests}
|
||||
* intentionally, to ensure configuration condition bugs do not exist.
|
||||
*/
|
||||
@Test
|
||||
public void should_use_B3Propagation_factory_if_no_have_any_config() {
|
||||
void should_use_NEVER_SAMPLER_when_only_logging() {
|
||||
this.contextRunner.run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isSameAs(Sampler.NEVER_SAMPLE);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates
|
||||
* {@link org.springframework.cloud.sleuth.sampler.SamplerAutoConfigurationTests}
|
||||
* intentionally, to ensure configuration condition bugs do not exist.
|
||||
*/
|
||||
@Test
|
||||
void should_use_RateLimitedSampler_when_reporting() {
|
||||
this.contextRunner.withUserConfiguration(WithReporter.class).run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isInstanceOf(RateLimitingSampler.class);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates
|
||||
* {@link org.springframework.cloud.sleuth.sampler.SamplerAutoConfigurationTests}
|
||||
* intentionally, to ensure configuration condition bugs do not exist.
|
||||
*/
|
||||
@Test
|
||||
void should_override_sampler() {
|
||||
this.contextRunner.withUserConfiguration(WithReporter.class, WithSampler.class)
|
||||
.run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isSameAs(Sampler.ALWAYS_SAMPLE);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_use_B3Propagation_factory_by_default() {
|
||||
this.contextRunner.run((context -> {
|
||||
final Propagation.Factory bean = context.getBean(Propagation.Factory.class);
|
||||
BDDAssertions.then(bean).isInstanceOf(Propagation.Factory.class);
|
||||
@@ -87,7 +128,7 @@ public class TraceAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_use_baggageBean() {
|
||||
void should_use_baggageBean() {
|
||||
this.contextRunner.withUserConfiguration(WithBaggageBeans.class, Baggage.class)
|
||||
.run((context -> {
|
||||
final Baggage bean = context.getBean(Baggage.class);
|
||||
@@ -98,7 +139,7 @@ public class TraceAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_use_local_keys_from_properties() {
|
||||
void should_use_local_keys_from_properties() {
|
||||
this.contextRunner.withPropertyValues("spring.sleuth.baggage.local-fields=bp")
|
||||
.withUserConfiguration(Baggage.class).run((context -> {
|
||||
final Baggage bean = context.getBean(Baggage.class);
|
||||
@@ -108,7 +149,7 @@ public class TraceAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_combine_baggage_beans_and_properties() {
|
||||
void should_combine_baggage_beans_and_properties() {
|
||||
this.contextRunner.withPropertyValues("spring.sleuth.baggage.local-fields=bp")
|
||||
.withUserConfiguration(WithBaggageBeans.class, Baggage.class)
|
||||
.run((context -> {
|
||||
@@ -121,7 +162,7 @@ public class TraceAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_use_baggagePropagationFactoryBuilder_bean() {
|
||||
void should_use_baggagePropagationFactoryBuilder_bean() {
|
||||
// BaggagePropagation.FactoryBuilder unwraps itself if there are no baggage fields
|
||||
// defined
|
||||
this.contextRunner
|
||||
@@ -174,6 +215,36 @@ public class TraceAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithReporter {
|
||||
|
||||
@Bean
|
||||
Reporter<zipkin2.Span> spanReporter() {
|
||||
return zipkin2.Span::toString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithSampler {
|
||||
|
||||
@Bean
|
||||
Sampler alwaysSampler() {
|
||||
return Sampler.ALWAYS_SAMPLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithLocalKeys {
|
||||
|
||||
@Bean
|
||||
MeterRegistry meterRegistry() {
|
||||
return new SimpleMeterRegistry();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithBaggagePropagationFactoryBuilderBean {
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.autoconfig;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import brave.Tracing;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -25,22 +23,22 @@ import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
@SpringBootTest(classes = TraceAutoConfigurationWithDisabledSleuthTests.Config.class,
|
||||
properties = "spring.sleuth.enabled=false",
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(
|
||||
// WebEnvironment.NONE will not read a Yaml profile
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = TraceAutoConfigurationWithDisabledSleuthTests.Config.class)
|
||||
@ActiveProfiles("disabled")
|
||||
@DirtiesContext
|
||||
@ExtendWith(OutputCaptureExtension.class)
|
||||
public class TraceAutoConfigurationWithDisabledSleuthTests {
|
||||
|
||||
@@ -50,6 +48,10 @@ public class TraceAutoConfigurationWithDisabledSleuthTests {
|
||||
@Autowired(required = false)
|
||||
Tracing tracing;
|
||||
|
||||
@Autowired
|
||||
@Value("${spring.application.name:}")
|
||||
String applicationName;
|
||||
|
||||
@Test
|
||||
public void shouldStartContext() {
|
||||
BDDAssertions.then(this.tracing).isNull();
|
||||
@@ -59,6 +61,12 @@ public class TraceAutoConfigurationWithDisabledSleuthTests {
|
||||
public void shouldNotContainAnyTracingInfoInTheLogs(CapturedOutput capture) {
|
||||
log.info("hello");
|
||||
|
||||
assertThat(applicationName).isEqualTo("foo"); // prove bootstrap-disabled.yml
|
||||
// loaded
|
||||
|
||||
// spring.application.name is put in the log format by
|
||||
// TraceEnvironmentPostProcessor
|
||||
// checking for the service name here ensures this isn't accidentally loaded
|
||||
BDDAssertions.then(capture.toString()).doesNotContain("[foo");
|
||||
}
|
||||
|
||||
@@ -66,27 +74,6 @@ public class TraceAutoConfigurationWithDisabledSleuthTests {
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public FactoryBean<SecureRandom> secureRandom() {
|
||||
return new FactoryBean<SecureRandom>() {
|
||||
|
||||
@Override
|
||||
public SecureRandom getObject() throws Exception {
|
||||
return new SecureRandom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return SecureRandom.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,26 +23,27 @@ import brave.ScopedSpan;
|
||||
import brave.Tracer;
|
||||
import brave.baggage.BaggageField;
|
||||
import brave.propagation.TraceContext;
|
||||
import brave.sampler.Sampler;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
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.ActiveProfiles;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Taras Danylchuk
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
properties = { "spring.profiles.active=baggage" }, // intentionally test yaml
|
||||
classes = BaggageTagFinishedSpanHandlerTest.TestConfiguration.class)
|
||||
@SpringBootTest(
|
||||
// WebEnvironment.NONE will not read a Yaml profile
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = BaggageTagFinishedSpanHandlerTest.Config.class)
|
||||
@ActiveProfiles("baggage") // application-baggage.yml
|
||||
public class BaggageTagFinishedSpanHandlerTest {
|
||||
|
||||
static final BaggageField COUNTRY_CODE = BaggageField.create("country-code");
|
||||
@@ -76,22 +77,15 @@ public class BaggageTagFinishedSpanHandlerTest {
|
||||
assertThat(tags).containsEntry(COUNTRY_CODE.name(), "FO");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableConfigurationProperties(SleuthBaggageProperties.class)
|
||||
public static class TestConfiguration {
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public ArrayListSpanReporter arrayListSpanReporter(
|
||||
SleuthBaggageProperties properties) {
|
||||
ArrayListSpanReporter spanReporter() {
|
||||
return new ArrayListSpanReporter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Sampler alwaysSampler() {
|
||||
return Sampler.ALWAYS_SAMPLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,13 +46,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.tuple;
|
||||
import static org.assertj.core.api.InstanceOfAssertFactories.array;
|
||||
|
||||
public class TraceBaggageAutoConfigurationTests {
|
||||
public class TraceBaggageConfigurationTests {
|
||||
|
||||
static final String[] EMPTY_ARRAY = {};
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(TraceBaggageAutoConfiguration.class));
|
||||
.withConfiguration(AutoConfigurations.of(TraceBaggageConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void shouldCreateLocalFields() {
|
||||
@@ -125,6 +124,16 @@ public class TraceBaggageAutoConfigurationTests {
|
||||
.containsOnly("x-vcap-request-id", "country-code"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateTagHandler_yaml() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.sleuth.baggage.tag-fields[0]=x-vcap-request-id",
|
||||
"spring.sleuth.baggage.tag-fields[1]=country-code")
|
||||
.run((context) -> assertThatFieldNamesToTag(context)
|
||||
.containsOnly("x-vcap-request-id", "country-code"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateTagHandler_oldProperty() {
|
||||
this.contextRunner.withPropertyValues(
|
||||
@@ -133,6 +142,15 @@ public class TraceBaggageAutoConfigurationTests {
|
||||
.containsOnly("x-vcap-request-id", "country-code"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateTagHandler_oldProperty_yaml() {
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.sleuth.propagation.tag.whitelisted-keys[0]=x-vcap-request-id",
|
||||
"spring.sleuth.propagation.tag.whitelisted-keys[1]=country-code")
|
||||
.run((context) -> assertThatFieldNamesToTag(context)
|
||||
.containsOnly("x-vcap-request-id", "country-code"));
|
||||
}
|
||||
|
||||
static AbstractListAssert<?, List<? extends String>, String, ObjectAssert<String>> assertThatFieldNamesToTag(
|
||||
AssertableApplicationContext context) {
|
||||
return assertThat(context.getBean(FinishedSpanHandler.class))
|
||||
@@ -25,7 +25,6 @@ import org.junit.jupiter.api.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.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -78,8 +77,6 @@ public class TraceRpcAutoConfigurationTests {
|
||||
private ApplicationContextRunner contextRunner(String... propertyValues) {
|
||||
return new ApplicationContextRunner().withPropertyValues(propertyValues)
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class,
|
||||
TraceRpcAutoConfiguration.class,
|
||||
TraceRpcAutoConfiguration.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.springframework.boot.context.annotation.UserConfigurations;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -58,8 +57,7 @@ public class SkipPatternProviderConfigTest {
|
||||
InfoEndpointAutoConfiguration.class,
|
||||
HealthEndpointAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, TraceAutoConfiguration.class,
|
||||
TraceWebAutoConfiguration.class));
|
||||
TraceAutoConfiguration.class, TraceWebAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void should_return_null_when_cleared() throws Exception {
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
|
||||
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.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -195,7 +194,6 @@ public class TraceHttpAutoConfigurationTests {
|
||||
private ApplicationContextRunner contextRunner(String... propertyValues) {
|
||||
return new ApplicationContextRunner().withPropertyValues(propertyValues)
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class,
|
||||
TraceHttpAutoConfiguration.class,
|
||||
TraceWebAutoConfiguration.class));
|
||||
}
|
||||
|
||||
@@ -16,44 +16,170 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.sampler;
|
||||
|
||||
import brave.Tracing;
|
||||
import brave.TracingCustomizer;
|
||||
import brave.handler.FinishedSpanHandler;
|
||||
import brave.handler.MutableSpan;
|
||||
import brave.propagation.TraceContext;
|
||||
import brave.sampler.RateLimitingSampler;
|
||||
import brave.sampler.Sampler;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.reporter.Reporter;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
* @since
|
||||
*/
|
||||
// TODO: missing spring cloud context tests
|
||||
public class SamplerAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(SamplerAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void should_use_probability_sampler_when_property_set() {
|
||||
SamplerProperties properties = new SamplerProperties();
|
||||
properties.setProbability(10f);
|
||||
|
||||
Sampler sampler = SamplerAutoConfiguration.samplerFromProps(properties);
|
||||
|
||||
BDDAssertions.then(sampler).isInstanceOf(ProbabilityBasedSampler.class);
|
||||
void should_use_NEVER_SAMPLER_when_only_logging() {
|
||||
this.contextRunner.run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isSameAs(Sampler.NEVER_SAMPLE);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_use_rate_limiting_sampler_when_probability_not_set() {
|
||||
void should_use_RateLimitedSampler_withFinishedSpanHandler() {
|
||||
this.contextRunner.withUserConfiguration(WithFinishedSpanHandler.class)
|
||||
.run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isInstanceOf(RateLimitingSampler.class);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_use_RateLimitedSampler_withReporter() {
|
||||
this.contextRunner.withUserConfiguration(WithReporter.class).run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isInstanceOf(RateLimitingSampler.class);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_use_RateLimitedSampler_withTracingCustomizer() {
|
||||
this.contextRunner.withUserConfiguration(WithTracingCustomizer.class)
|
||||
.run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isInstanceOf(RateLimitingSampler.class);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_override_sampler() {
|
||||
this.contextRunner.withUserConfiguration(WithReporter.class, WithSampler.class)
|
||||
.run((context -> {
|
||||
final Sampler bean = context.getBean(Sampler.class);
|
||||
BDDAssertions.then(bean).isSameAs(Sampler.ALWAYS_SAMPLE);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void samplerFromProps_probability() {
|
||||
SamplerProperties properties = new SamplerProperties();
|
||||
properties.setProbability(0.01f);
|
||||
|
||||
Sampler sampler = SamplerAutoConfiguration.samplerFromProps(properties);
|
||||
|
||||
BDDAssertions.then(sampler).isInstanceOf(brave.sampler.CountingSampler.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void samplerFromProps_rateLimit() {
|
||||
SamplerProperties properties = new SamplerProperties();
|
||||
|
||||
Sampler sampler = SamplerAutoConfiguration.samplerFromProps(properties);
|
||||
|
||||
BDDAssertions.then(sampler).isInstanceOf(RateLimitingSampler.class);
|
||||
BDDAssertions.then(sampler).isInstanceOf(brave.sampler.RateLimitingSampler.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_use_probability_sampler_when_both_rate_and_probability_is_set() {
|
||||
void samplerFromProps_rateLimitZero() {
|
||||
SamplerProperties properties = new SamplerProperties();
|
||||
properties.setProbability(10f);
|
||||
properties.setRate(0);
|
||||
|
||||
Sampler sampler = SamplerAutoConfiguration.samplerFromProps(properties);
|
||||
|
||||
BDDAssertions.then(sampler).isSameAs(Sampler.NEVER_SAMPLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void samplerFromProps_prefersProbability() {
|
||||
SamplerProperties properties = new SamplerProperties();
|
||||
properties.setProbability(0.01f);
|
||||
properties.setRate(20);
|
||||
|
||||
Sampler sampler = SamplerAutoConfiguration.samplerFromProps(properties);
|
||||
|
||||
BDDAssertions.then(sampler).isInstanceOf(ProbabilityBasedSampler.class);
|
||||
BDDAssertions.then(sampler).isInstanceOf(brave.sampler.CountingSampler.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void samplerFromProps_prefersZeroProbability() {
|
||||
SamplerProperties properties = new SamplerProperties();
|
||||
properties.setProbability(0.0f);
|
||||
properties.setRate(20);
|
||||
|
||||
Sampler sampler = SamplerAutoConfiguration.samplerFromProps(properties);
|
||||
|
||||
BDDAssertions.then(sampler).isSameAs(Sampler.NEVER_SAMPLE);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithFinishedSpanHandler {
|
||||
|
||||
@Bean
|
||||
FinishedSpanHandler finishedSpanHandler() {
|
||||
return new FinishedSpanHandler() {
|
||||
@Override
|
||||
public boolean handle(TraceContext context, MutableSpan span) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithReporter {
|
||||
|
||||
@Bean
|
||||
Reporter<Span> spanReporter() {
|
||||
return zipkin2.Span::toString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithSampler {
|
||||
|
||||
@Bean
|
||||
Sampler alwaysSampler() {
|
||||
return Sampler.ALWAYS_SAMPLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class WithTracingCustomizer {
|
||||
|
||||
@Bean
|
||||
TracingCustomizer tracingCustomizer() {
|
||||
return Tracing.Builder::toString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
spring:
|
||||
sleuth:
|
||||
baggage:
|
||||
foo: bar
|
||||
remoteFields:
|
||||
- country-code
|
||||
- x-vcap-request-id
|
||||
|
||||
@@ -46,7 +46,6 @@ import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfigura
|
||||
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -91,7 +90,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
this.server.url("/").toString());
|
||||
this.context.register(ZipkinAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, Config.class);
|
||||
Config.class);
|
||||
this.context.refresh();
|
||||
Span span = this.context.getBean(Tracing.class).tracer().nextSpan().name("foo")
|
||||
.tag("foo", "bar").start();
|
||||
@@ -121,7 +120,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
environment().setProperty("spring.zipkin.encoder", "JSON_V1");
|
||||
this.context.register(ZipkinAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, Config.class);
|
||||
Config.class);
|
||||
this.context.refresh();
|
||||
Span span = this.context.getBean(Tracing.class).tracer().nextSpan().name("foo")
|
||||
.tag("foo", "bar").start();
|
||||
@@ -145,7 +144,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
environment().setProperty("spring.zipkin.sender.type", "rabbit");
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
RabbitAutoConfiguration.class, ZipkinAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, TraceAutoConfiguration.class);
|
||||
TraceAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBean(Sender.class)).isInstanceOf(RabbitMQSender.class);
|
||||
@@ -160,7 +159,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
environment().setProperty("spring.zipkin.sender.type", "kafka");
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
KafkaAutoConfiguration.class, ZipkinAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, TraceAutoConfiguration.class);
|
||||
TraceAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBean(Sender.class)).isInstanceOf(KafkaSender.class);
|
||||
@@ -177,7 +176,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
environment().setProperty("spring.zipkin.sender.type", "activemq");
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
ActiveMQAutoConfiguration.class, ZipkinAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, TraceAutoConfiguration.class);
|
||||
TraceAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBean(Sender.class)).isInstanceOf(ActiveMQSender.class);
|
||||
@@ -191,8 +190,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
environment().setProperty("spring.zipkin.sender.type", "web");
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
RabbitAutoConfiguration.class, KafkaAutoConfiguration.class,
|
||||
ZipkinAutoConfiguration.class, TraceBaggageAutoConfiguration.class,
|
||||
TraceAutoConfiguration.class);
|
||||
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBean(Sender.class).getClass().getName())
|
||||
@@ -207,8 +205,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
environment().setProperty("spring.zipkin.sender.type", "WEB");
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
RabbitAutoConfiguration.class, KafkaAutoConfiguration.class,
|
||||
ZipkinAutoConfiguration.class, TraceBaggageAutoConfiguration.class,
|
||||
TraceAutoConfiguration.class);
|
||||
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBean(Sender.class).getClass().getName())
|
||||
@@ -223,8 +220,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
environment().setProperty("spring.zipkin.sender.type", "rabbit");
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
RabbitAutoConfiguration.class, KafkaAutoConfiguration.class,
|
||||
ZipkinAutoConfiguration.class, TraceBaggageAutoConfiguration.class,
|
||||
TraceAutoConfiguration.class);
|
||||
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBean(Sender.class)).isInstanceOf(RabbitMQSender.class);
|
||||
@@ -239,8 +235,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
this.server.url("/").toString());
|
||||
this.context.register(ZipkinAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, Config.class,
|
||||
MultipleReportersConfig.class);
|
||||
Config.class, MultipleReportersConfig.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBeansOfType(Sender.class)).hasSize(2);
|
||||
@@ -275,7 +270,7 @@ public class ZipkinAutoConfigurationTests {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(ZipkinAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, Config.class, MyConfig.class);
|
||||
Config.class, MyConfig.class);
|
||||
this.context.refresh();
|
||||
|
||||
then(this.context.getBeansOfType(Sender.class)).hasSize(1);
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -147,8 +146,6 @@ public class TraceMessagingAutoConfigurationTests {
|
||||
private ApplicationContextRunner contextRunner(String... propertyValues) {
|
||||
return new ApplicationContextRunner().withPropertyValues(propertyValues)
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class,
|
||||
TraceMessagingAutoConfiguration.class,
|
||||
TraceMessagingAutoConfiguration.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.baggage.TraceBaggageAutoConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -34,8 +33,7 @@ public class TraceWebServletAutoConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class,
|
||||
TraceBaggageAutoConfiguration.class, TraceHttpAutoConfiguration.class,
|
||||
TraceWebAutoConfiguration.class,
|
||||
TraceHttpAutoConfiguration.class, TraceWebAutoConfiguration.class,
|
||||
TraceWebServletAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user