-
Notifications
You must be signed in to change notification settings - Fork 889
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
Composite propagators: Clarify the behavior of multiple extractor #496
Comments
IMO propagators should be validating extracted contexts to ensure they are valid before setting them on the context. I could see this being important for use cases where the propagation format spec changes however. For instance, if Trace Context releases a version 2, you may want to have a v1 propagator as a fallback if the v2 propagator fails or vice versa. |
Maybe we should pass any extracted SpanContext down to the next propagators in chain to allow them to decide if they should extract and overwrite,...? |
I think this already happens implicitly because each propagator gets as input the context returned by the previous one. However, there is no way to know for the propagator whether any value left there was set by a another composite propagator component or is the value from the parent context, which should be overwritten. I think you should only add orthogonal components to an aggregate propagator. A new special ChainedPropagator API is probably required to coordinate multiple propagators competing for the same Context key. |
So in theory there should only be a propagator for each cross-cutting concern (tracing, correlation context), so they work on only one 'slot' of the What you mention has been known as 'fallback' propagators, as a stack-alike In such case, it would work like:
I'm wondering if we should add a section on this case (probably yes). |
As setting of propagators is possible via API which may have a lot independent clients it's maybe hard to ensure that there are no duplicates. e.g. HttpTextPropagator seem to be reused in grpc (and maybe other protocols having text header support) so each OTel plugin may add one instance of such a processor. |
A composite extractor with a policy would work to satisfy all use cases. For example, type ExtractPolicy int
const {
StopOnValid
ExtractAll
}
type struct CompositeExtractorWithPolicy {
extractors []*extractor
policy ExtractPolicy
extractValdiator func(context.Context) bool
}
func (cewp *CompositeExtractorPolicy) Extract(ctx context.Context, supplier HTTPSupplier) (context.Context) {
for extractor := range cewp.extractors {
newCtx := extractor.Extract(ctx, supplier)
valid := cewp.extractValidator(newCtx)
if cewp.policy == StopOnValid {
if valid {
return newCtx
}
}
}
} |
@rghetia But wouldn't this result in a propagator for one concern may stops extraction of another, unrelated concern? |
you just supply two sets for propagator with policy, one for each concern. |
We know that only a single context/key can be extracted. The precedence order should be configurable by the user of the system/SDK. Then if the extraction fails for any reason the SDK could "try again" with the next extractor. |
I'm doing related work around this, so will take it from here. |
Please see open-telemetry/opentelemetry-java#1339 as a prototype for this. A new Two questions arise:
Thoughts? cc @dyladan @pavolloffay @Oberon00 |
I think #671 solved the issue I pointed out in my comment #496 (comment). If we think a MultiPropagator is something that is generally useful, I think we should add it to the spec. Trying to specify it in detail might surface more issues. |
@Oberon00 For the record: I think specifing a |
I'm not sure how the concrete concern plays a role when defining a multi-propagator? I would think of something like class MultiHttpTextPropagator implements HttpTextPropagator {
public MultiHttpTextPropagator(Collection<HttpTextPropagator> extractors, Collection<HttpTextPropagator> injectors) { ... };
@Override
public <Carrier> void extract(Context target, Carrier c, Getter<Carrier> g) {...} // Call all extractors (unconditionally)
@Override
public <Carrier> void inject(Context target, Carrier c, Setter<Carrier> s) {...} // Call all injectors (unconditionally)
} If we want to not try all extractors everytime we'd just need to pass some |
Having a look at this P1 issue with @carlosalberto, should this really be a P2 because it looks like an addition to the API, not a breaking change that should go in earlier? Thinks java is the only one that has this atm. |
See my comment above #496 (comment):
Those "more issues" might require breaking changes to fix them. |
From the issue triage mtg today, talked with @carlosalberto and looks like with the PR #671 this issue can now be bumped down to P2 which means it is not necessarily a blocking change for freezing trace api. |
I'm confused if a MultiPropagator is different than the Composite Propagator already in the spec. Is this an additional thing, or a clarification of the existing one? |
I think it's about multiple propagators for the same concern. E.g. B3+W3C trace propagators at once. |
Ah, so Composite is multiple-concerns and Multi is multiple for a single concern. Got it. |
Looking at the Java
Not all span context propagators encode the full W3C TraceContext, for example Jaeger format doesn't encode tracestate. If the Jaeger propagator extracted first and you immediately return, the tracestate won't be propagated on. Also, what if the trace flags are not matching e.g. a load balancer before your service decides to set the sampled flag, but only sets it on the Jaeger header. Then if the Jaeger propagator is configured in Maybe the |
|
That just looks like the regular Composite Propagator mentioned in the spec. That has the issue of overwriting still, right? |
Yes. I just wanted to make sure that the old thing you pointed at wasn't a relevant part of the conversation, since it was deleted before 1.0.0 was released. |
If this issue is still relevant, please open a new issue with more detail. |
In a composite propagator there can be more than one Extractor for trace context. The specification doe not indicate how to handle extraction from two different propagators if both of them extracts valid trace context. In current implementation in Go the second extractor overwrites the first. So the last one wins. There are two problems with this.
The text was updated successfully, but these errors were encountered: