-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
OpenTelemetry context not propagated to a fork-join pool thread via the OpenTelemetryMpContextPropagation
#31417
Comments
/cc @brunobat (opentelemetry), @radcortez (opentelemetry) |
@radcortez I opened this issue you could be interested into. |
Hi @ppatierno can you please explain were is this My understanding is that you need managed managed threads to work in a container like Quarkus. |
@brunobat it was suggest and added by this PR #30478 |
My understanding is that is attaching the OTel context to a thread customised with |
So I don't understand the role of |
The issue is that the I've opened #31546 to fix this in the test. |
@radcortez I am confused I don't understand how it fixes my problem. Even because in my use case I don't have a Thread Thread[executor-thread-0,5,main] ----> 0e86b6dc0b77f82107401408e681068c - 5f7b36f74fddb93e
Thread Thread[ForkJoinPool-1-worker-19,5,main] ----> 00000000000000000000000000000000 - 0000000000000000
Thread Thread[ForkJoinPool-1-worker-19,5,main] ----> 0e86b6dc0b77f82107401408e681068c - 5f7b36f74fddb93e So the only difference is that the The output that I would expect, at least from what is my pov why the context propagation is not working would be this: Thread Thread[executor-thread-0,5,main] ----> 0e86b6dc0b77f82107401408e681068c - 5f7b36f74fddb93e
Thread Thread[ForkJoinPool-1-worker-19,5,main] ----> 0e86b6dc0b77f82107401408e681068c - 5f7b36f74fddb93e
Thread Thread[ForkJoinPool-1-worker-19,5,main] ----> 0e86b6dc0b77f82107401408e681068c - 5f7b36f74fddb93e |
It may be related to how the Kafka interceptor OTel instrumentation is doing. Do you have a reproducer I can look at? |
@radcortez I would like to take the Kafka interceptor OTel out of the picture ... why context is not available in the Thread Thread[executor-thread-0,5,main] ----> 0e86b6dc0b77f82107401408e681068c - 5f7b36f74fddb93e
Thread Thread[ForkJoinPool-1-worker-19,5,main] ----> 00000000000000000000000000000000 - 0000000000000000
Thread Thread[ForkJoinPool-1-worker-19,5,main] ----> 0e86b6dc0b77f82107401408e681068c - 5f7b36f74fddb93e Why context traceid-spanid is all zeros in the "middle"? If the context is right there, it will be ok in the Kafka interceptor OTel as well. |
Sorry, I didn't read your question correctly the first time and just focused on the requirement of The issue is that Only the new Is there a reason you want to apply the code in the |
Only the new CompletableFuture is affected by the propagation done by OpenTelemetryMpContextPropagation. Got it!
Let me reply with another question then ... what should I have in the
|
Correct. I'm not saying that you are wrong. Is just how the spec is designed with Is it possible to supply the Kafka interceptor to the next completable future? Theoretically, I don't see a reason for that not to work. What issue do you experience with it? @Ladicek are you aware of a way to propagate a context in |
Ah ok, then we are on the same page! That was the missing piece on my side, it is just by design.
The Kafka interceptor is something that you set when you create a Kafka producer client. It is called when you use the Kafka producer client send operation (to send a message to a Kafka topic). Before actually sending the message, the interceptor runs some code and then send the message. So it's where it adds the span to trace the send operation. |
But you do call some sort of What if you wrap that call in a |
I didn't get your suggestion actually :-( Let me share some part of the current code which is not updated (I have my tries with OpenTelemetry integration just locally for now). So this is the REST method called from outside and start the process of sending the message through the this returns a completable future, it starts a which then call a So what I was doing in the first REST related method was trying: return this.threadContext.withContextCapture(source.send(routingContext, body, topicName, async)); Hoping that wrapping that Completable future + the OpenTelemetryMpContextPropagation would have helped with context propagation. |
I don't really know what this issue is all about, but seeing code like return this.threadContext.withContextCapture(source.send(routingContext, body, topicName, async)); immediately triggers an alert in my head. This is virtually always wrong and if it compiles, that's by accident. The context propagation API is supposed to be used like this: return this.threadContext.withContextCapture(() -> source.send(routingContext, body, topicName, async)); |
What isn't clear from the description I wrote down in the very first comment with printing some log exactly?
I see that |
Something like this: threadContext
.withContextCapture(CompletableFuture.supplyAsync(new Supplier<Runnable>() {
@Override
public Runnable get() {
return new Runnable() {
@Override
public void run() {
// Send message here
}
};
}
}, customExecutorService))
.thenApplyAsync(new Function<Runnable, Void>() {
@Override
public Void apply(final Runnable runnable) {
runnable.run();
return null;
}
}, customExecutorService); |
Sorry, when I said "I don't really know what this issue is all about", I meant I haven't been involved here and I don't have the time to go through the history. I didn't mean to imply that the issue is unclear -- just to state that I don't know it. Now, you can of course call (And now I see that those overloads are not actually overloads [of |
@radcortez ... it seems too much :-) but I understand what you are proposing.
@Ladicek I see your point right ... I could try some refactoring to use Runnable, Callable or Supplier but to be honest as for the above comment, I am not sure I do really need the usage of |
|
While porting the Strimzi HTTP - Kafka bridge from pure Vert.x to Quarkus (using RESTeasy Reactive) I need OpenTelemetry context propagation across threads.
In our code, a REST call is executed in the Vert.x event loop which brings the OTel context (with the HTTP call span) within the Vert.x context. The REST call then uses
CompletableFuture.supplyAsync
to run a Kafka client call (in order to free the Vert.x loop soon) which uses an interceptor (from the OpenTelementry Kafka instrumentation library) to add its own span which has to be a child of the HTTP call span.The problem is that the original OTel context is not propagated in the fork-join pool thread, where the Kafka call runs.
In order to do that I found that:
ManagedExecutor
instance to run theCompletableFuture.supplyAsync
code in a Quarkus pool related thread and the OTel context is propagated correctly.@Blocking
annotation. Not using theCompletableFuture.supplyAsync
and running everything in the same worker thread (not using the Vert.x event loop at all).OpenTelemetryMpContextPropagation
(coming in Quarkus 3.0.0) which should help to do the same by capturing the context withthreadContext.withContextCapture
on theCompletableFuture.supplyAsync
call.While the first two options work, the third one doesn't.
If I understood the purpose of the
OpenTelemetryMpContextPropagation
, my expectation was that the OTel context is propagated from a Quarkus managed thread (i.e. Vert.x event loop, any worker thread, ...) to a fork-join pool as well but it seems not happening.In our code, the Kafka related span is not attached as child of the HTTP request span, because of the OTel context not propagated (because of missing Vert.x context) . I was able to see why and replicated in the
OpenTelemetryMpContextPropagationTest
just by printing the trace and span ids this way.The output is something like this:
As you can see the OTel context is not propagated in the fork-join pool thread, not managed by Quarkus, and it returns to be available in the
thenApplyAsync
because the code is executed in some Quarkus managed thread, I guess.AFAIU, the purpose of the
OpenTelemetryMpContextPropagation
was to make OTel context available across threads even if not managed by Quarkus, so not propagated by a Vert.x context.Is there anything I misunderstood about the usage of
OpenTelemetryMpContextPropagation
, or is it a bug?The text was updated successfully, but these errors were encountered: