From 68de0bb538483c5f76fdf78c686e273f15b4c684 Mon Sep 17 00:00:00 2001 From: Tim Quinn Date: Thu, 21 Dec 2023 08:45:06 -0600 Subject: [PATCH] 4.x Make `RegistryFactory` and its `getInstance` and `getRegistry` methods public (#8175) * Make RegistryFactory and its getInstance and getRegistry methods public as in 3.x; update the MP metrics doc to clarify Signed-off-by: Tim Quinn * Restore producer for RegistryFactory Signed-off-by: Tim Quinn --------- Signed-off-by: Tim Quinn --- .../includes/metrics/metrics-shared.adoc | 68 ++++++++++++++++--- .../microprofile/metrics/MetricProducer.java | 2 +- .../microprofile/metrics/RegistryFactory.java | 15 ++-- .../metrics/RegistryProducer.java | 5 ++ .../microprofile/metrics/ProducerTest.java | 10 +++ 5 files changed, 83 insertions(+), 17 deletions(-) diff --git a/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc b/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc index f2064105866..820966d480c 100644 --- a/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc +++ b/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc @@ -153,24 +153,70 @@ In addition to your application {metrics}, the reports contain other To register or look up {metrics} programmatically, your service code uses the link:{microprofile-metrics-javadoc-url}/org/eclipse/microprofile/metrics/MetricRegistry.html[`MetricRegistry`] instance for the scope of interest: `base`, `vendor`, `application`, or a custom scope. ifdef::mp-flavor[] -To get a `MetricRegistry` reference +Either of the following techniques gets a `MetricRegistry` reference. +Remember that injection works only if the class is a bean so CDI can inject into it. -* `@Inject` the metric registry you want, perhaps also using the link:{microprofile-metrics-javadoc-annotation-url}/RegistryScope.html[`@RegistryScope`] annotation to select the registry type, or -* Get a Helidon link:{metrics-mp-javadoc-base-url}/RegistryFactory.html[`RegistryFactory`]; either +* `@Inject MetricRegistry`, optionally using link:{microprofile-metrics-javadoc-annotation-url}/RegistryScope.html[`@RegistryScope`] to indicate the registry scope. + -- -** `@Inject` `RegistryFactory` or -** Invoke one of the static `getInstance` methods on `RegistryFactory` +[source,java] +.Injecting the default `MetricRegistry` (for the application scope) +---- +class Example { + + @Inject + private MetricRegistry applicationRegistry; +} +---- + +[source,java] +.Injecting a non-default `MetricRegistry` +---- +class Example { + + @RegistryScope("myCustomScope") + @Inject + private MetricRegistry myCustomRegistry; +} +---- -- +* Get a Helidon link:{metrics-mp-javadoc-base-url}/RegistryFactory.html[`RegistryFactory`] instance and invoke its `getRegistry` method. + -Then invoke `getRegistry` on the `RegistryFactory` instance. -endif::[] -ifdef::se-flavor[] -To get a `MetricRegistry` reference, first get a Helidon link:{metrics-javadoc-base-url}/RegistryFactory.html[`RegistryFactory`]. -Then invoke `getRegistry` on the `RegistryFactory` instance. +-- +Obtain the `RegistryFactory` using either of the following techniques: + +** `@Inject RegistryFactory`. ++ +[source,java] +.Getting the `RegistryFactory` using injection +---- +class InjectExample { + + @Inject + private RegistryFactory registryFactory; + + private MetricRegistry findRegistry(String scope) { + return registryFactory.getRegistry(scope); + } +} +---- ++ +** Invoke the static `getInstance()` method on the `RegistryFactory` class. ++ +[source,java] +.Getting the `RegistryFactory` programmatically +---- +class Example { + + private MetricRegistry findRegistry(String scope) { + return RegistryFactory.getInstance().getRegistry(scope); + } +} +---- +-- endif::[] -The `MetricRegistry` allows your code to register new metrics, look up previously-registered metrics, and remove metrics. +Once it has a reference to a `MetricRegistry` your code can use the reference to register new metrics, look up previously-registered metrics, and remove metrics. // end::metric-registry-api[] // tag::example-apps[] diff --git a/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/MetricProducer.java b/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/MetricProducer.java index 5afe7335414..895fec36b8d 100644 --- a/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/MetricProducer.java +++ b/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/MetricProducer.java @@ -206,7 +206,7 @@ static MetricLocator create(InjectionPoint ip) { final Metric metricAnno = ip.getAnnotated().getAnnotation(Metric.class); final Tag[] tags = tags(metricAnno); final String scope = metricAnno == null ? MetricRegistry.APPLICATION_SCOPE : metricAnno.scope(); - Registry registry = RegistryFactory.getInstance().getRegistry(scope); + Registry registry = RegistryFactory.getInstance().registry(scope); final MetricID metricID = new MetricID(getName(metricAnno, ip), tags); return new MetricLocator(metricAnno, registry, metricID); } diff --git a/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryFactory.java b/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryFactory.java index a260d1cedaa..6ee95053c3c 100644 --- a/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryFactory.java +++ b/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryFactory.java @@ -35,6 +35,7 @@ import org.eclipse.microprofile.metrics.Gauge; import org.eclipse.microprofile.metrics.Histogram; import org.eclipse.microprofile.metrics.Metric; +import org.eclipse.microprofile.metrics.MetricRegistry; import org.eclipse.microprofile.metrics.Timer; /** @@ -52,7 +53,7 @@ * method creates a new instance but does not record it internally. *

*/ -class RegistryFactory { +public class RegistryFactory { static final Collection> METRIC_TYPES = Set.of(Counter.class, Gauge.class, @@ -86,7 +87,7 @@ static RegistryFactory getInstance(MeterRegistry meterRegistry) { * * @return registry factory singleton */ - static RegistryFactory getInstance() { + public static RegistryFactory getInstance() { RegistryFactory result = REGISTRY_FACTORY.get(); if (result == null) { LOGGER.log(Level.WARNING, "Attempt to retrieve current " + RegistryFactory.class.getName() @@ -115,7 +116,11 @@ static void closeAll() { * @param scope scope of registry * @return Registry for the scope requested */ - Registry getRegistry(String scope) { + public MetricRegistry getRegistry(String scope) { + return registry(scope); + } + + Registry registry(String scope) { return accessMetricsSettings(() -> registries.computeIfAbsent(scope, s -> Registry.create(s, meterRegistry))); } @@ -150,7 +155,7 @@ private void registerMetricForExistingMeter(Meter delegate) { if (scope == null) { LOGGER.log(Level.WARNING, "Attempt to register an existing meter with no scope: " + delegate); } - getRegistry(scope).onMeterAdded(delegate); + registry(scope).onMeterAdded(delegate); } private void removeMetricForMeter(Meter meter) { @@ -158,7 +163,7 @@ private void removeMetricForMeter(Meter meter) { if (scope == null) { LOGGER.log(Level.WARNING, "Attempt to register an existing meter with no scope: " + meter); } - getRegistry(scope).onMeterRemoved(meter); + registry(scope).onMeterRemoved(meter); } } diff --git a/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryProducer.java b/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryProducer.java index 166a5fb6f9b..83a04dbe97c 100644 --- a/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryProducer.java +++ b/microprofile/metrics/src/main/java/io/helidon/microprofile/metrics/RegistryProducer.java @@ -71,6 +71,11 @@ public static org.eclipse.microprofile.metrics.MetricRegistry getVendorRegistry( return RegistryFactory.getInstance().getRegistry(MetricRegistry.VENDOR_SCOPE); } + @Produces + public static RegistryFactory getRegistryFactory() { + return RegistryFactory.getInstance(); + } + /** * Clears Application registry. This is required for the Metric TCKs as they * all run on the same VM and must not interfere with each other. diff --git a/microprofile/metrics/src/test/java/io/helidon/microprofile/metrics/ProducerTest.java b/microprofile/metrics/src/test/java/io/helidon/microprofile/metrics/ProducerTest.java index c5bd652cf8e..092c10e65c2 100644 --- a/microprofile/metrics/src/test/java/io/helidon/microprofile/metrics/ProducerTest.java +++ b/microprofile/metrics/src/test/java/io/helidon/microprofile/metrics/ProducerTest.java @@ -25,6 +25,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.sameInstance; import static org.hamcrest.MatcherAssert.assertThat; @@ -46,6 +47,9 @@ public class ProducerTest extends MetricsBaseTest { @Inject private MetricRegistry appRegistry; + @Inject + private RegistryFactory registryFactory; + private final MetricID counter1 = new MetricID("counter1"); private final MetricID counter2 = new MetricID("counter2"); @@ -79,4 +83,10 @@ void testRegistryProducer() { assertThat("App registry counter", appCounter.getCount(), is(appCounterIncr)); assertThat("Special registry counter", specialCounter.getCount(), is(specialCounterIncr)); } + + @Test + void testRegistryFactoryProducer() { + MetricRegistry customRegistry = registryFactory.getRegistry("myCustomScope"); + assertThat("Custom scoped MetricRegistry", customRegistry, notNullValue()); + } }