Skip to content

Commit

Permalink
Disable propagation of traces if tracing is disabled
Browse files Browse the repository at this point in the history
Closes gh-38641
  • Loading branch information
mhalbritter committed Dec 5, 2023
1 parent a0fc2d4 commit 02347ab
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 163 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,10 @@
import brave.Tracing;
import brave.Tracing.Builder;
import brave.TracingCustomizer;
import brave.baggage.BaggageField;
import brave.baggage.BaggagePropagation;
import brave.baggage.BaggagePropagation.FactoryBuilder;
import brave.baggage.BaggagePropagationConfig;
import brave.baggage.BaggagePropagationCustomizer;
import brave.baggage.CorrelationScopeConfig.SingleCorrelationField;
import brave.baggage.CorrelationScopeCustomizer;
import brave.baggage.CorrelationScopeDecorator;
import brave.context.slf4j.MDCScopeDecorator;
import brave.handler.SpanHandler;
import brave.propagation.CurrentTraceContext;
import brave.propagation.CurrentTraceContext.ScopeDecorator;
import brave.propagation.CurrentTraceContextCustomizer;
import brave.propagation.Propagation;
import brave.propagation.Propagation.Factory;
import brave.propagation.Propagation.KeyFactory;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.sampler.Sampler;
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
Expand All @@ -53,17 +41,15 @@
import io.micrometer.tracing.exporter.SpanReporter;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Baggage.Correlation;
import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
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.EnableConfigurationProperties;
import org.springframework.boot.context.properties.IncompatibleConfigurationException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
Expand All @@ -79,9 +65,12 @@
@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class)
@ConditionalOnClass({ Tracer.class, BraveTracer.class })
@EnableConfigurationProperties(TracingProperties.class)
@Import({ BravePropagationConfigurations.PropagationWithoutBaggage.class,
BravePropagationConfigurations.PropagationWithBaggage.class,
BravePropagationConfigurations.NoPropagation.class })
public class BraveAutoConfiguration {

private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager();
static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager();

/**
* Default value for application name if {@code spring.application.name} is not set.
Expand Down Expand Up @@ -182,108 +171,4 @@ BraveSpanCustomizer braveSpanCustomizer(SpanCustomizer spanCustomizer) {
return new BraveSpanCustomizer(spanCustomizer);
}

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", havingValue = "false")
static class BraveNoBaggageConfiguration {

@Bean
@ConditionalOnMissingBean
Factory propagationFactory(TracingProperties properties) {
return CompositePropagationFactory.create(properties.getPropagation());
}

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", matchIfMissing = true)
static class BraveBaggageConfiguration {

private final TracingProperties tracingProperties;

BraveBaggageConfiguration(TracingProperties tracingProperties) {
this.tracingProperties = tracingProperties;
}

@Bean
@ConditionalOnMissingBean
BaggagePropagation.FactoryBuilder propagationFactoryBuilder(
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
// There's a chicken-and-egg problem here: to create a builder, we need a
// factory. But the CompositePropagationFactory needs data from the builder.
// We create a throw-away builder with a throw-away factory, and then copy the
// config to the real builder.
FactoryBuilder throwAwayBuilder = BaggagePropagation.newFactoryBuilder(createThrowAwayFactory());
baggagePropagationCustomizers.orderedStream()
.forEach((customizer) -> customizer.customize(throwAwayBuilder));
CompositePropagationFactory propagationFactory = CompositePropagationFactory.create(
this.tracingProperties.getPropagation(), BRAVE_BAGGAGE_MANAGER,
LocalBaggageFields.extractFrom(throwAwayBuilder));
FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(propagationFactory);
throwAwayBuilder.configs().forEach(builder::add);
return builder;
}

@SuppressWarnings("deprecation")
private Factory createThrowAwayFactory() {
return new Factory() {

@Override
public <K> Propagation<K> create(KeyFactory<K> keyFactory) {
return null;
}

};
}

@Bean
@Order(0)
BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() {
return (builder) -> {
List<String> remoteFields = this.tracingProperties.getBaggage().getRemoteFields();
for (String fieldName : remoteFields) {
builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName)));
}
};
}

@Bean
@ConditionalOnMissingBean
Factory propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) {
return factoryBuilder.build();
}

@Bean
@ConditionalOnMissingBean
CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder(
ObjectProvider<CorrelationScopeCustomizer> correlationScopeCustomizers) {
CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder();
correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
}

@Bean
@Order(0)
@ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled",
matchIfMissing = true)
CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() {
return (builder) -> {
Correlation correlationProperties = this.tracingProperties.getBaggage().getCorrelation();
for (String field : correlationProperties.getFields()) {
BaggageField baggageField = BaggageField.create(field);
SingleCorrelationField correlationField = SingleCorrelationField.newBuilder(baggageField)
.flushOnUpdate()
.build();
builder.add(correlationField);
}
};
}

@Bean
@ConditionalOnMissingBean(CorrelationScopeDecorator.class)
ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) {
return builder.build();
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* Copyright 2012-2023 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.boot.actuate.autoconfigure.tracing;

import java.util.List;

import brave.baggage.BaggageField;
import brave.baggage.BaggagePropagation;
import brave.baggage.BaggagePropagation.FactoryBuilder;
import brave.baggage.BaggagePropagationConfig;
import brave.baggage.BaggagePropagationCustomizer;
import brave.baggage.CorrelationScopeConfig.SingleCorrelationField;
import brave.baggage.CorrelationScopeCustomizer;
import brave.baggage.CorrelationScopeDecorator;
import brave.context.slf4j.MDCScopeDecorator;
import brave.propagation.CurrentTraceContext.ScopeDecorator;
import brave.propagation.Propagation;
import brave.propagation.Propagation.Factory;
import brave.propagation.Propagation.KeyFactory;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Baggage.Correlation;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
* Brave propagation configurations. They are imported by {@link BraveAutoConfiguration}.
*
* @author Moritz Halbritter
*/
class BravePropagationConfigurations {

/**
* Propagates traces but no baggage.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", havingValue = "false")
static class PropagationWithoutBaggage {

@Bean
@ConditionalOnMissingBean(Factory.class)
@ConditionalOnEnabledTracing
CompositePropagationFactory propagationFactory(TracingProperties properties) {
return CompositePropagationFactory.create(properties.getPropagation());
}

}

/**
* Propagates traces and baggage.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", matchIfMissing = true)
@EnableConfigurationProperties(TracingProperties.class)
static class PropagationWithBaggage {

private final TracingProperties tracingProperties;

PropagationWithBaggage(TracingProperties tracingProperties) {
this.tracingProperties = tracingProperties;
}

@Bean
@ConditionalOnMissingBean
BaggagePropagation.FactoryBuilder propagationFactoryBuilder(
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
// There's a chicken-and-egg problem here: to create a builder, we need a
// factory. But the CompositePropagationFactory needs data from the builder.
// We create a throw-away builder with a throw-away factory, and then copy the
// config to the real builder.
FactoryBuilder throwAwayBuilder = BaggagePropagation.newFactoryBuilder(createThrowAwayFactory());
baggagePropagationCustomizers.orderedStream()
.forEach((customizer) -> customizer.customize(throwAwayBuilder));
CompositePropagationFactory propagationFactory = CompositePropagationFactory.create(
this.tracingProperties.getPropagation(), BraveAutoConfiguration.BRAVE_BAGGAGE_MANAGER,
LocalBaggageFields.extractFrom(throwAwayBuilder));
FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(propagationFactory);
throwAwayBuilder.configs().forEach(builder::add);
return builder;
}

@SuppressWarnings("deprecation")
private Factory createThrowAwayFactory() {
return new Factory() {

@Override
public <K> Propagation<K> create(KeyFactory<K> keyFactory) {
return null;
}

};
}

@Bean
@Order(0)
BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() {
return (builder) -> {
List<String> remoteFields = this.tracingProperties.getBaggage().getRemoteFields();
for (String fieldName : remoteFields) {
builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName)));
}
};
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledTracing
Factory propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) {
return factoryBuilder.build();
}

@Bean
@ConditionalOnMissingBean
CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder(
ObjectProvider<CorrelationScopeCustomizer> correlationScopeCustomizers) {
CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder();
correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
}

@Bean
@Order(0)
@ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled",
matchIfMissing = true)
CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() {
return (builder) -> {
Correlation correlationProperties = this.tracingProperties.getBaggage().getCorrelation();
for (String field : correlationProperties.getFields()) {
BaggageField baggageField = BaggageField.create(field);
SingleCorrelationField correlationField = SingleCorrelationField.newBuilder(baggageField)
.flushOnUpdate()
.build();
builder.add(correlationField);
}
};
}

@Bean
@ConditionalOnMissingBean(CorrelationScopeDecorator.class)
ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) {
return builder.build();
}

}

/**
* Propagates neither traces nor baggage.
*/
@Configuration(proxyBeanMethods = false)
static class NoPropagation {

@Bean
@ConditionalOnMissingBean(Factory.class)
CompositePropagationFactory noopPropagationFactory() {
return CompositePropagationFactory.noop();
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.boot.actuate.autoconfigure.tracing;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
Expand Down Expand Up @@ -84,6 +85,14 @@ public TraceContext decorate(TraceContext context) {
.orElse(context);
}

/**
* Creates a new {@link CompositePropagationFactory} which doesn't do any propagation.
* @return the {@link CompositePropagationFactory}
*/
static CompositePropagationFactory noop() {
return new CompositePropagationFactory(Collections.emptyList(), Collections.emptyList());
}

/**
* Creates a new {@link CompositePropagationFactory}.
* @param properties the propagation properties
Expand Down
Loading

0 comments on commit 02347ab

Please sign in to comment.