Skip to content

Commit

Permalink
4.x Make RegistryFactory and its getInstance and getRegistry me…
Browse files Browse the repository at this point in the history
…thods public (helidon-io#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 <[email protected]>

* Restore producer for RegistryFactory

Signed-off-by: Tim Quinn <[email protected]>

---------

Signed-off-by: Tim Quinn <[email protected]>
  • Loading branch information
tjquinno authored Dec 21, 2023
1 parent b2a7dcf commit 68de0bb
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 17 deletions.
68 changes: 57 additions & 11 deletions docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -52,7 +53,7 @@
* method creates a new instance but does not record it internally.
* </p>
*/
class RegistryFactory {
public class RegistryFactory {

static final Collection<Class<? extends Metric>> METRIC_TYPES = Set.of(Counter.class,
Gauge.class,
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)));
}
Expand Down Expand Up @@ -150,15 +155,15 @@ 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) {
String scope = meter.scope().orElse(null);
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);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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");

Expand Down Expand Up @@ -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());
}
}

0 comments on commit 68de0bb

Please sign in to comment.