-
Notifications
You must be signed in to change notification settings - Fork 848
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a AutoConfiguredComponentWrapper SPI #3714
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for 1.7
* interface will be invoked to replace it, commonly with a wrapping {@link SpanExporter} which uses | ||
* {@link io.opentelemetry.sdk.trace.data.DelegatingSpanData} to adjust the exported data. | ||
*/ | ||
public interface SpanExporterWrapper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somehow SpanExporterWrapperProvider
doesn't seem right, but if the Provider
suffix pattern is important, it could maybe be SpanExporterWrappingProvider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like we're building a pipeline tool via the decorator pattern. Does it make more sense to instead expose something like SpanProcessor, but in a more explicit that allows modifying spans? What are the use cases here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have two use cases:
- Modify or drop certain span attributes using
DelegatingSpanData
- Drop certain spans all together from
Collection<SpanData>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the job of a span processor. From the spec:
SDK MUST allow users to implement and configure custom processors and decorate built-in processors for advanced scenarios such as tagging or filtering.
I put together a little test demonstration of how to accomplish this with span processors here: https://github.com/jack-berg/opentelemetry-java/blob/filter-span-processor/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/FilterAndEnrichSpanProcessorTest.java#L26-L58
Its definitely possible to replicate that via SPI through the SdkTracerProviderConfigurer
. But not very conveniently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks good but can we make SpanProcessor
loadable through SPI? E.g. Maybe a SpanProcessorProvider
? That will make configuration part easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it's not possible to remove attributes in a span processor since the span is not mutable in onEnd. This came up in the pre-1.0 days and it was generally understood that unless Span processor were updated with a mutable end method, Span exporter is the only place to have full control of mutation, especially filtering attributes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well timed comment came in too :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added another example to my demo branch that shows how to create a SpanExporter
, which delegates to another SpanExporter
after filtering out certain attributes: https://github.com/jack-berg/opentelemetry-java/blob/filter-span-processor/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/FilterSpanExporter.java#L30-L61
In this case, it filters out attributes which are not of type string.
@edwardxia Can you check if this pattern will work fine for you? |
It should work, and indeed this would be much easier to use comparing to custom exporter SPI just for the decorating use case. Thanks! |
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. | ||
+++ NEW SUPERCLASS: java.lang.Object | ||
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.trace.export.SpanExporter wrap(io.opentelemetry.sdk.trace.export.SpanExporter, io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Urk. Did we intend to make this module stable, even though the autoconfigure module isn't stable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we had intended the interfaces to go stable when we did the split. We talked about this at the time :)
for (SpanExporterWrapper wrapper : wrappers) { | ||
exporter = wrapper.wrap(exporter, config); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this makes me nervous, a bit. Are there cases where this arbitrary ordering might break something inadvertently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add an Order method with default returning 0 like we have in other SPIs.
Hmm. Although this does solve the very narrow use-case at hand, I wonder if we're thinking too small here. If we start providing SPIs like this, I feel like we're going to end up with a giant pile of SPIs that will be hard to figure out what to do with. Would it make sense to take a step back and figure out a more general solution to the problem of "take something autoconfigured and tweak it a bit", rather than proliferate the SPIs? |
@jkwatson How about a single SPI with multiple methods for each of the autoconfigured pieces, |
I think something like this would be good. |
…nto span-exporter-wrapper
* automatically created by autoconfiguration, for example a span exporter, implementations of this | ||
* interface will be invoked to replace it, resulting in the final used component. | ||
*/ | ||
public interface AutoConfiguredComponentWrapper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have defined this and used in place of my previous proposed SpanExporterWrapper. Let me know if this looks OK and I'll slot it in the rest of the places
Codecov Report
@@ Coverage Diff @@
## main #3714 +/- ##
============================================
- Coverage 89.24% 89.16% -0.08%
- Complexity 3839 3868 +29
============================================
Files 462 465 +3
Lines 11969 12085 +116
Branches 1163 1181 +18
============================================
+ Hits 10682 10776 +94
- Misses 905 914 +9
- Partials 382 395 +13
Continue to review full report at Codecov.
|
public interface AutoConfiguredComponentWrapper { | ||
|
||
/** Wraps a {@link Resource}. */ | ||
default Resource wrap(Resource resource, ConfigProperties config) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrap
is an odd name here, since you'd presumably just use the normal merge
functionality for Resources, wouldn't you?
I wonder if the names of these methods should be something more generic than wrap
, but a good name escapes me right this second. augment
? decorate
? customize
maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the more I think about it, the more I like "AutoConfiguredComponentCustomizer" as the SPI name.
Closing in favor of #3753 |
Also graduates DelegatingSpanData out of incubator.
Fixes #3695