baggageKeys = new ArrayList<>();
@@ -58,7 +60,7 @@ public class SleuthProperties {
*
* Note: {@code fieldName} will be implicitly lower-cased.
*
- * @see brave.propagation.ExtraFieldPropagation.FactoryBuilder#addField(String)
+ * @see BaggagePropagationConfig.SingleBaggageField#remote(BaggageField)
*/
private List propagationKeys = new ArrayList<>();
@@ -66,7 +68,7 @@ public class SleuthProperties {
* Same as {@link #propagationKeys} except that this field is not propagated to remote
* services.
*
- * @see brave.propagation.ExtraFieldPropagation.FactoryBuilder#addRedactedField(String)
+ * @see BaggagePropagationConfig.SingleBaggageField#local(BaggageField)
*/
private List localKeys = new ArrayList<>();
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java
index c1ceaaa76..755ade230 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java
@@ -25,12 +25,14 @@ import brave.ErrorParser;
import brave.Tracer;
import brave.Tracing;
import brave.TracingCustomizer;
+import brave.baggage.BaggagePropagation;
+import brave.baggage.BaggagePropagationConfig;
+import brave.baggage.BaggagePropagationCustomizer;
import brave.handler.FinishedSpanHandler;
import brave.propagation.B3Propagation;
import brave.propagation.CurrentTraceContext;
+import brave.propagation.CurrentTraceContext.ScopeDecorator;
import brave.propagation.CurrentTraceContextCustomizer;
-import brave.propagation.ExtraFieldCustomizer;
-import brave.propagation.ExtraFieldPropagation;
import brave.propagation.Propagation;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.sampler.Sampler;
@@ -44,6 +46,7 @@ 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;
@@ -70,6 +73,7 @@ import org.springframework.util.StringUtils;
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
@EnableConfigurationProperties(SleuthProperties.class)
+@AutoConfigureAfter(PropertyBasedBaggageConfiguration.class)
public class TraceAutoConfiguration {
/**
@@ -89,7 +93,7 @@ public class TraceAutoConfiguration {
List scopeDecorators = new ArrayList<>();
@Autowired(required = false)
- ExtraFieldPropagation.FactoryBuilder extraFieldPropagationFactoryBuilder;
+ List baggagePropagationCustomizers = new ArrayList<>();
@Autowired(required = false)
List tracingCustomizers = new ArrayList<>();
@@ -97,9 +101,6 @@ public class TraceAutoConfiguration {
@Autowired(required = false)
List currentTraceContextCustomizers = new ArrayList<>();
- @Autowired(required = false)
- List extraFieldCustomizers = new ArrayList<>();
-
@Bean
@ConditionalOnMissingBean
// NOTE: stable bean name as might be used outside sleuth
@@ -143,42 +144,24 @@ public class TraceAutoConfiguration {
return new DefaultSpanNamer();
}
+ /**
+ * To override the underlying context format, override this bean and set the delegate
+ * to what you need. {@link BaggagePropagation.FactoryBuilder} will unwrap itself if
+ * no fields are configured.
+ */
@Bean
@ConditionalOnMissingBean
- Propagation.Factory sleuthPropagation(SleuthProperties sleuthProperties) {
- if (sleuthProperties.getBaggageKeys().isEmpty()
- && sleuthProperties.getPropagationKeys().isEmpty()
- && extraFieldCustomizers.isEmpty()
- && this.extraFieldPropagationFactoryBuilder == null
- && sleuthProperties.getLocalKeys().isEmpty()) {
- return B3Propagation.FACTORY;
- }
- ExtraFieldPropagation.FactoryBuilder factoryBuilder;
- if (this.extraFieldPropagationFactoryBuilder != null) {
- factoryBuilder = this.extraFieldPropagationFactoryBuilder;
- }
- else {
- factoryBuilder = ExtraFieldPropagation
- .newFactoryBuilder(B3Propagation.FACTORY);
- }
- if (!sleuthProperties.getBaggageKeys().isEmpty()) {
- factoryBuilder = factoryBuilder
- // for HTTP
- .addPrefixedFields("baggage-", sleuthProperties.getBaggageKeys())
- // for messaging
- .addPrefixedFields("baggage_", sleuthProperties.getBaggageKeys());
- }
- if (!sleuthProperties.getPropagationKeys().isEmpty()) {
- for (String key : sleuthProperties.getPropagationKeys()) {
- factoryBuilder = factoryBuilder.addField(key);
- }
- }
- if (!sleuthProperties.getLocalKeys().isEmpty()) {
- for (String key : sleuthProperties.getLocalKeys()) {
- factoryBuilder = factoryBuilder.addRedactedField(key);
- }
- }
- for (ExtraFieldCustomizer customizer : this.extraFieldCustomizers) {
+ BaggagePropagation.FactoryBuilder baggagePropagationFactoryBuilder() {
+ return BaggagePropagation.newFactoryBuilder(B3Propagation.FACTORY);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ Propagation.Factory sleuthPropagation(
+ BaggagePropagation.FactoryBuilder factoryBuilder,
+ List baggageConfig) {
+ baggageConfig.forEach(factoryBuilder::add);
+ for (BaggagePropagationCustomizer customizer : this.baggagePropagationCustomizers) {
customizer.customize(factoryBuilder);
}
return factoryBuilder.build();
@@ -186,7 +169,7 @@ public class TraceAutoConfiguration {
@Bean
CurrentTraceContext sleuthCurrentTraceContext(CurrentTraceContext.Builder builder) {
- for (CurrentTraceContext.ScopeDecorator scopeDecorator : this.scopeDecorators) {
+ for (ScopeDecorator scopeDecorator : this.scopeDecorators) {
builder.addScopeDecorator(scopeDecorator);
}
for (CurrentTraceContextCustomizer customizer : this.currentTraceContextCustomizers) {
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java
index ae1f852a5..a23afe2b9 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java
@@ -16,22 +16,28 @@
package org.springframework.cloud.sleuth.log;
-import brave.propagation.CurrentTraceContext;
+import java.util.List;
+
+import brave.baggage.CorrelationScopeConfig;
+import brave.baggage.CorrelationScopeDecorator;
+import brave.context.slf4j.MDCScopeDecorator;
+import brave.propagation.CurrentTraceContext.ScopeDecorator;
import org.slf4j.MDC;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.sleuth.autoconfig.SleuthProperties;
+import org.springframework.cloud.sleuth.autoconfig.PropertyBasedBaggageConfiguration;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
- * Auto-configuration} adds a {@link Slf4jScopeDecorator} that prints tracing information
- * in the logs.
+ * Auto-configuration} adds a {@link CorrelationScopeDecorator} that prints tracing
+ * information in the logs.
*
*
* @author Spencer Gibb
@@ -41,6 +47,7 @@ import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
@AutoConfigureBefore(TraceAutoConfiguration.class)
+@AutoConfigureAfter(PropertyBasedBaggageConfiguration.class)
public class SleuthLogAutoConfiguration {
/**
@@ -54,10 +61,12 @@ public class SleuthLogAutoConfiguration {
@Bean
@ConditionalOnProperty(value = "spring.sleuth.log.slf4j.enabled",
matchIfMissing = true)
- static CurrentTraceContext.ScopeDecorator slf4jSpanDecorator(
- SleuthProperties sleuthProperties,
- SleuthSlf4jProperties sleuthSlf4jProperties) {
- return new Slf4jScopeDecorator(sleuthProperties, sleuthSlf4jProperties);
+ ScopeDecorator correlationScopeDecorator(
+ List correlationScopeConfigs) {
+ CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder();
+ builder.clear();
+ correlationScopeConfigs.forEach(builder::add);
+ return builder.build();
}
}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java
index 26d028b8e..3f13d2dca 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthSlf4jProperties.java
@@ -19,6 +19,8 @@ package org.springframework.cloud.sleuth.log;
import java.util.ArrayList;
import java.util.List;
+import brave.context.slf4j.MDCScopeDecorator;
+
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
@@ -31,7 +33,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
public class SleuthSlf4jProperties {
/**
- * Enable a {@link Slf4jScopeDecorator} that prints tracing information in the logs.
+ * Enable a {@link MDCScopeDecorator} that prints tracing information in the logs.
*/
private boolean enabled = true;
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java
deleted file mode 100644
index d2d0c667c..000000000
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jScopeDecorator.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2013-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.sleuth.log;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.TreeSet;
-
-import brave.baggage.BaggageField;
-import brave.baggage.BaggageFields;
-import brave.baggage.CorrelationField;
-import brave.baggage.CorrelationScopeDecorator;
-import brave.context.slf4j.MDCScopeDecorator;
-import brave.propagation.CurrentTraceContext.Scope;
-import brave.propagation.CurrentTraceContext.ScopeDecorator;
-import brave.propagation.TraceContext;
-import org.slf4j.MDC;
-
-import org.springframework.cloud.sleuth.autoconfig.SleuthProperties;
-
-/**
- * Adds {@linkplain MDC} properties "traceId", "parentId", "spanId" and "spanExportable"
- * when a {@link brave.Tracer#currentSpan() span is current}. These can be used in log
- * correlation. Supports backward compatibility of MDC entries by adding legacy "X-B3"
- * entries to MDC context "X-B3-TraceId", "X-B3-ParentSpanId", "X-B3-SpanId" and
- * "X-B3-Sampled"
- *
- * @author Marcin Grzejszczak
- * @since 2.1.0
- */
-final class Slf4jScopeDecorator implements ScopeDecorator {
-
- // Backward compatibility for all logging patterns
- private static final ScopeDecorator LEGACY_IDS = MDCScopeDecorator.newBuilder()
- .clear()
- .addField(CorrelationField.newBuilder(BaggageFields.TRACE_ID)
- .name("X-B3-TraceId").build())
- .addField(CorrelationField.newBuilder(BaggageFields.PARENT_ID)
- .name("X-B3-ParentSpanId").build())
- .addField(CorrelationField.newBuilder(BaggageFields.SPAN_ID)
- .name("X-B3-SpanId").build())
- .addField(CorrelationField.newBuilder(BaggageFields.SAMPLED)
- .name("X-Span-Export").build())
- .build();
-
- private final ScopeDecorator delegate;
-
- Slf4jScopeDecorator(SleuthProperties sleuthProperties,
- SleuthSlf4jProperties sleuthSlf4jProperties) {
-
- CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder().clear()
- .addField(CorrelationField.create(BaggageFields.TRACE_ID))
- .addField(CorrelationField.create(BaggageFields.PARENT_ID))
- .addField(CorrelationField.create(BaggageFields.SPAN_ID))
- .addField(CorrelationField.newBuilder(BaggageFields.SAMPLED)
- .name("spanExportable").build());
-
- Set whitelist = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
- whitelist.addAll(sleuthSlf4jProperties.getWhitelistedMdcKeys());
-
- // Note: we are adding all the keys as-is because correlation context doesn't
- // prefix, only ExtraFieldPropagation does
- Set retained = new LinkedHashSet<>();
- retained.addAll(sleuthProperties.getBaggageKeys());
- retained.addAll(sleuthProperties.getLocalKeys());
- retained.addAll(sleuthProperties.getPropagationKeys());
- retained.retainAll(whitelist);
-
- // For backwards compatibility set all fields dirty, so that any changes made by
- // MDC directly are reverted.
- for (String name : retained) {
- builder.addField(CorrelationField.newBuilder(BaggageField.create(name))
- .dirty().build());
- }
-
- this.delegate = builder.build();
- }
-
- @Override
- public Scope decorateScope(TraceContext context, Scope scope) {
- return LEGACY_IDS.decorateScope(context, delegate.decorateScope(context, scope));
- }
-
-}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java
index 7023750f6..d428d62ca 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/SleuthTagPropagationAutoConfiguration.java
@@ -21,7 +21,6 @@ import brave.handler.FinishedSpanHandler;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.sleuth.autoconfig.SleuthProperties;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -42,11 +41,9 @@ public class SleuthTagPropagationAutoConfiguration {
protected static class TagPropagationConfiguration {
@Bean
- static FinishedSpanHandler sleuthFinishedSpanHandler(
- SleuthProperties sleuthProperties,
+ FinishedSpanHandler sleuthFinishedSpanHandler(
SleuthTagPropagationProperties tagPropagationProperties) {
- return new TagPropagationFinishedSpanHandler(sleuthProperties,
- tagPropagationProperties);
+ return new TagPropagationFinishedSpanHandler(tagPropagationProperties);
}
}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java
index c6bc5c6f6..e9b03e129 100644
--- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/propagation/TagPropagationFinishedSpanHandler.java
@@ -16,51 +16,38 @@
package org.springframework.cloud.sleuth.propagation;
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.List;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import brave.Tags;
+import brave.baggage.BaggageField;
import brave.handler.FinishedSpanHandler;
import brave.handler.MutableSpan;
-import brave.propagation.ExtraFieldPropagation;
import brave.propagation.TraceContext;
-import org.springframework.cloud.sleuth.autoconfig.SleuthProperties;
-
-import static java.util.Objects.nonNull;
-
/**
- * Finish span handler which adds extra propagation fields to span tags, so spans could be
- * looked up by its baggage.
+ * Finish span handler which adds baggage to span tags, so spans could be looked up by a
+ * baggage name.
*
* @author Taras Danylchuk
* @since 2.1.0
*/
public class TagPropagationFinishedSpanHandler extends FinishedSpanHandler {
- private final SleuthProperties sleuthProperties;
+ private final Set baggageToTag = new LinkedHashSet<>();
- private final SleuthTagPropagationProperties tagPropagationProperties;
-
- public TagPropagationFinishedSpanHandler(SleuthProperties sleuthProperties,
+ public TagPropagationFinishedSpanHandler(
SleuthTagPropagationProperties tagPropagationProperties) {
- this.sleuthProperties = sleuthProperties;
- this.tagPropagationProperties = tagPropagationProperties;
+ Set keys = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+ keys.addAll(tagPropagationProperties.getWhitelistedKeys());
+ keys.forEach(key -> baggageToTag.add(BaggageField.create(key)));
}
@Override
public boolean handle(TraceContext context, MutableSpan span) {
- for (List strings : Arrays.asList(this.sleuthProperties.getBaggageKeys(),
- this.sleuthProperties.getPropagationKeys())) {
- for (String key : strings) {
- if (this.tagPropagationProperties.getWhitelistedKeys().contains(key)) {
- AbstractMap.SimpleEntry entry = new AbstractMap.SimpleEntry<>(
- key, ExtraFieldPropagation.get(context, key));
- if (nonNull(entry.getValue())) {
- span.tag(entry.getKey(), entry.getValue());
- }
- }
- }
+ for (BaggageField field : baggageToTag) {
+ Tags.BAGGAGE_FIELD.tag(field, context, span);
}
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 37a671eaa..a2459467f 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
@@ -2,6 +2,7 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration,\
org.springframework.cloud.sleuth.sampler.SamplerAutoConfiguration,\
+org.springframework.cloud.sleuth.autoconfig.PropertyBasedBaggageConfiguration,\
org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration,\
org.springframework.cloud.sleuth.log.SleuthLogAutoConfiguration,\
org.springframework.cloud.sleuth.propagation.SleuthTagPropagationAutoConfiguration,\
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 f65030315..471fc9718 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
@@ -17,10 +17,10 @@
package org.springframework.cloud.sleuth.autoconfig;
import brave.TracingCustomizer;
+import brave.baggage.BaggagePropagationCustomizer;
import brave.http.HttpTracingCustomizer;
import brave.messaging.MessagingTracingCustomizer;
import brave.propagation.CurrentTraceContextCustomizer;
-import brave.propagation.ExtraFieldCustomizer;
import brave.propagation.Propagation;
import brave.rpc.RpcTracingCustomizer;
import brave.sampler.Sampler;
@@ -61,7 +61,7 @@ public class TraceAutoConfigurationCustomizersTests {
}
@Test
- public void should_apply_extra_field_customizer_when_no_extra_properties_are_defined() {
+ public void should_apply_baggage_customizer_when_no_baggage_properties_are_defined() {
this.contextRunner.run((context) -> {
Customizers bean = context.getBean(Customizers.class);
@@ -76,7 +76,7 @@ public class TraceAutoConfigurationCustomizersTests {
private void shouldApplyCustomizations(Customizers bean) {
then(bean.tracingCustomizerApplied).isTrue();
then(bean.contextCustomizerApplied).isTrue();
- then(bean.extraFieldCustomizerApplied).isTrue();
+ then(bean.baggagePropagationCustomizerApplied).isTrue();
then(bean.httpCustomizerApplied).isTrue();
then(bean.rpcCustomizerApplied).isTrue();
}
@@ -99,7 +99,7 @@ public class TraceAutoConfigurationCustomizersTests {
boolean contextCustomizerApplied;
- boolean extraFieldCustomizerApplied;
+ boolean baggagePropagationCustomizerApplied;
boolean httpCustomizerApplied;
@@ -118,8 +118,8 @@ public class TraceAutoConfigurationCustomizersTests {
}
@Bean
- ExtraFieldCustomizer sleuthExtraFieldCustomizer() {
- return builder -> extraFieldCustomizerApplied = true;
+ BaggagePropagationCustomizer sleuthBaggagePropagationCustomizer() {
+ return builder -> baggagePropagationCustomizerApplied = true;
}
@Bean
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java
index a022300cd..791b7e481 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationPropagationCustomizationTests.java
@@ -16,9 +16,9 @@
package org.springframework.cloud.sleuth.autoconfig;
+import brave.baggage.BaggagePropagation;
import brave.propagation.B3Propagation;
import brave.propagation.B3SinglePropagation;
-import brave.propagation.ExtraFieldPropagation;
import brave.propagation.Propagation;
import org.assertj.core.api.BDDAssertions;
import org.junit.jupiter.api.Test;
@@ -34,7 +34,9 @@ import org.springframework.context.support.GenericApplicationContext;
public class TraceAutoConfigurationPropagationCustomizationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
- .withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class));
+ .withConfiguration(
+ AutoConfigurations.of(PropertyBasedBaggageConfiguration.class,
+ TraceAutoConfiguration.class));
@Test
public void stillCreatesDefault() {
@@ -49,7 +51,7 @@ public class TraceAutoConfigurationPropagationCustomizationTests {
this.contextRunner.withPropertyValues("spring.sleuth.baggage-keys=my-baggage")
.run((context) -> {
BDDAssertions.then(context.getBean(Propagation.Factory.class))
- .hasFieldOrPropertyWithValue("delegate.delegate",
+ .hasFieldOrPropertyWithValue("delegate",
B3Propagation.FACTORY);
});
}
@@ -79,19 +81,17 @@ public class TraceAutoConfigurationPropagationCustomizationTests {
public void allowsCustomizationOfBuilder() {
this.contextRunner.withPropertyValues("spring.sleuth.baggage-keys=my-baggage")
.withUserConfiguration(CustomPropagationFactoryBuilderConfig.class)
- .run((context) -> {
- BDDAssertions.then(context.getBean(Propagation.Factory.class))
- .hasFieldOrPropertyWithValue("delegate.delegate",
- B3SinglePropagation.FACTORY);
- });
+ .run((context) -> BDDAssertions
+ .then(context.getBean(Propagation.Factory.class))
+ .extracting("delegate").isSameAs(B3SinglePropagation.FACTORY));
}
@Configuration
static class CustomPropagationFactoryBuilderConfig {
@Bean
- public ExtraFieldPropagation.FactoryBuilder factoryBuilder() {
- return ExtraFieldPropagation.newFactoryBuilder(B3SinglePropagation.FACTORY);
+ public BaggagePropagation.FactoryBuilder b3Single() {
+ return BaggagePropagation.newFactoryBuilder(B3SinglePropagation.FACTORY);
}
}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java
index e485fd011..f780404e1 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfigurationTests.java
@@ -16,9 +16,16 @@
package org.springframework.cloud.sleuth.autoconfig;
-import brave.propagation.B3Propagation;
-import brave.propagation.ExtraFieldPropagation;
+import java.util.List;
+
+import brave.Tracing;
+import brave.baggage.BaggageField;
+import brave.baggage.BaggagePropagation;
+import brave.baggage.BaggagePropagationConfig;
+import brave.baggage.BaggagePropagationConfig.SingleBaggageField;
+import brave.propagation.B3SinglePropagation;
import brave.propagation.Propagation;
+import brave.propagation.TraceContextOrSamplingFlags;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.assertj.core.api.BDDAssertions;
@@ -27,6 +34,7 @@ import zipkin2.reporter.InMemoryReporterMetrics;
import zipkin2.reporter.ReporterMetrics;
import zipkin2.reporter.metrics.micrometer.MicrometerReporterMetrics;
+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;
@@ -36,7 +44,9 @@ import org.springframework.context.annotation.Configuration;
public class TraceAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
- .withConfiguration(AutoConfigurations.of(TraceAutoConfiguration.class));
+ .withConfiguration(
+ AutoConfigurations.of(PropertyBasedBaggageConfiguration.class,
+ TraceAutoConfiguration.class));
@Test
public void should_apply_micrometer_reporter_metrics_when_meter_registry_bean_present() {
@@ -77,25 +87,81 @@ public class TraceAutoConfigurationTests {
}
@Test
- public void should_use_local_keys_from_properties() {
- this.contextRunner.withUserConfiguration(WithLocalKeys.class).run((context -> {
- final Propagation.Factory bean = context.getBean(Propagation.Factory.class);
- BDDAssertions.then(bean).isInstanceOf(ExtraFieldPropagation.Factory.class);
- }));
+ public void should_use_baggageBean() {
+ this.contextRunner.withUserConfiguration(WithBaggageBeans.class, Baggage.class)
+ .run((context -> {
+ final Baggage bean = context.getBean(Baggage.class);
+ BDDAssertions.then(bean.fields).containsOnly(
+ BaggageField.create("userId"),
+ BaggageField.create("userName"));
+ }));
}
@Test
- public void should_use_extraFieldPropagationFactoryBuilder_bean() {
- this.contextRunner
- .withUserConfiguration(WithExtraFieldPropagationFactoryBuilderBean.class)
- .run((context -> {
- final Propagation.Factory bean = context
- .getBean(Propagation.Factory.class);
- BDDAssertions.then(bean)
- .isInstanceOf(ExtraFieldPropagation.Factory.class);
+ public void should_use_local_keys_from_properties() {
+ this.contextRunner.withPropertyValues("spring.sleuth.local-keys=test-key")
+ .withUserConfiguration(Baggage.class).run((context -> {
+ final Baggage bean = context.getBean(Baggage.class);
+ BDDAssertions.then(bean.fields)
+ .containsExactly(BaggageField.create("test-key"));
}));
}
+ @Test
+ public void should_combine_baggage_beans_and_properties() {
+ this.contextRunner.withPropertyValues("spring.sleuth.local-keys=test-key")
+ .withUserConfiguration(WithBaggageBeans.class, Baggage.class)
+ .run((context -> {
+ final Baggage bean = context.getBean(Baggage.class);
+ BDDAssertions.then(bean.fields).containsOnly(
+ BaggageField.create("userId"),
+ BaggageField.create("userName"),
+ BaggageField.create("test-key"));
+ }));
+ }
+
+ @Test
+ public void should_use_baggagePropagationFactoryBuilder_bean() {
+ // BaggagePropagation.FactoryBuilder unwraps itself if there are no baggage fields
+ // defined
+ this.contextRunner
+ .withUserConfiguration(WithBaggagePropagationFactoryBuilderBean.class)
+ .run((context -> BDDAssertions
+ .then(context.getBean(Propagation.Factory.class))
+ .isSameAs(B3SinglePropagation.FACTORY)));
+ }
+
+ @Configuration
+ static class Baggage {
+
+ List fields;
+
+ @Autowired
+ Baggage(Tracing tracing) {
+ // When predefined baggage fields exist, the result !=
+ // TraceContextOrSamplingFlags.EMPTY
+ TraceContextOrSamplingFlags emptyExtraction = tracing.propagation()
+ .extractor((c, k) -> null).extract(Boolean.TRUE);
+ fields = BaggageField.getAll(emptyExtraction);
+ }
+
+ }
+
+ @Configuration
+ static class WithBaggageBeans {
+
+ @Bean
+ BaggagePropagationConfig userId() {
+ return SingleBaggageField.remote(BaggageField.create("userId"));
+ }
+
+ @Bean
+ BaggagePropagationConfig userName() {
+ return SingleBaggageField.remote(BaggageField.create("userName"));
+ }
+
+ }
+
@Configuration
static class WithMeterRegistry {
@@ -107,23 +173,11 @@ public class TraceAutoConfigurationTests {
}
@Configuration
- static class WithLocalKeys {
+ static class WithBaggagePropagationFactoryBuilderBean {
@Bean
- SleuthProperties sleuthProperties() {
- final SleuthProperties sleuthProperties = new SleuthProperties();
- sleuthProperties.getLocalKeys().add("test-key");
- return sleuthProperties;
- }
-
- }
-
- @Configuration
- static class WithExtraFieldPropagationFactoryBuilderBean {
-
- @Bean
- ExtraFieldPropagation.FactoryBuilder extraFieldPropagationFactoryBuilderBean() {
- return ExtraFieldPropagation.newFactoryBuilder(B3Propagation.FACTORY);
+ BaggagePropagation.FactoryBuilder baggagePropagationFactoryBuilderBean() {
+ return BaggagePropagation.newFactoryBuilder(B3SinglePropagation.FACTORY);
}
}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java
index dc565d5fe..875064d23 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/DemoApplication.java
@@ -20,7 +20,9 @@ import java.util.Arrays;
import java.util.List;
import brave.Span;
+import brave.Tags;
import brave.Tracer;
+import brave.baggage.BaggageField;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -73,6 +75,11 @@ public class DemoApplication {
@RequestHeader HttpHeaders headers) {
this.sender.send(message);
this.httpSpan = this.tracer.currentSpan();
+
+ // tag what was propagated
+ BaggageField baz = BaggageField.getByName(httpSpan.context(), "baz");
+ Tags.BAGGAGE_FIELD.tag(baz, httpSpan);
+
return new Greeting(message);
}
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java
index 073bc5371..20b8d00d2 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java
@@ -18,12 +18,17 @@ package org.springframework.cloud.sleuth.instrument.multiple;
import java.net.URI;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
-import java.util.stream.Collectors;
import brave.Span;
+import brave.Tags;
import brave.Tracer;
-import brave.propagation.ExtraFieldPropagation;
+import brave.Tracer.SpanInScope;
+import brave.Tracing;
+import brave.baggage.BaggageField;
+import brave.baggage.BaggagePropagationConfig;
+import brave.baggage.BaggagePropagationConfig.SingleBaggageField;
import brave.sampler.Sampler;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -40,24 +45,24 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.TestPropertySource;
import org.springframework.web.client.RestTemplate;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.BDDAssertions.then;
import static org.awaitility.Awaitility.await;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
-@TestPropertySource(
- properties = { "spring.application.name=multiplehopsintegrationtests" })
@SpringBootTest(classes = MultipleHopsIntegrationTests.Config.class,
- webEnvironment = RANDOM_PORT)
-@ActiveProfiles("baggage")
+ webEnvironment = RANDOM_PORT, properties = { "spring.sleuth.baggage-keys=baz",
+ "spring.sleuth.propagation-keys=foo" })
public class MultipleHopsIntegrationTests {
+ @Autowired
+ Tracing tracing;
+
@Autowired
Tracer tracer;
@@ -79,7 +84,7 @@ public class MultipleHopsIntegrationTests {
}
@Test
- public void should_prepare_spans_for_export() throws Exception {
+ public void should_prepare_spans_for_export() {
this.restTemplate.getForObject(
"http://localhost:" + this.config.port + "/greeting", String.class);
@@ -98,38 +103,28 @@ public class MultipleHopsIntegrationTests {
.containsAll(asList("words", "counts", "greetings"));
}
- // issue #237 - baggage
@Test
- // Notes:
- // * path-prefix header propagation can't reliably support mixed case, due to http/2
- // downcasing
- // * Since not all tokenizers are case insensitive, mixed case can break correlation
- // * Brave's ExtraFieldPropagation downcases due to the above
- // * This code should probably test the side-effect on http headers
- // * the assumption all correlation fields (baggage) are saved to a span is an
- // interesting one
- // * should all correlation fields (baggage) be added to the MDC context?
- // * Until below, a configuration item of a correlation field whitelist is needed
- // * https://github.com/openzipkin/brave/pull/577
- // * probably needed anyway as an empty whitelist is a nice way to disable the feature
- public void should_propagate_the_baggage() throws Exception {
+ public void should_propagate_the_baggage() {
+ // TODO: make a DemoBaggage type instead of saying to use the api directly
+ BaggageField foo = BaggageField.create("foo");
+ BaggageField bar = BaggageField.create("bar");
+ BaggageField baz = BaggageField.create("baz");
+
// tag::baggage[]
Span initialSpan = this.tracer.nextSpan().name("span").start();
- ExtraFieldPropagation.set(initialSpan.context(), "foo", "bar");
- ExtraFieldPropagation.set(initialSpan.context(), "UPPER_CASE", "someValue");
+ foo.updateValue(initialSpan.context(), "1");
+ bar.updateValue(initialSpan.context(), "2");
// end::baggage[]
- try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(initialSpan)) {
+ try (SpanInScope ws = this.tracer.withSpanInScope(initialSpan)) {
// tag::baggage_tag[]
- initialSpan.tag("foo",
- ExtraFieldPropagation.get(initialSpan.context(), "foo"));
- initialSpan.tag("UPPER_CASE",
- ExtraFieldPropagation.get(initialSpan.context(), "UPPER_CASE"));
+ Tags.BAGGAGE_FIELD.tag(foo, initialSpan);
+ Tags.BAGGAGE_FIELD.tag(bar, initialSpan);
// end::baggage_tag[]
+ // set baz in a header not with the api explicitly
HttpHeaders headers = new HttpHeaders();
- headers.put("baggage-baz", Collections.singletonList("baz"));
- headers.put("baggage-bizarreCASE", Collections.singletonList("value"));
+ headers.put("baggage-baz", Collections.singletonList("3"));
RequestEntity requestEntity = new RequestEntity(headers, HttpMethod.GET,
URI.create("http://localhost:" + this.config.port + "/greeting"));
this.restTemplate.exchange(requestEntity, String.class);
@@ -137,29 +132,29 @@ public class MultipleHopsIntegrationTests {
finally {
initialSpan.finish();
}
+
await().atMost(5, SECONDS).untilAsserted(() -> {
then(this.reporter.getSpans()).isNotEmpty();
});
- then(this.application.allSpans()).as("All have foo")
- .allMatch(span -> "bar".equals(baggage(span, "foo")));
- then(this.application.allSpans()).as("All have UPPER_CASE")
- .allMatch(span -> "someValue".equals(baggage(span, "UPPER_CASE")));
- then(this.application.allSpans().stream()
- .filter(span -> "baz".equals(baggage(span, "baz")))
- .collect(Collectors.toList())).as("Someone has baz").isNotEmpty();
- then(this.reporter.getSpans().stream()
- .filter(span -> span.tags().containsKey("foo")
- && span.tags().containsKey("UPPER_CASE"))
- .collect(Collectors.toList())).as("Someone has foo and UPPER_CASE tags")
- .isNotEmpty();
- then(this.application.allSpans().stream()
- .filter(span -> "value".equals(baggage(span, "bizarreCASE")))
- .collect(Collectors.toList())).isNotEmpty();
- }
+ List withBagTags = this.reporter.getSpans().stream()
+ .filter(s -> s.tags().containsKey(foo.name())).collect(toList());
- private String baggage(Span span, String name) {
- return ExtraFieldPropagation.get(span.context(), name);
+ // set with tag api
+ then(withBagTags).as("only initialSpan was bag tagged").hasSize(1);
+ assertThat(withBagTags.get(0).tags()).containsEntry("foo", "1")
+ .containsEntry("bar", "2");
+
+ // set with baggage api
+ then(this.application.allSpans()).as("All have foo")
+ .allMatch(span -> "1".equals(foo.getValue(span.context())));
+ then(this.application.allSpans()).as("All have bar")
+ .allMatch(span -> "2".equals(bar.getValue(span.context())));
+
+ // baz is not tagged in the initial span, only downstream!
+ then(this.application.allSpans()).as("All downstream have baz")
+ .filteredOn(span -> !span.equals(initialSpan))
+ .allMatch(span -> "3".equals(baz.getValue(span.context())));
}
@Configuration
@@ -174,6 +169,11 @@ public class MultipleHopsIntegrationTests {
this.port = event.getSource().getPort();
}
+ @Bean
+ BaggagePropagationConfig notInProperties() {
+ return SingleBaggageField.remote(BaggageField.create("bar"));
+ }
+
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java
index 764cbd77e..04613af8f 100644
--- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java
+++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java
@@ -18,8 +18,9 @@ package org.springframework.cloud.sleuth.log;
import brave.Span;
import brave.Tracer;
-import brave.baggage.CorrelationField;
+import brave.baggage.CorrelationScopeConfig.SingleCorrelationField;
import brave.propagation.CurrentTraceContext.Scope;
+import brave.propagation.CurrentTraceContext.ScopeDecorator;
import brave.propagation.ExtraFieldPropagation;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.AfterEach;
@@ -51,7 +52,7 @@ public class Slf4JSpanLoggerTest {
Tracer tracer;
@Autowired
- Slf4jScopeDecorator slf4jScopeDecorator;
+ ScopeDecorator slf4jScopeDecorator;
Span span;
@@ -173,10 +174,11 @@ public class Slf4JSpanLoggerTest {
@Test
public void should_only_include_whitelist() {
- assertThat(this.slf4jScopeDecorator).extracting("delegate.fields")
- .asInstanceOf(InstanceOfAssertFactories.array(CorrelationField[].class))
- .extracting(CorrelationField::name).containsExactly("traceId", "parentId",
- "spanId", "spanExportable", "my-baggage", "my-local",
+ assertThat(this.slf4jScopeDecorator).extracting("fields")
+ .asInstanceOf(
+ InstanceOfAssertFactories.array(SingleCorrelationField[].class))
+ .extracting(SingleCorrelationField::name).containsOnly("traceId",
+ "parentId", "spanId", "spanExportable", "my-baggage", "my-local",
"my-propagation"); // my-baggage-two is not in the whitelist
}
diff --git a/spring-cloud-sleuth-core/src/test/resources/application-baggage.yml b/spring-cloud-sleuth-core/src/test/resources/application-baggage.yml
deleted file mode 100644
index 1467d2326..000000000
--- a/spring-cloud-sleuth-core/src/test/resources/application-baggage.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-spring.sleuth:
- baggage-keys:
- - baz
- - bizarrecase
- propagation-keys:
- - foo
- - upper_case
diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml
index 810de6c3c..dba808b68 100644
--- a/spring-cloud-sleuth-dependencies/pom.xml
+++ b/spring-cloud-sleuth-dependencies/pom.xml
@@ -31,8 +31,8 @@
spring-cloud-sleuth-dependencies
Spring Cloud Sleuth Dependencies
- 5.11.1
- 0.36.1
+ 5.11.2
+ 0.36.2
3.4.1