Skip to content

Commit a257408

Browse files
[Observability] MDC, Context Propagation (via B3 and W3C) and Baggage
1 parent 0f44e69 commit a257408

File tree

8 files changed

+799
-23
lines changed

8 files changed

+799
-23
lines changed

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

Lines changed: 153 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121
import brave.Tracing;
2222
import brave.Tracing.Builder;
2323
import brave.TracingCustomizer;
24+
import brave.baggage.BaggageField;
25+
import brave.baggage.BaggagePropagation;
26+
import brave.baggage.BaggagePropagationConfig;
27+
import brave.baggage.BaggagePropagationCustomizer;
28+
import brave.baggage.CorrelationScopeConfig;
29+
import brave.baggage.CorrelationScopeCustomizer;
30+
import brave.baggage.CorrelationScopeDecorator;
31+
import brave.context.slf4j.MDCScopeDecorator;
2432
import brave.handler.SpanHandler;
2533
import brave.http.HttpClientHandler;
2634
import brave.http.HttpClientRequest;
@@ -33,19 +41,27 @@
3341
import brave.propagation.CurrentTraceContext;
3442
import brave.propagation.CurrentTraceContext.ScopeDecorator;
3543
import brave.propagation.CurrentTraceContextCustomizer;
44+
import brave.propagation.Propagation;
3645
import brave.propagation.Propagation.Factory;
3746
import brave.propagation.ThreadLocalCurrentTraceContext;
3847
import brave.sampler.Sampler;
3948
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
4049
import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext;
4150
import io.micrometer.tracing.brave.bridge.BraveHttpClientHandler;
4251
import io.micrometer.tracing.brave.bridge.BraveHttpServerHandler;
52+
import io.micrometer.tracing.brave.bridge.BravePropagator;
4353
import io.micrometer.tracing.brave.bridge.BraveTracer;
54+
import io.micrometer.tracing.brave.bridge.W3CPropagation;
55+
import org.slf4j.MDC;
4456

57+
import org.springframework.beans.factory.ObjectProvider;
4558
import org.springframework.boot.autoconfigure.AutoConfiguration;
4659
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
60+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
4761
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
4862
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
63+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
64+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4965
import org.springframework.boot.context.properties.EnableConfigurationProperties;
5066
import org.springframework.context.annotation.Bean;
5167
import org.springframework.context.annotation.Configuration;
@@ -55,6 +71,7 @@
5571
* {@link EnableAutoConfiguration Auto-configuration} for Brave.
5672
*
5773
* @author Moritz Halbritter
74+
* @author Marcin Grzejszczak
5875
* @since 3.0.0
5976
*/
6077
@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class)
@@ -105,12 +122,6 @@ public CurrentTraceContext braveCurrentTraceContext(List<CurrentTraceContext.Sco
105122
return builder.build();
106123
}
107124

108-
@Bean
109-
@ConditionalOnMissingBean
110-
public Factory bravePropagationFactory() {
111-
return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
112-
}
113-
114125
@Bean
115126
@ConditionalOnMissingBean
116127
public Sampler braveSampler(TracingProperties properties) {
@@ -135,21 +146,35 @@ public HttpClientHandler<HttpClientRequest, HttpClientResponse> httpClientHandle
135146
return HttpClientHandler.create(httpTracing);
136147
}
137148

149+
@Configuration(proxyBeanMethods = false)
150+
@ConditionalOnMissingClass("io.micrometer.tracing.brave.bridge.BraveTracer")
151+
static class BraveMicrometerMissing {
152+
153+
@Bean
154+
@ConditionalOnMissingBean
155+
@ConditionalOnProperty(value = "management.tracing.propagation.type", havingValue = "B3", matchIfMissing = true)
156+
Factory bravePropagationFactory() {
157+
return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
158+
}
159+
160+
}
161+
138162
@Configuration(proxyBeanMethods = false)
139163
@ConditionalOnClass(BraveTracer.class)
140164
static class BraveMicrometer {
141165

166+
private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager();
167+
142168
@Bean
143169
@ConditionalOnMissingBean
144-
BraveTracer braveTracerBridge(brave.Tracer tracer, CurrentTraceContext currentTraceContext,
145-
BraveBaggageManager braveBaggageManager) {
146-
return new BraveTracer(tracer, new BraveCurrentTraceContext(currentTraceContext), braveBaggageManager);
170+
BraveTracer braveTracerBridge(brave.Tracer tracer, CurrentTraceContext currentTraceContext) {
171+
return new BraveTracer(tracer, new BraveCurrentTraceContext(currentTraceContext), BRAVE_BAGGAGE_MANAGER);
147172
}
148173

149174
@Bean
150175
@ConditionalOnMissingBean
151-
BraveBaggageManager braveBaggageManager() {
152-
return new BraveBaggageManager();
176+
BravePropagator bravePropagator(Tracing tracing) {
177+
return new BravePropagator(tracing);
153178
}
154179

155180
@Bean
@@ -166,6 +191,123 @@ BraveHttpClientHandler braveHttpClientHandler(
166191
return new BraveHttpClientHandler(httpClientHandler);
167192
}
168193

194+
@Configuration(proxyBeanMethods = false)
195+
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", havingValue = "false",
196+
matchIfMissing = true)
197+
static class BraveNoBaggageConfiguration {
198+
199+
@Bean
200+
@ConditionalOnMissingBean
201+
@ConditionalOnProperty(value = "management.tracing.propagation.type", havingValue = "W3C",
202+
matchIfMissing = true)
203+
Factory w3cPropagationNoBaggageFactory() {
204+
return new W3CPropagation(BRAVE_BAGGAGE_MANAGER, List.of()); // TODO: Use
205+
// snapshots
206+
// of
207+
// tracing
208+
// to not
209+
// use
210+
// baggage
211+
// for W3C
212+
}
213+
214+
@Bean
215+
@ConditionalOnMissingBean
216+
@ConditionalOnProperty(value = "management.tracing.propagation.type", havingValue = "B3")
217+
Factory b3PropagationNoBaggageFactory() {
218+
return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
219+
}
220+
221+
}
222+
223+
@Configuration(proxyBeanMethods = false)
224+
@ConditionalOnProperty(value = "management.tracing.baggage.enabled", matchIfMissing = true)
225+
static class BraveBaggageConfiguration {
226+
227+
@Bean
228+
@ConditionalOnMissingBean
229+
@ConditionalOnProperty(value = "management.tracing.propagation.type", havingValue = "W3C",
230+
matchIfMissing = true)
231+
BaggagePropagation.FactoryBuilder w3cPropagationFactory() {
232+
return BaggagePropagation.newFactoryBuilder(new W3CPropagation(BRAVE_BAGGAGE_MANAGER, List.of()));
233+
}
234+
235+
@Bean
236+
@ConditionalOnMissingBean
237+
@ConditionalOnProperty(value = "management.tracing.propagation.type", havingValue = "B3")
238+
BaggagePropagation.FactoryBuilder b3PropagationFactory() {
239+
return BaggagePropagation.newFactoryBuilder(
240+
B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build());
241+
}
242+
243+
@Bean
244+
@ConditionalOnMissingBean
245+
Propagation.Factory micrometerTracingPropagationWithBaggage(
246+
BaggagePropagation.FactoryBuilder factoryBuilder, TracingProperties tracingProperties,
247+
ObjectProvider<List<BaggagePropagationCustomizer>> baggagePropagationCustomizers) {
248+
List<String> remoteFields = tracingProperties.getBaggage().getRemoteFields();
249+
for (String fieldName : remoteFields) {
250+
factoryBuilder
251+
.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName)));
252+
}
253+
baggagePropagationCustomizers.ifAvailable(
254+
(customizers) -> customizers.forEach((customizer) -> customizer.customize(factoryBuilder)));
255+
return factoryBuilder.build();
256+
}
257+
258+
@Bean
259+
@ConditionalOnMissingBean(CorrelationScopeDecorator.class)
260+
@ConditionalOnBean(CorrelationScopeDecorator.Builder.class)
261+
@ConditionalOnProperty(value = "management.tracing.baggage.correlation-enabled", matchIfMissing = true)
262+
ScopeDecorator correlationFieldsCorrelationScopeDecorator(TracingProperties properties,
263+
ObjectProvider<List<CorrelationScopeCustomizer>> correlationScopeCustomizers,
264+
CorrelationScopeDecorator.Builder builder) {
265+
List<String> correlationFields = properties.getBaggage().getCorrelationFields();
266+
for (String field : correlationFields) {
267+
builder.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create(field))
268+
.flushOnUpdate().build());
269+
}
270+
correlationScopeCustomizers.ifAvailable(
271+
(customizers) -> customizers.forEach((customizer) -> customizer.customize(builder)));
272+
return builder.build();
273+
}
274+
275+
@Bean
276+
@ConditionalOnMissingBean(CorrelationScopeDecorator.class)
277+
@ConditionalOnBean(CorrelationScopeDecorator.Builder.class)
278+
@ConditionalOnProperty(value = "management.tracing.baggage.correlation-enabled", havingValue = "false")
279+
ScopeDecorator noCorrelationFieldsCorrelationScopeDecorator(CorrelationScopeDecorator.Builder builder,
280+
ObjectProvider<List<CorrelationScopeCustomizer>> correlationScopeCustomizers) {
281+
correlationScopeCustomizers.ifAvailable(
282+
(customizers) -> customizers.forEach((customizer) -> customizer.customize(builder)));
283+
return builder.build();
284+
}
285+
286+
}
287+
288+
}
289+
290+
@Configuration(proxyBeanMethods = false)
291+
static class CorrelationScopeDecoratorConfiguration {
292+
293+
@Bean
294+
@ConditionalOnMissingBean
295+
@ConditionalOnClass(MDC.class)
296+
CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder() {
297+
return MDCScopeDecorator.newBuilder();
298+
}
299+
300+
@Bean
301+
@ConditionalOnMissingBean(CorrelationScopeDecorator.class)
302+
@ConditionalOnBean(CorrelationScopeDecorator.Builder.class)
303+
@ConditionalOnMissingClass("io.micrometer.tracing.brave.bridge.BraveTracer")
304+
ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder,
305+
ObjectProvider<List<CorrelationScopeCustomizer>> correlationScopeCustomizers) {
306+
correlationScopeCustomizers
307+
.ifAvailable((customizers) -> customizers.forEach((customizer) -> customizer.customize(builder)));
308+
return builder.build();
309+
}
310+
169311
}
170312

171313
}

0 commit comments

Comments
 (0)