Skip to content

Commit 02347ab

Browse files
committed
Disable propagation of traces if tracing is disabled
Closes gh-38641
1 parent a0fc2d4 commit 02347ab

File tree

7 files changed

+320
-163
lines changed

7 files changed

+320
-163
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java

Lines changed: 5 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,10 @@
2424
import brave.Tracing;
2525
import brave.Tracing.Builder;
2626
import brave.TracingCustomizer;
27-
import brave.baggage.BaggageField;
28-
import brave.baggage.BaggagePropagation;
29-
import brave.baggage.BaggagePropagation.FactoryBuilder;
30-
import brave.baggage.BaggagePropagationConfig;
31-
import brave.baggage.BaggagePropagationCustomizer;
32-
import brave.baggage.CorrelationScopeConfig.SingleCorrelationField;
33-
import brave.baggage.CorrelationScopeCustomizer;
34-
import brave.baggage.CorrelationScopeDecorator;
35-
import brave.context.slf4j.MDCScopeDecorator;
3627
import brave.handler.SpanHandler;
3728
import brave.propagation.CurrentTraceContext;
38-
import brave.propagation.CurrentTraceContext.ScopeDecorator;
3929
import brave.propagation.CurrentTraceContextCustomizer;
40-
import brave.propagation.Propagation;
4130
import brave.propagation.Propagation.Factory;
42-
import brave.propagation.Propagation.KeyFactory;
4331
import brave.propagation.ThreadLocalCurrentTraceContext;
4432
import brave.sampler.Sampler;
4533
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
@@ -53,17 +41,15 @@
5341
import io.micrometer.tracing.exporter.SpanReporter;
5442

