Make CurrentTraceContext.Builder a bean#35424
Make CurrentTraceContext.Builder a bean#35424be-hase wants to merge 3 commits intospring-projects:mainfrom
Conversation
|
@be-hase Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
| @ConditionalOnMissingBean | ||
| @ConditionalOnBean(Sender.class) | ||
| AsyncReporter<Span> spanReporter(Sender sender, BytesEncoder<Span> encoder) { | ||
| Reporter<Span> spanReporter(Sender sender, BytesEncoder<Span> encoder) { |
There was a problem hiding this comment.
I think this could be considered a bug and, therefore, it should be handled separately. Could you please split this out into a new PR, along with a test that verifies that the auto-configured spanReporter bean backs off when you define a custom Reporter bean?
| scopeDecorators.forEach(currentTraceContextBuilder::addScopeDecorator); | ||
| for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) { | ||
| currentTraceContextCustomizer.customize(builder); | ||
| currentTraceContextCustomizer.customize(currentTraceContextBuilder); |
There was a problem hiding this comment.
I think that any CurrentTraceContextCustomizer beans should be applied to the braveCurrentTraceContextBuilder bean rather than only applying them when creating the CurrentTraceContext. This will align with other areas where we define a builder bean such as Jackson2ObjectMapperBuilder and RestTemplateBuilder.
There was a problem hiding this comment.
Is this what you intend to do?
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
public CurrentTraceContext.Builder braveCurrentTraceContextBuilder(List<CurrentTraceContextCustomizer> currentTraceContextCustomizers) {
CurrentTraceContext.Builder builder =ThreadLocalCurrentTraceContext.newBuilder();
for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) {
currentTraceContextCustomizer.customize(builder);
}
return builder;
}But if we do, we will have to write code to iterate and apply the CurrentTraceContextCustomizers each time you want to change the type of CurrentTraceContext. I think this is inconvenient.
@Bean
@Scope("prototype")
public CurrentTraceContext.Builder braveCurrentTraceContextBuilder(List<CurrentTraceContextCustomizer> currentTraceContextCustomizers) {
CurrentTraceContext.Builder builder = StrictCurrentTraceContext.newBuilder();
for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) {
currentTraceContextCustomizer.customize(builder);
}
return builder;
}There was a problem hiding this comment.
Yes, for consistency with how other builders and applying customisers to them, I think we need to do something like this.
Taking a step back, perhaps we would be better offering a configuration property that allows control of the type of builder that is auto-configured. Its value could be thread local, strict, or standard which would map to ThreadLocalCurrentTraceContext.Builder, StrictCurrentTraceContext.Builder and CurrentTraceContext.Builder respectively.
There was a problem hiding this comment.
Hmmm. How about putting Supplier<CurrentTraceContext.Builder> in the bean then?
This would make it easy to change the type of CurrentTraceContext.
@Bean
@ConditionalOnMissingBean
public Supplier<CurrentTraceContext.Builder> braveCurrentTraceContextBuilderSupplier() {
return ThreadLocalCurrentTraceContext::newBuilder;
}
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
public CurrentTraceContext.Builder braveCurrentTraceContextBuilder(
Supplier<CurrentTraceContext.Builder> builderSupplier,
List<CurrentTraceContext.ScopeDecorator> scopeDecorators,
List<CurrentTraceContextCustomizer> currentTraceContextCustomizers) {
CurrentTraceContext.Builder builder = builderSupplier.get();
scopeDecorators.forEach(builder::addScopeDecorator);
for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) {
currentTraceContextCustomizer.customize(builder);
}
return builder;
}
@Bean
@ConditionalOnMissingBean
public CurrentTraceContext braveCurrentTraceContext(CurrentTraceContext.Builder currentTraceContextBuilder) {
return currentTraceContextBuilder.build();
}There was a problem hiding this comment.
Sorry, I don't think that's a good idea. I can't think of anywhere else where we have the indirection of a Supplier providing access to a builder. I don't think there's anything that's unique about this situation to justify it and it's likely to cause confusion.
There was a problem hiding this comment.
I think it is an idea that would make it easier to use different CurrentTraceContexts, but yes, Supplier may be confused.
Hmmm, ok, I'll close this PR, thanks.
Workaround by registering my own bean.
@Bean
fun braveCurrentTraceContext(
scopeDecorators: List<CurrentTraceContext.ScopeDecorator>,
currentTraceContextCustomizers: List<CurrentTraceContextCustomizer>,
): CurrentTraceContext {
// See: https://armeria.dev/docs/advanced-zipkin
val builder = RequestContextCurrentTraceContext.builder()
scopeDecorators.forEach(Consumer { scopeDecorator: CurrentTraceContext.ScopeDecorator ->
builder.addScopeDecorator(
scopeDecorator
)
})
for (currentTraceContextCustomizer in currentTraceContextCustomizers) {
currentTraceContextCustomizer.customize(builder)
}
return builder.build()
}| @Scope("prototype") | ||
| @ConditionalOnMissingBean | ||
| public CurrentTraceContext braveCurrentTraceContext(List<CurrentTraceContext.ScopeDecorator> scopeDecorators, | ||
| public CurrentTraceContext.Builder braveCurrentTraceContextBuilder() { |
There was a problem hiding this comment.
The tests should be updated to assert that this new bean is defined and that it backs off when a custom CurrentTraceContext.Builder bean is defined.
|
@be-hase Thank you for signing the Contributor License Agreement! |
When I did Micrometer Tracing/Observation support on my product, I noticed a part that I want to fix on the spring boot side, so I'm throwing a PR.
( I was wondering if I should start an issue first, but since it is a trivial fix, I will throw a PR directly. Sorry.)
Modifications
BraveAutoConfiguration.java
I would like to put CurrentTraceContext.Builder in the bean and use it.
Why:
Because the framework(armeria) I am using, requires the use of
RequestContextCurrentTraceContextinstead ofThereadLocalCurrentTraceContext.This modification will help users who are using something other than the
ThreadLocalCurrentTraceContext.For example, it is also useful when you want to use
StrictCurrentTraceContextfor debugging purposes.https://github.com/openzipkin/brave/blob/f4a2c7f7d0b8c2725ffef99fb4a5ccca222b6492/brave/src/main/java/brave/propagation/StrictCurrentTraceContext.java
ZipkinConfigurations.ReporterConfiguration
I want to use a
Reporter<Span>that I created myself(bean configuration).For some reason, the current
AsyncReporter<Span>is used, so if I configure the bean by myself, twoReporter<Span>are created.ToDo