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

4.x Make RegistryFactory and its getInstance and getRegistry methods public #8175

Merged
merged 2 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
}
}