-
Notifications
You must be signed in to change notification settings - Fork 992
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
Better support for working with Observation from Kotlin #4754
Comments
I think this issue should be in Micrometer instead where the Observation API is and some other bits of Kotlin support: https://github.com/micrometer-metrics/micrometer/blob/main/micrometer-core/src/main/kotlin/io/micrometer/core/instrument/kotlin/ |
Thanks for opening the issue. Is this something you would be willing to make a pull request for, @ilya40umov? I don't regularly use Kotlin so it will probably be easier for folks who do to suggest the changes. |
@shakuzen I'll definitely try looking into this (not sure sure if I'll have time for this next week though). |
So far I was able to improve a bit upon the second extension function I posted originally, so now it looks as follows:
This is basically making sure that it preserves most of the original coroutine context, similar to how TransactionalOperatorExtensions.kt#L48 is doing it. Then it can be used from Kotlin code like this:
I am a bit conflicted about this being an extension function of Or this whole method could be added as an extension of already existing
This is because the method also needs a reference to |
The following implementation should do the trick without tapping into
As an optimization, it may be possible to avoid adding |
As for the "normal", i.e. non-suspending API, we could extend
I'm only including two methods, i.e. |
@shakuzen I will think about it for a few more days and then will raise a PR with the changes I mentioned above and hopefully some tests. |
Just for reference, here are a couple of examples of how to both versions of the APIs (suspending and non-suspending) look in Kotlin code: |
I've opened a PR where I ended up adding 2 extension functions to |
I've added a second PR which is adding the same 2 extensions on |
@ilya40umov is it possible to map the CoroutineContext to an |
@ArvindEnvoy I've created a separate issue to track the topic of |
@jonatan-ivanov @shakuzen I totally forgot about this issue / associated PRs, as I ended up implementing a solution based on #4823 in a shared library at my current job. Ideally, it would be still nice to decide which of the two PRs you guys would rather keep: #4772 or #4823 . |
Hey, I've totally missed the PRs, sorry. What's the difference between the two? |
So, one is adding the extension functions to I initially created this PR #4772 with |
Hey, I've totally missed the PRs, sorry. What's the difference between the two? |
@marcingrzejszczak looks like your question from before (that I answered above) got duplicated somehow. Were you planning to write something else? |
First, let just say that this PR helped me a lot, even in its current state. The But i got a question about this bit :
I don't really understand why the need to open and close a scope and retrieving the |
Yeah, it looks strange but works 💯 And 👍 @ilya40umov |
@PierrickPuimeanChieze TL;DR this is needed because when coroutines suspend / resume they may end up continuing on a different thread. The concept of "current" observation is by default implement via a ThreadLocal variable, which is not handled correctly when you start using coroutines. This is why this "asContextElement" is needed, which is adding KotlinObservationContextElement to the context, which in turn implements I can't possibly cover this topic in depth in a Github comment, but you may find this repo I created a while ago useful. It covers actually 3 different concurrency models and different libraries for tracing (i.e. Brave vs OpenTelemetry vs using Spring & Micrometer). |
Thanks for your answer. I already knew about the way coroutine worked (took me a lot of brain juice a while ago to understand why my transaction got lost in oblivion when used with coroutines) but my question was more about the use of openScope. I found the definitions and explanation of the Scope quite succinct in the micrometer documentation,honestly. I will check your repo. Maybe it will help my understanding. And again, thanks a lot. |
Right now (as far as I can tell), there is no extra support for using
Observation
API from Kotlin code.For example, to create a new
Observation
in normal, blocking code, one first needs to invent a convenience function like this:And when it comes to wrapping a suspending block of code within
Observation
it gets even more complicated:At the same time, when working with Otel APIs directly, there is an option to construct a span/context and put it into scope via Otel's ContextExtensions.kt
The text was updated successfully, but these errors were encountered: