Skip to content

Commit

Permalink
Remove clear-out of registries from extension; do it in TCK-only shut…
Browse files Browse the repository at this point in the history
…down observer; update doc (helidon-io#8292)

Signed-off-by: Tim Quinn <[email protected]>
  • Loading branch information
tjquinno authored Jan 26, 2024
1 parent 0be9a97 commit b02a537
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 6 deletions.
34 changes: 34 additions & 0 deletions docs/src/main/asciidoc/mp/metrics/metrics.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ Helidon automatically looks up the metric referenced from any injection site and
include::{rootdir}/includes/metrics/metrics-shared.adoc[tag=metric-registry-api]
=== Working with Metrics in CDI Extensions
You can work with metrics inside your own CDI extensions, but be careful to do so at the correct point in the CDI lifecycle.
Configuration can influence how the metrics system behaves, as the <<Configuration, configuration>> section below explains.
Your code should work with metrics only after the Helidon metrics system has initialized itself using configuration.
One way to accomplish this is to deal with metrics in a method that observes the Helidon `RuntimeStart` CDI event, which the xref:extension_example[extension example below] illustrates.
// Here's Configuration.
include::{rootdir}/includes/metrics/metrics-config.adoc[tag=config-intro]
Expand Down Expand Up @@ -574,6 +580,34 @@ curl -H "Accept: application/json" 'http://localhost:8080/metrics?scope=applica
----
<1> The application has been running for 23 seconds.
[[extension_example]]
==== Working with Metrics in CDI Extensions
You can work with metrics from your own CDI extension by observing the `RuntimeStart` event.
[source,java]
.CDI Extension that works correctly with metrics
----
import io.helidon.microprofile.cdi.RuntimeStart;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.Extension;
import org.eclipse.microprofile.metrics.Counter;
import org.eclipse.microprofile.metrics.MetricRegistry;
public class MyExtension implements Extension {
void startup(@Observes @RuntimeStart Object event, // <1>
MetricRegistry metricRegistry) { // <2>
metricRegistry.counter("myCounter"); // <3>
}
}
----
<1> Declares that your observer method responds to the `RuntimeStart` event. By this time, Helidon has initialized the metrics system.
<2> Injects a `MetricRegistry` (the application registry by default).
<3> Uses the injected registry to register a metric (a counter in this case).
[NOTE]
====
Helidon does not prevent you from working with metrics earlier than the `RuntimeStart` event, but, if you do so, then Helidon might ignore certain configuration settings that would otherwise control how metrics behaves.
Instead, consider writing your extension to use earlier lifecycle events (such as `ProcessAnnotatedType`) to gather and store information about metrics that you want to register.
Then your extension's `RuntimeStart` observer method would use that stored information to register the metrics you need.
====
// Config examples
include::{rootdir}/includes/metrics/metrics-config.adoc[tag=config-examples]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023 Oracle and/or its affiliates.
* Copyright (c) 2018, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -320,9 +320,6 @@ public void registerService(@Observes @Priority(LIBRARY_BEFORE + 10) @Initialize
// this needs to be done early on, so the registry is configured before accessed
MetricsObserver observer = configure();

// Initialize our implementation
RegistryProducer.clearApplicationRegistry();

registerMetricsForAnnotatedSites();
registerAnnotatedGauges(bm);
registerRestRequestMetrics();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023 Oracle and/or its affiliates.
* Copyright (c) 2018, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@

import java.lang.System.Logger.Level;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -120,6 +121,15 @@ public MetricRegistry getRegistry(String scope) {
return registry(scope);
}

/**
* Report the scopes of all existing registries.
*
* @return set of scope names
*/
public Set<String> scopes() {
return Collections.unmodifiableSet(registries.keySet());
}

Registry registry(String scope) {
return accessMetricsSettings(() -> registries.computeIfAbsent(scope, s ->
Registry.create(s, meterRegistry)));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023 Oracle and/or its affiliates.
* Copyright (c) 2020, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,16 +15,34 @@
*/
package io.helidon.microprofile.metrics.tck;

import java.util.Set;

import io.helidon.microprofile.metrics.RegistryFactory;
import io.helidon.microprofile.server.CatchAllExceptionMapper;

import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Initialized;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
import jakarta.enterprise.inject.spi.BeforeShutdown;
import jakarta.enterprise.inject.spi.Extension;
import org.eclipse.microprofile.metrics.MetricRegistry;

public class MetricsTckCdiExtension implements Extension {

void before(@Observes BeforeBeanDiscovery discovery) {
discovery.addAnnotatedType(ArrayParamConverterProvider.class, ArrayParamConverterProvider.class.getSimpleName());
discovery.addAnnotatedType(CatchAllExceptionMapper.class, CatchAllExceptionMapper.class.getSimpleName());
}

void clear(@Observes BeforeShutdown shutdown) {
// Erase the metric registries for all scopes so they are clear at the start of the next TCK test.

RegistryFactory.getInstance().scopes().stream()
.map(RegistryFactory.getInstance()::getRegistry)
.forEach(metricRegistry ->
metricRegistry.getNames().forEach(metricRegistry::remove)
);
}
}

0 comments on commit b02a537

Please sign in to comment.