-
Notifications
You must be signed in to change notification settings - Fork 57
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
Make sure to call close() on Scope returned from io.opentelemetry.context.Context.makeCurrent() #924
base: series/2.x
Are you sure you want to change the base?
Make sure to call close() on Scope returned from io.opentelemetry.context.Context.makeCurrent() #924
Conversation
…text.Context.makeCurrent()
@joost-de-vries Thanks for spotting this! I'll look into it when I have time and tell you what I think about your solution. The only concern I have is that these changes are not backward-compatible. |
@grouzen thank you for your quick response. Yes, too bad that the Baggage api is affected. I couldn't think of a solution that doesn't. Maybe you have an idea? I've tested this fix on datadog. |
There's still a failing assertion |
Now I realize that it is required to change the Baggage API this way to reflect the |
@joost-de-vries Please pull the changes from |
@grouzen I wonder how to test the fix. One way would be to mock de java OpenTelemetry Context.makeCurrent. And check that |
Thinking about the changed api of Baggage: I guess I can introduce a new trait. And add deprecation warnings to the existing. def baggage(logAnnotated: Boolean = false): URLayer[ContextStorage, Baggage] =
Baggage.live(logAnnotated) I guess we could call the existing trait |
Frankly, I'm still thinking about how to avoid having scoped baggage API. I need to find some time to read the Baggage OTEL spec. I assume it is fine to have nested OTEL scopes when dealing with baggage data because, as far as I remember, according to the spec, it stores the baggage data in the trace context rather than the span, which makes perfect sense to me. |
Sounds good. I think it is a sane way of testing this kind of stuff. |
Yes, I'm chewing on that too. Come to think of it: the latter solution is simplest probably. |
I've looked into this: |
@grouzen I've implemented the latter approach. Existing code will compile unchanged. (of course that raises the question what the implementation of the existing methods should be. I've implemented it with a local |
I've added a test to verify that Context prevCtx = Context.current();
try (Scope ignored = ctx.makeCurrent()) {
assert Context.current() == ctx;
...
}
assert Context.current() == prevCtx; Most of those tests fail on master. But not all. |
Hey! Sorry for being silent, don't have time to work on this atm. |
@grouzen I understand. Are you on zio discord? I can share our experiences with zio + datadog. |
Yeah, you can find me on the zio-telemetry channel as well. It would be lovely to hear about your experience! |
@grouzen we can split this issue in two: 1. the above fix for Tracing only. That won't affect current api 2. a fix for Baggage. We can then take a bit more time in coming up with an appropriate api. It would be nice to get the fix for Tracing merged. |
Yes, lets do the first PR for Tracing. I spent lots of time researching this and now I think we need to change how we manage the context and context storage completely. |
…scope' into opentelemetry-jvm-storage-close-scope
injectLogAnnotations *> modifyBuilder(_.put(name, value)).unit | ||
|
||
// to preserve the existing behavior where the otel Scope returned from Context.makeCurrent is not closed | ||
// see io.opentelemetry.context.Context.makeCurrent | ||
private def unclosedScope[A](io: URIO[Scope, A]): UIO[A] = |
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.
@grouzen this seems to me the way to preserve existing behaviour. What do you think?
Also: perhaps good to link to an issue in that comment?
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.
It needs to be checked with some end-to-end test. One of the options could be a manual verification using an optelemetry-instrumentation example. Additionally, it would be good to check how it works with dd-trace-java because it is the reason why this issue was created in the first place.
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'm just afraid we close the current span this way, and I believe this is not what we want to do while modifying baggage data, right? That's why I think we need to do manual tests. Also, adding a unit test to prove/disprove my assumption would be great.
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.
What kind of implementation would you propose?
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.
It can't be fixed this way, as I said before. I think the whole idea of having specific ZIO2 instrumentation in opentelemetry-java-instrumentation and dd-trace-java was a mistake, hence the current implementation of ContextStorage.native was a mistake too. It must be done differently and I'm working on this right now.
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 think the better solution in your situation would be to use your fork with the fix for your case while I'm figuring out how to fix it properly to make everyone happy.
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.
Using the previous supervisor based approach?
For us it would be nice not to be dependent on the zio support in dd-trace-java. I get the sense that that's not maintained actively.
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.
The solution is quite straightforward - map between FiberRef-based and ThreadLocal-based ContextStorage implementations when needed manually. This automatically allows getting rid of finicky Supervisor-based implementations
A different way of managing context storage. Interesting! I removed the scoped methods from Baggage. |
One more thing. I should have asked about it in the very beginning. Could you please provide a repo with a minimal example of reproducing this issue? I'm curious about how your setup differs from everyone else's and why nobody has experienced this issue before. |
I've looked into the telemetry tests in zio-telemetry for one that involves 1. global otel 2. jvm context storage 3. auto instrumentation 4. zio auto intrumentation. But didn't see one. |
An |
The documentation for
io.opentelemetry.context.Context.makeCurrent()
statesEvery makeCurrent() must be followed by a Scope#close(). Breaking these rules may lead to memory leaks and incorrect scoping.
Running zio-opentelemetry with
-Dio.opentelemetry.context.enableStrictContext=true
leads to an errorThis PR uses
zio.Scope
to make sure that the otel Scope returned by Context.makeCurrent is always closed.