5543
import org.springframework.beans.factory.ObjectProvider;
56-
import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Baggage.Correlation;
5744
import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType;
5845
import org.springframework.boot.autoconfigure.AutoConfiguration;
5946
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
6047
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
6148
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
62-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
6349
import org.springframework.boot.context.properties.EnableConfigurationProperties;
6450
import org.springframework.boot.context.properties.IncompatibleConfigurationException;
6551
import org.springframework.context.annotation.Bean;
66-
import org.springframework.context.annotation.Configuration;
52+
import org.springframework.context.annotation.Import;
6753
import org.springframework.core.Ordered;
6854
import org.springframework.core.annotation.Order;
6955
import org.springframework.core.env.Environment;
@@ -79,9 +65,12 @@
7965
@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class)
8066
@ConditionalOnClass({ Tracer.class, BraveTracer.class })
8167
@EnableConfigurationProperties(TracingProperties.class)
68+
@Import({ BravePropagationConfigurations.PropagationWithoutBaggage.class,
69+
BravePropagationConfigurations.PropagationWithBaggage.class,
70+
BravePropagationConfigurations.NoPropagation.class })
8271
public class BraveAutoConfiguration {
8372

84-
private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager();
73+
static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager();
8574

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

185-
@Configuration(proxyBeanMethods = false)
186-
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", havingValue = "false")
187-
static class BraveNoBaggageConfiguration {
188-
189-
@Bean
190-
@ConditionalOnMissingBean
191-
Factory propagationFactory(TracingProperties properties) {
192-
return CompositePropagationFactory.create(properties.getPropagation());
193-
}
194-
195-
}
196-
197-
@Configuration(proxyBeanMethods = false)
198-
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", matchIfMissing = true)
199-
static class BraveBaggageConfiguration {
200-
201-
private final TracingProperties tracingProperties;
202-
203-
BraveBaggageConfiguration(TracingProperties tracingProperties) {
204-
this.tracingProperties = tracingProperties;
205-
}
206-
207-
@Bean
208-
@ConditionalOnMissingBean
209-
BaggagePropagation.FactoryBuilder propagationFactoryBuilder(
210-
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
211-
// There's a chicken-and-egg problem here: to create a builder, we need a
212-
// factory. But the CompositePropagationFactory needs data from the builder.
213-
// We create a throw-away builder with a throw-away factory, and then copy the
214-
// config to the real builder.
215-
FactoryBuilder throwAwayBuilder = BaggagePropagation.newFactoryBuilder(createThrowAwayFactory());
216-
baggagePropagationCustomizers.orderedStream()
217-
.forEach((customizer) -> customizer.customize(throwAwayBuilder));
218-
CompositePropagationFactory propagationFactory = CompositePropagationFactory.create(
219-
this.tracingProperties.getPropagation(), BRAVE_BAGGAGE_MANAGER,
220-
LocalBaggageFields.extractFrom(throwAwayBuilder));
221-
FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(propagationFactory);
222-
throwAwayBuilder.configs().forEach(builder::add);
223-
return builder;
224-
}
225-
226-
@SuppressWarnings("deprecation")
227-
private Factory createThrowAwayFactory() {
228-
return new Factory() {
229-
230-
@Override
231-
public <K> Propagation<K> create(KeyFactory<K> keyFactory) {
232-
return null;
233-
}
234-
235-
};
236-
}
237-
238-
@Bean
239-
@Order(0)
240-
BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() {
241-
return (builder) -> {
242-
List<String> remoteFields = this.tracingProperties.getBaggage().getRemoteFields();
243-
for (String fieldName : remoteFields) {
244-
builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName)));
245-
}
246-
};
247-
}
248-
249-
@Bean
250-
@ConditionalOnMissingBean
251-
Factory propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) {
252-
return factoryBuilder.build();
253-
}
254-
255-
@Bean
256-
@ConditionalOnMissingBean
257-
CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder(
258-
ObjectProvider<CorrelationScopeCustomizer> correlationScopeCustomizers) {
259-
CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder();
260-
correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
261-
return builder;
262-
}
263-
264-
@Bean
265-
@Order(0)
266-
@ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled",
267-
matchIfMissing = true)
268-
CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() {
269-
return (builder) -> {
270-
Correlation correlationProperties = this.tracingProperties.getBaggage().getCorrelation();
271-
for (String field : correlationProperties.getFields()) {
272-
BaggageField baggageField = BaggageField.create(field);
273-
SingleCorrelationField correlationField = SingleCorrelationField.newBuilder(baggageField)
274-
.flushOnUpdate()
275-
.build();
276-
builder.add(correlationField);
277-
}
278-
};
279-
}
280-
281-
@Bean
282-
@ConditionalOnMissingBean(CorrelationScopeDecorator.class)
283-
ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) {
284-
return builder.build();
285-
}
286-
287-
}
288-
289174
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.tracing;
18+
19+
import java.util.List;
20+
21+
import brave.baggage.BaggageField;
22+
import brave.baggage.BaggagePropagation;
23+
import brave.baggage.BaggagePropagation.FactoryBuilder;
24+
import brave.baggage.BaggagePropagationConfig;
25+
import brave.baggage.BaggagePropagationCustomizer;
26+
import brave.baggage.CorrelationScopeConfig.SingleCorrelationField;
27+
import brave.baggage.CorrelationScopeCustomizer;
28+
import brave.baggage.CorrelationScopeDecorator;
29+
import brave.context.slf4j.MDCScopeDecorator;
30+
import brave.propagation.CurrentTraceContext.ScopeDecorator;
31+
import brave.propagation.Propagation;
32+
import brave.propagation.Propagation.Factory;
33+
import brave.propagation.Propagation.KeyFactory;
34+
35+
import org.springframework.beans.factory.ObjectProvider;
36+
import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Baggage.Correlation;
37+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
38+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
39+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
40+
import org.springframework.context.annotation.Bean;
41+
import org.springframework.context.annotation.Configuration;
42+
import org.springframework.core.annotation.Order;
43+
44+
/**
45+
* Brave propagation configurations. They are imported by {@link BraveAutoConfiguration}.
46+
*
47+
* @author Moritz Halbritter
48+
*/
49+
class BravePropagationConfigurations {
50+
51+
/**
52+
* Propagates traces but no baggage.
53+
*/
54+
@Configuration(proxyBeanMethods = false)
55+
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", havingValue = "false")
56+
static class PropagationWithoutBaggage {
57+
58+
@Bean
59+
@ConditionalOnMissingBean(Factory.class)
60+
@ConditionalOnEnabledTracing
61+
CompositePropagationFactory propagationFactory(TracingProperties properties) {
62+
return CompositePropagationFactory.create(properties.getPropagation());
63+
}
64+
65+
}
66+
67+
/**
68+
* Propagates traces and baggage.
69+
*/
70+
@Configuration(proxyBeanMethods = false)
71+
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", matchIfMissing = true)
72+
@EnableConfigurationProperties(TracingProperties.class)
73+
static class PropagationWithBaggage {
74+
75+
private final TracingProperties tracingProperties;
76+
77+
PropagationWithBaggage(TracingProperties tracingProperties) {
78+
this.tracingProperties = tracingProperties;
79+
}
80+
81+
@Bean
82+
@ConditionalOnMissingBean
83+
BaggagePropagation.FactoryBuilder propagationFactoryBuilder(
84+
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
85+
// There's a chicken-and-egg problem here: to create a builder, we need a
86+
// factory. But the CompositePropagationFactory needs data from the builder.
87+
// We create a throw-away builder with a throw-away factory, and then copy the
88+
// config to the real builder.
89+
FactoryBuilder throwAwayBuilder = BaggagePropagation.newFactoryBuilder(createThrowAwayFactory());
90+
baggagePropagationCustomizers.orderedStream()
91+
.forEach((customizer) -> customizer.customize(throwAwayBuilder));
92+
CompositePropagationFactory propagationFactory = CompositePropagationFactory.create(
93+
this.tracingProperties.getPropagation(), BraveAutoConfiguration.BRAVE_BAGGAGE_MANAGER,
94+
LocalBaggageFields.extractFrom(throwAwayBuilder));
95+
FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(propagationFactory);
96+
throwAwayBuilder.configs().forEach(builder::add);
97+
return builder;
98+
}
99+
100+
@SuppressWarnings("deprecation")
101+
private Factory createThrowAwayFactory() {
102+
return new Factory() {
103+
104+
@Override
105+
public <K> Propagation<K> create(KeyFactory<K> keyFactory) {
106+
return null;
107+
}
108+
109+
};
110+
}
111+
112+
@Bean
113+
@Order(0)
114+
BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() {
115+
return (builder) -> {
116+
List<String> remoteFields = this.tracingProperties.getBaggage().getRemoteFields();
117+
for (String fieldName : remoteFields) {
118+
builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName)));
119+
}
120+
};
121+
}
122+
123+
@Bean
124+
@ConditionalOnMissingBean
125+
@ConditionalOnEnabledTracing
126+
Factory propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) {
127+
return factoryBuilder.build();
128+
}
129+
130+
@Bean
131+
@ConditionalOnMissingBean
132+
CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder(
133+
ObjectProvider<CorrelationScopeCustomizer> correlationScopeCustomizers) {
134+
CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder();
135+
correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
136+
return builder;
137+
}
138+
139+
@Bean
140+
@Order(0)
141+
@ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled",
142+
matchIfMissing = true)
143+
CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() {
144+
return (builder) -> {
145+
Correlation correlationProperties = this.tracingProperties.getBaggage().getCorrelation();
146+
for (String field : correlationProperties.getFields()) {
147+
BaggageField baggageField = BaggageField.create(field);
148+
SingleCorrelationField correlationField = SingleCorrelationField.newBuilder(baggageField)
149+
.flushOnUpdate()
150+
.build();
151+
builder.add(correlationField);
152+
}
153+
};
154+
}
155+
156+
@Bean
157+
@ConditionalOnMissingBean(CorrelationScopeDecorator.class)
158+
ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) {
159+
return builder.build();
160+
}
161+
162+
}
163+
164+
/**
165+
* Propagates neither traces nor baggage.
166+
*/
167+
@Configuration(proxyBeanMethods = false)
168+
static class NoPropagation {
169+
170+
@Bean
171+
@ConditionalOnMissingBean(Factory.class)
172+
CompositePropagationFactory noopPropagationFactory() {
173+
return CompositePropagationFactory.noop();
174+
}
175+
176+
}
177+
178+
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.actuate.autoconfigure.tracing;
1818

1919
import java.util.Collection;
20+
import java.util.Collections;
2021
import java.util.List;
2122
import java.util.function.Predicate;
2223
import java.util.stream.Stream;
@@ -84,6 +85,14 @@ public TraceContext decorate(TraceContext context) {
8485
.orElse(context);
8586
}
8687

88+
/**
89+
* Creates a new {@link CompositePropagationFactory} which doesn't do any propagation.
90+
* @return the {@link CompositePropagationFactory}
91+
*/
92+
static CompositePropagationFactory noop() {
93+
return new CompositePropagationFactory(Collections.emptyList(), Collections.emptyList());
94+
}
95+
8796
/**
8897
* Creates a new {@link CompositePropagationFactory}.
8998
* @param properties the propagation properties

0 commit comments

Comments
 (0)