-
Notifications
You must be signed in to change notification settings - Fork 633
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
Use user-provided ObservationRegistries instead of constant global registry #2719
Comments
@tmarback Can you give us more details? Why do you need to enable both Spring Boot observations and Reactor Netty observations? |
My application uses Reactor Netty's HTTPClient to make requests to some external APIs it uses. I would like to have visibility into those requests within an operation (traced through observations) as they are often a big chunk of the runtime, so logically it would be nice to use the instrumentation that already exists. That said, there are other components in the application (like the database) that also need to be traced, and those are either set up by Spring Boot directly, or by the application using the Spring-provided registry (as a regular IoC dependency). |
@tmarback What do you think about specifying
This is the configuration that you need, Spring Boot will add the rest to this |
@violetagg I'm not quite sure what it is, but something about doing it that way still breaks the final trace: For reference, this is how it looks normally: If I go the other way around and compile a local version of reactor-netty where the global registry is settable and use that to inject the ObservationRegistry from Spring, it works: (note the Worth noting that the last image doesn't add |
In order to have Reactor Netty tracing working you have to have both |
can you provide some reproducible example? |
But that's what I'm saying, it did work without those handlers (after replacing the global netty registry with the Spring Boot-provided one). Adding a few And they seem to have all the tags I would expect them to have. I'll try to set up an example repo but it might take a bit. |
Ah, sorry about that, I forgot to mention that the But yes, all those measurements are there even without |
Also, sidenote that this is all somewhat beside the point; even if overriding the default |
Agree, I would like to see what we can offer you as a workaround for the time being. Worth noting here that if you want to use all optimisations and functionality provided by Reactor Netty, you need to configure your new
|
Looking at the source, they seem to be only copying the tags present in the context rather than directly specifying them. That said, I compared the span tags with By the way, I made the sample reproducible case: https://github.com/tmarback/netty-observation-repro This is what I see after running it (as per the README): |
@tmarback There is an issue in Spring Boot when you want to add custom |
@tmarback We are going to address this issue for the next release. You wrote:
and
Do you have a use case where you need more than one |
@violetagg Sorry for the delay.
Awesome, will be waiting for it 👍
Personally I don't have one; I suggested per-component registry injection as that is what I understood to be the recommended approach by the Micrometer devs when I asked on Slack (though it's always possible I misunderstood), and I didn't see any reason why it shouldn't be supported (other than a relatively small code reduction). |
I'm not challenging the need of API for changing the
|
I know, that's what I was talking about. What I meant is that the impression I got is that the "recommended" way to do things is, in addition to having a settable registry in general, to have per-component granularity, which would imply that there is some known use case for it (even if I don't personally know about it). But again, I'm not sure.
Fair enough, I didn't consider that detail. I guess arguments could be made about the practical benefits of making a facade dependency optional, but I'm sure this has already been debated by people much more knowledgeable than me :)
I alluded to this in the original issue, but I'm perfectly OK with sticking with a global-but-settable registry in the immediate term as that already fixes the main problem. Everything else can be just a long-term consideration. |
It would help if you could point us to this discussion but injecting a registry per-component does not mean injecting a new registry to each component: quite the opposite, it should be one registry that you should inject everywhere you need. I see multiple reasons why this should not be supported, the strongest one to me is the inability of tracking the current observation so context propagation (and tracing) won't work (it would also make somewhat of a chaos throughout your components). |
It was this Slack thread. You mentioned
Which, given the context (of there not being an official global registry), I interpreted to mean per-component injection. If I got that wrong, then that's my bad 🙃
Of course, I don't mean that every component would have a different registry (the whole reason I opened this issue was that reactor-netty was using a different registry than Boot, after all). The question was whether there is a use case to allowing major independent components to have different registries (say, two distinct HTTP clients that are used in entirely distinct flows but happen to be in the same JVM), versus maintaining the global (i.e. |
Sorry for not being clear, by "an external registry" I meant one registry. If you have a component where you can't inject a registry (static utility class/method) and if you need the current observation, since the thread local for it is static, if you are in the same class loader and create an instance of the registry in your static component, you will be able to get the current observation. But I would not consider this as the normal use of the Observation API since this should not really happen in user code and that registry should only be used for getting the current observation and for creating any. |
That solves that issue then, thank you for clarifying 🙂 |
@tmarback @jonatan-ivanov Thanks for the clarification! |
Currently, reactor-netty's instrumentation with Micrometer's Observation API relies on a constant global
ObservationRegistry
created within netty itself (in Metrics.java). It should instead allow client code to inject their ownObservationRegistry
instances to the components being used.Motivation
Using a fixed registry makes reactor-netty's instrumentation not useable for tracing if the user already has an external registry under use (for example, the one provided by Spring Boot Actuator), as attempting to use both registries at once leads to incorrect results (from my experience it leads to inconsistent issues with parent spans, missing spans, etc). According to the Micrometer developers, this is not a bug, as only one registry should be in use in the app lifecycle.
Desired solution
Ideally, each major component (e.g. a Client or Server instance, other independent internal components) should be able to receive an
ObservationRegistry
instance from client code to use in their metrics, for maximum configurability. Incidentally, this would bring it more in line with Reactor itself, which has moved away from global registries altogether recently, even for metrics.Considered alternatives
A limited but simpler alternative patch would be to allow client code to set the global registry used by netty (possibly by moving it behind a static getter/setter pair). This retains many of the limitations so it's not the preferred solution, but it could be a potential temporary workaround if the changes required for per-instance registries would take a significant time (so the instrumentation is at least usable by apps with only one registry in the meantime). I can provide a PR with this option if desired.
The text was updated successfully, but these errors were encountered: