Skip to content
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

[DRAFT] Allow different Micrometer backends to be configured #509

Merged
merged 10 commits into from
Sep 15, 2022

Conversation

jgallimore
Copy link

Issue #508 This is a draft PR to demonstrate a potential way to configure and use the other Micrometer backends that are available.

@jgallimore jgallimore changed the title Allow different Micrometer backends to be configured [DRAFT] Allow different Micrometer backends to be configured Jun 23, 2022
@jgallimore jgallimore added enhancement New feature or request micrometer labels Jun 23, 2022
@jgallimore
Copy link
Author

Looks like I have some tests to fix with this at the very least, but I'm interested in what people think about the approach.

@donbourne
Copy link

This looks like a pretty cool way to automatically register and configure micrometer backends. I think conceptually you're saying that when the specified list of classes in the RequiresClass annotation are present on the classpath at runtime then the corresponding Producer should be active. How does RequiresClass get used (apologies if that's obvious and I'm missing it!)?

@jgallimore
Copy link
Author

That's correct - the corresponding Producer is only available to CDI if the classes referenced with the @RequiredClass annotation are available. The @RequiresClass annotation isn't actually read anywhere - just having a reference on the producer to a specific class is enough to stop CDI using the producer if those classes aren't available, as there will be a NoClassDefFoundError when trying to load the class for the producer.

Spring Boot uses a similar mechanism to load the various Micrometer backends. I quite like that this should enable the specific backend config to be done using MicroProfile config.

It looks like the unit tests don't use CDI at present, hence why there are some failures - I'll see if I can sort that out.

I'm also thinking to add an "enabled" option to each one, and default to disabled for all of them, except Prometheus. That way, vendors could just include all the micrometer backend jars (if they wanted to), allowing consumers to simply enable the ones they wish to use.

@jgallimore
Copy link
Author

@donbourne In amongst my excitement, I forgot to merge this code: https://github.com/smallrye/smallrye-metrics/pull/509/files#diff-c58a21a7cc71c5ba90e694d6a23a5b459dd2812994f408acae420edb366bb697R114-R122 from another branch I had in progress where I was playing with this. This uses the @RequiresClass annotation to determine which producers to add during the BeforeBeanDiscovery phase. Sorry for any confusion. I'm adding some tests using Weld and Arquillian to ensure that this logic works correctly.

@donbourne
Copy link

donbourne commented Jun 24, 2022

just having a reference on the producer to a specific class is enough to stop CDI using the producer if those classes aren't available, as there will be a NoClassDefFoundError when trying to load the class for the producer.

omg, that is nefarious and awesome.

I'm also thinking to add an "enabled" option to each one, and default to disabled for all of them, except Prometheus. That way, vendors could just include all the micrometer backend jars (if they wanted to), allowing consumers to simply enable the ones they wish to use.

I like that idea.

@jgallimore jgallimore force-pushed the backend-config branch 2 times, most recently from 5618fc8 to 8622394 Compare June 27, 2022 15:07
for (Bean<?> bean : beans) {
final Object reference = bm.getReference(bean, MeterRegistry.class, bm.createCreationalContext(bean));
if (MeterRegistry.class.isInstance(reference)) {
meterRegistries.add(MeterRegistry.class.cast(reference));
Copy link
Contributor

@Channyboy Channyboy Jun 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to keep the MPPrometheusMeterRegistry as is and just add the "new" registries to the Global Registry directly? I suppose that means this doesn't even have to be in MetricRegistries .

Seems like all the back-end registries are being included to the BASE, APPLICATION, VENDOR MPCompositeMeterRegistry and those 3 composite registries will then be added to the global meter registry anyways. Specifically, wouldn't this mean that there is a single Prometheus Meter Registry (From MicrometerBackEnd) that will have all app, base, vendor and future custom scope metrics. This would be difficult to filter out with the existing scrape calls that the Prometheus client provides for the finer granularity calls /metric?scope=___ requests.

The CounterAdapter, GaugeAdapter, etc are already registering with the Global Meter Registry directly. And since we have created and have control of the MPPrometheusRegistrys with the MeterFilters requiring the specific ThreadLocal we can register to the right scope. However, it will still register to anything else in the global registry (that isn't in our control, i.e. the other Micrometer Back ends that have no MeterFilters requiring a boolean thread local ).

Also, as part of the custom scope change, I was intending to change this to which is a little more dynamic than from before: https://github.com/Channyboy/smallrye-metrics/blob/micrometer-customScopes/implementation/src/main/java/io/smallrye/metrics/MetricRegistries.java#L111

I'm clearly biased 😂 , but adding the extra/new registries to global registry should be the most straightforward way if every "new" registration is going to the global registry. We have our own little kingdom of MPPrometheusMeterRegistrys that we can micromanage with the ThreadLocal Meter Filters to make fine granularity exporting easier and to keep the 1-to-1 Metric Registry -> Prometheus Meter Registry simple. Especially if we need to add custom scopes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Channyboy Thanks for the review! That sounds reasonable, let me take a swing at adding these to the global registry.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made the change - however - what I now see is that the application metrics from the various annotated methods do not show up in my other configured backend systems, whereas they did when using the MPCompositeRegistry previously. Having those metrics show up in Elastic / Statsd / whatever is definitely what I was shooting for. Any thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jgallimore Sorry for the delay, these should help #511

@jgallimore jgallimore force-pushed the backend-config branch 3 times, most recently from 86ce67e to 67d0984 Compare July 12, 2022 15:35
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.ProcessManagedBean;
import javax.enterprise.inject.spi.WithAnnotations;
import javax.enterprise.inject.spi.*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we keep it explicit and not use a wildcard?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - I've pushed a change for this.

import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we keep it explicit and not use a wildcard?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - I've pushed a change for this.

@Channyboy Channyboy mentioned this pull request Sep 14, 2022
@jgallimore
Copy link
Author

@Channyboy I've merged in the latest changes from the micrometer branch (javax->jakarta change) and fixed up the imports. Hopefully this is good to go.

@Channyboy
Copy link
Contributor

Not able to test other backends yet, but it doesn't blow up for me ;)

@jgallimore jgallimore merged commit 828da06 into smallrye:micrometer Sep 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request micrometer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants