ARTEMIS-2771 support JVM GC & thread metrics

This commit is contained in:
Justin Bertram 2020-05-20 10:27:19 -05:00 committed by Clebert Suconic
parent 818ab3d41c
commit 4b7b612eb9
14 changed files with 407 additions and 35 deletions

View File

@ -600,6 +600,15 @@ public final class ActiveMQDefaultConfiguration {
// How long to wait for a reply if in the middle of a fail-over. -1 means wait forever.
private static long DEFAULT_FEDERATION_CALL_FAILOVER_TIMEOUT = -1;
// Whether or not to report JVM memory metrics
private static final boolean DEFAULT_JVM_MEMORY_METRICS = true;
// Whether or not to report JVM GC metrics
private static final boolean DEFAULT_JVM_GC_METRICS = false;
// Whether or not to report JVM thread metrics
private static final boolean DEFAULT_JVM_THREAD_METRICS = false;
/**
* If true then the ActiveMQ Artemis Server will make use of any Protocol Managers that are in available on the classpath. If false then only the core protocol will be available, unless in Embedded mode where users can inject their own Protocol Managers.
*/
@ -1630,4 +1639,25 @@ public final class ActiveMQDefaultConfiguration {
return DEFAULT_FEDERATION_CALL_FAILOVER_TIMEOUT;
}
/**
* Whether or not to report JVM memory metrics
*/
public static boolean getDefaultJvmMemoryMetrics() {
return DEFAULT_JVM_MEMORY_METRICS;
}
/**
* Whether or not to report JVM GC metrics
*/
public static boolean getDefaultJvmGcMetrics() {
return DEFAULT_JVM_GC_METRICS;
}
/**
* Whether or not to report JVM thread metrics
*/
public static boolean getDefaultJvmThreadMetrics() {
return DEFAULT_JVM_THREAD_METRICS;
}
}

View File

@ -1056,8 +1056,11 @@ public interface Configuration {
Configuration addSecuritySettingPlugin(SecuritySettingPlugin plugin);
@Deprecated
Configuration setMetricsPlugin(ActiveMQMetricsPlugin plugin);
Configuration setMetricsConfiguration(MetricsConfiguration metricsConfiguration);
/**
* @return list of {@link ConnectorServiceConfiguration}
*/
@ -1065,8 +1068,11 @@ public interface Configuration {
List<SecuritySettingPlugin> getSecuritySettingPlugins();
@Deprecated
ActiveMQMetricsPlugin getMetricsPlugin();
MetricsConfiguration getMetricsConfiguration();
/**
* The default password decoder
*/

View File

@ -0,0 +1,67 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.core.config;
import java.io.Serializable;
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.core.server.metrics.ActiveMQMetricsPlugin;
public class MetricsConfiguration implements Serializable {
private boolean jvmMemory = ActiveMQDefaultConfiguration.getDefaultJvmMemoryMetrics();
private boolean jvmGc = ActiveMQDefaultConfiguration.getDefaultJvmGcMetrics();
private boolean jvmThread = ActiveMQDefaultConfiguration.getDefaultJvmThreadMetrics();
private ActiveMQMetricsPlugin plugin;
public boolean isJvmMemory() {
return jvmMemory;
}
public MetricsConfiguration setJvmMemory(boolean jvmMemory) {
this.jvmMemory = jvmMemory;
return this;
}
public boolean isJvmGc() {
return jvmGc;
}
public MetricsConfiguration setJvmGc(boolean jvmGc) {
this.jvmGc = jvmGc;
return this;
}
public boolean isJvmThread() {
return jvmThread;
}
public MetricsConfiguration setJvmThread(boolean jvmThread) {
this.jvmThread = jvmThread;
return this;
}
public ActiveMQMetricsPlugin getPlugin() {
return plugin;
}
public MetricsConfiguration setPlugin(ActiveMQMetricsPlugin plugin) {
this.plugin = plugin;
return this;
}
}

View File

@ -56,6 +56,7 @@ import org.apache.activemq.artemis.core.config.CoreQueueConfiguration;
import org.apache.activemq.artemis.core.config.DivertConfiguration;
import org.apache.activemq.artemis.core.config.FederationConfiguration;
import org.apache.activemq.artemis.core.config.HAPolicyConfiguration;
import org.apache.activemq.artemis.core.config.MetricsConfiguration;
import org.apache.activemq.artemis.core.config.StoreConfiguration;
import org.apache.activemq.artemis.core.config.WildcardConfiguration;
import org.apache.activemq.artemis.core.config.ha.ReplicaPolicyConfiguration;
@ -269,7 +270,7 @@ public class ConfigurationImpl implements Configuration, Serializable {
private List<SecuritySettingPlugin> securitySettingPlugins = new ArrayList<>();
private ActiveMQMetricsPlugin metricsPlugin = null;
private MetricsConfiguration metricsConfiguration = null;
private final List<ActiveMQServerBasePlugin> brokerPlugins = new CopyOnWriteArrayList<>();
private final List<ActiveMQServerConnectionPlugin> brokerConnectionPlugins = new CopyOnWriteArrayList<>();
@ -1487,9 +1488,18 @@ public class ConfigurationImpl implements Configuration, Serializable {
return this.securitySettingPlugins;
}
@Deprecated
@Override
public ActiveMQMetricsPlugin getMetricsPlugin() {
return this.metricsPlugin;
if (metricsConfiguration != null) {
return metricsConfiguration.getPlugin();
}
return null;
}
@Override
public MetricsConfiguration getMetricsConfiguration() {
return this.metricsConfiguration;
}
@Override
@ -1712,9 +1722,19 @@ public class ConfigurationImpl implements Configuration, Serializable {
return this;
}
@Deprecated
@Override
public ConfigurationImpl setMetricsPlugin(final ActiveMQMetricsPlugin plugin) {
this.metricsPlugin = plugin;
if (metricsConfiguration == null) {
metricsConfiguration = new MetricsConfiguration();
}
metricsConfiguration.setPlugin(plugin);
return this;
}
@Override
public ConfigurationImpl setMetricsConfiguration(final MetricsConfiguration metricsConfiguration) {
this.metricsConfiguration = metricsConfiguration;
return this;
}

View File

@ -53,6 +53,7 @@ import org.apache.activemq.artemis.core.config.ConnectorServiceConfiguration;
import org.apache.activemq.artemis.core.config.CoreAddressConfiguration;
import org.apache.activemq.artemis.core.config.DivertConfiguration;
import org.apache.activemq.artemis.core.config.FederationConfiguration;
import org.apache.activemq.artemis.core.config.MetricsConfiguration;
import org.apache.activemq.artemis.core.config.ScaleDownConfiguration;
import org.apache.activemq.artemis.core.config.TransformerConfiguration;
import org.apache.activemq.artemis.core.config.WildcardConfiguration;
@ -710,11 +711,15 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
parseBrokerPlugins(e, config);
{ // for backwards compatibility
NodeList metricsPlugin = e.getElementsByTagName("metrics-plugin");
if (metricsPlugin.getLength() != 0) {
parseMetricsPlugin(metricsPlugin.item(0), config);
}
}
parseMetrics(e, config);
NodeList connectorServiceConfigs = e.getElementsByTagName("connector-service");
@ -806,6 +811,34 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
return properties;
}
/**
* @param e
* @param config
*/
private void parseMetrics(final Element e, final Configuration config) {
NodeList elements = e.getElementsByTagName("metrics");
MetricsConfiguration metricsConfiguration = new MetricsConfiguration();
if (elements.getLength() != 0) {
Element node = (Element) elements.item(0);
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
Node child = children.item(j);
if (child.getNodeName().equals("jvm-gc")) {
metricsConfiguration.setJvmGc(XMLUtil.parseBoolean(child));
} else if (child.getNodeName().equals("jvm-memory")) {
metricsConfiguration.setJvmMemory(XMLUtil.parseBoolean(child));
} else if (child.getNodeName().equals("jvm-threads")) {
metricsConfiguration.setJvmThread(XMLUtil.parseBoolean(child));
} else if (child.getNodeName().equals("plugin")) {
metricsConfiguration.setPlugin(parseMetricsPlugin(child, config));
}
}
}
config.setMetricsConfiguration(metricsConfiguration);
}
private ActiveMQMetricsPlugin parseMetricsPlugin(final Node item, final Configuration config) {
final String clazz = item.getAttributes().getNamedItem("class-name").getNodeValue();
@ -819,6 +852,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
});
ActiveMQServerLogger.LOGGER.initializingMetricsPlugin(clazz, properties.toString());
// leaving this as-is for backwards compatibility
config.setMetricsPlugin(metricsPlugin.init(properties));
return metricsPlugin;

View File

@ -2836,8 +2836,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
* on Micrometer as "optional" in the Maven pom.xml. This is particularly beneficial because optional dependencies
* are not required to be included in the OSGi bundle and the Micrometer jars apparently don't support OSGi.
*/
if (configuration.getMetricsPlugin() != null) {
metricsManager = new MetricsManager(configuration.getName(), configuration.getMetricsPlugin(), addressSettingsRepository);
if (configuration.getMetricsConfiguration() != null && configuration.getMetricsConfiguration().getPlugin() != null) {
metricsManager = new MetricsManager(configuration.getName(), configuration.getMetricsConfiguration(), addressSettingsRepository);
}
registerMeters();

View File

@ -28,8 +28,11 @@ import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
import org.apache.activemq.artemis.api.core.management.ResourceNames;
import org.apache.activemq.artemis.core.config.MetricsConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
@ -45,13 +48,21 @@ public class MetricsManager {
private final HierarchicalRepository<AddressSettings> addressSettingsRepository;
public MetricsManager(String brokerName,
ActiveMQMetricsPlugin metricsPlugin,
MetricsConfiguration metricsConfiguration,
HierarchicalRepository<AddressSettings> addressSettingsRepository) {
this.brokerName = brokerName;
meterRegistry = metricsPlugin.getRegistry();
meterRegistry = metricsConfiguration.getPlugin().getRegistry();
Metrics.globalRegistry.add(meterRegistry);
new JvmMemoryMetrics().bindTo(meterRegistry);
this.addressSettingsRepository = addressSettingsRepository;
if (metricsConfiguration.isJvmMemory()) {
new JvmMemoryMetrics().bindTo(meterRegistry);
}
if (metricsConfiguration.isJvmGc()) {
new JvmGcMetrics().bindTo(meterRegistry);
}
if (metricsConfiguration.isJvmThread()) {
new JvmThreadMetrics().bindTo(meterRegistry);
}
}
public MeterRegistry getMeterRegistry() {

View File

@ -1048,6 +1048,65 @@
</xsd:element>
<xsd:element name="metrics-plugin" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
DEPRECATED: use metrics instead. A metrics plugin
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="property" maxOccurs="unbounded" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
properties to configure a plugin
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="class-name" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
the name of the metrics plugin class to instantiate
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attributeGroup ref="xml:specialAttrs"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="metrics" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
metrics configuration
</xsd:documentation>
</xsd:annotation>
<xsd:all>
<xsd:element name="jvm-memory" type="xsd:boolean" default="true" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
whether or not to report JVM memory metrics
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="jvm-threads" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
whether or not to report JVM thread metrics
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="jvm-gc" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
whether or not to report JVM GC metrics
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="plugin" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
@ -1073,6 +1132,10 @@
<xsd:attributeGroup ref="xml:specialAttrs"/>
</xsd:complexType>
</xsd:element>
</xsd:all>
<xsd:attributeGroup ref="xml:specialAttrs"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="address-settings" maxOccurs="1" minOccurs="0">
<xsd:annotation>

View File

@ -43,6 +43,7 @@ import org.apache.activemq.artemis.core.config.CoreAddressConfiguration;
import org.apache.activemq.artemis.core.config.DivertConfiguration;
import org.apache.activemq.artemis.core.config.FileDeploymentManager;
import org.apache.activemq.artemis.core.config.HAPolicyConfiguration;
import org.apache.activemq.artemis.core.config.MetricsConfiguration;
import org.apache.activemq.artemis.core.config.ha.LiveOnlyPolicyConfiguration;
import org.apache.activemq.artemis.core.journal.impl.JournalImpl;
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
@ -465,12 +466,23 @@ public class FileConfigurationTest extends ConfigurationImplTest {
assertEquals(false, conf.isJournalDatasync());
// keep test for backwards compatibility
ActiveMQMetricsPlugin metricsPlugin = conf.getMetricsPlugin();
assertTrue(metricsPlugin instanceof SimpleMetricsPlugin);
Map<String, String> options = ((SimpleMetricsPlugin) metricsPlugin).getOptions();
assertEquals("x", options.get("foo"));
assertEquals("y", options.get("bar"));
assertEquals("z", options.get("baz"));
MetricsConfiguration metricsConfiguration = conf.getMetricsConfiguration();
assertTrue(metricsConfiguration.getPlugin() instanceof SimpleMetricsPlugin);
options = ((SimpleMetricsPlugin) metricsPlugin).getOptions();
assertEquals("x", options.get("foo"));
assertEquals("y", options.get("bar"));
assertEquals("z", options.get("baz"));
assertFalse(metricsConfiguration.isJvmMemory());
assertTrue(metricsConfiguration.isJvmGc());
assertTrue(metricsConfiguration.isJvmThread());
}
private void verifyAddresses() {

View File

@ -310,11 +310,16 @@
</federation>
</federations>
<metrics-plugin class-name="org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin">
<metrics>
<jvm-memory>false</jvm-memory>
<jvm-gc>true</jvm-gc>
<jvm-threads>true</jvm-threads>
<plugin class-name="org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin">
<property key="foo" value="x"/>
<property key="bar" value="y"/>
<property key="baz" value="z"/>
</metrics-plugin>
</plugin>
</metrics>
<ha-policy>
<!--only one of the following-->

View File

@ -194,11 +194,16 @@
</bridge>
</bridges>
<metrics-plugin class-name="org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin">
<metrics>
<jvm-memory>false</jvm-memory>
<jvm-gc>true</jvm-gc>
<jvm-threads>true</jvm-threads>
<plugin class-name="org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin">
<property key="foo" value="x"/>
<property key="bar" value="y"/>
<property key="baz" value="z"/>
</metrics-plugin>
</plugin>
</metrics>
<ha-policy>
<!--only one of the following-->

View File

@ -82,28 +82,37 @@ message count). However, these metrics can be deduced by aggregating the
lower level metrics (e.g. aggregate the message.count metrics from all queues
to get the total).
JVM memory metrics are exported as well.
JVM memory metrics are also exported by default and GC and thread metrics can
be configured
## Configuration
All metrics are enabled by default. If you want to disable metrics for a
particular address or set of addresses you can do so by setting the
`enable-metrics` `address-setting` to `false`.
Metrics for all addresses and queues are enabled by default. If you want to
disable metrics for a particular address or set of addresses you can do so by
setting the `enable-metrics` `address-setting` to `false`.
To configure the plugin itself use the `metrics-plugin` element in `broker.xml`
and specify the `class-name` attribute, e.g.:
In `broker.xml` use the `metrics` element to configure which JVM metrics are
reported and to configure the plugin itself. Here's a configuration with all
JVM metrics:
```xml
<metrics-plugin class-name="org.apache.activemq.artemis.core.server.metrics.plugins.LoggingMetricsPlugin" />
<metrics>
<jvm-memory>true</jvm-memory> <!-- defaults to true -->
<jvm-gc>true</jvm-gc> <!-- defaults to false -->
<jvm-threads>true</jvm-threads> <!-- defaults to false -->
<plugin class-name="org.apache.activemq.artemis.core.server.metrics.plugins.LoggingMetricsPlugin"/>
</metrics>
```
The plugin can also be configured with key/value properties in order to
customize the implementation as necessary, e.g.:
```xml
<metrics-plugin class-name="org.example.MyMetricsPlugin">
<metrics>
<plugin class-name="org.example.MyMetricsPlugin">
<property key="host" value="example.org" />
<property key="port" value="5162" />
<property key="foo" value="10" />
</metrics-plugin>
</plugin>
</metrics>
```

View File

@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* <br>
* http://www.apache.org/licenses/LICENSE-2.0
* <br>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.tests.integration.plugin;
import io.micrometer.core.instrument.Meter;
import org.apache.activemq.artemis.core.config.MetricsConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Before;
import org.junit.Test;
public class JvmMetricsTest extends ActiveMQTestBase {
@Override
@Before
public void setUp() throws Exception {
super.setUp();
}
@Test
public void testJvmMemoryMetricsPositive() throws Exception {
internalTestMetrics(true, true, false, false, "jvm.memory");
}
@Test
public void testJvmMemoryMetricsNegative() throws Exception {
internalTestMetrics(false, false, false, false, "jvm.memory");
}
@Test
public void testJvmGcMetricsPositive() throws Exception {
internalTestMetrics(true, false, true, false, "jvm.gc");
}
@Test
public void testJvmGcMetricsNegative() throws Exception {
internalTestMetrics(false, false, false, false, "jvm.gc");
}
@Test
public void testJvmThreadMetricsPositive() throws Exception {
internalTestMetrics(true, false, false, true, "jvm.thread");
}
@Test
public void testJvmThreadMetricsNegative() throws Exception {
internalTestMetrics(false, false, false, false, "jvm.thread");
}
private void internalTestMetrics(boolean found, boolean memory, boolean gc, boolean thread, String match) throws Exception {
ActiveMQServer server = createServer(false, createDefaultInVMConfig()
.setMetricsConfiguration(new MetricsConfiguration()
.setPlugin(new SimpleMetricsPlugin().init(null))
.setJvmMemory(memory)
.setJvmGc(gc)
.setJvmThread(thread)));
server.start();
boolean result = false;
for (Meter.Id meterId : MetricsPluginTest.getMetrics(server).keySet()) {
if (meterId.getName().startsWith(match)) {
result = true;
break;
}
}
assertEquals(found, result);
}
}

View File

@ -17,6 +17,8 @@
package org.apache.activemq.artemis.tests.integration.plugin;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -36,6 +38,7 @@ import org.apache.activemq.artemis.api.core.client.ClientProducer;
import org.apache.activemq.artemis.api.core.client.ClientSession;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.core.config.MetricsConfiguration;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.Queue;
import org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin;
@ -44,11 +47,25 @@ import org.apache.activemq.artemis.tests.util.Wait;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.hamcrest.Matchers.containsInAnyOrder;
@RunWith(Parameterized.class)
public class MetricsPluginTest extends ActiveMQTestBase {
private boolean legacyConfig;
@Parameterized.Parameters(name = "legacyConfig={0}")
public static Collection<Object[]> getParams() {
return Arrays.asList(new Object[][]{{true}, {false}});
}
public MetricsPluginTest(boolean legacyConfig) {
this.legacyConfig = legacyConfig;
}
protected ActiveMQServer server;
protected ClientSession session;
protected ClientSessionFactory sf;
@ -59,7 +76,11 @@ public class MetricsPluginTest extends ActiveMQTestBase {
public void setUp() throws Exception {
super.setUp();
server = createServer(false, createDefaultInVMConfig());
if (legacyConfig) {
server.getConfiguration().setMetricsPlugin(new SimpleMetricsPlugin().init(null));
} else {
server.getConfiguration().setMetricsConfiguration(new MetricsConfiguration().setPlugin(new SimpleMetricsPlugin().init(null)));
}
server.start();
locator = createInVMNonHALocator();
sf = createSessionFactory(locator);
@ -245,6 +266,10 @@ public class MetricsPluginTest extends ActiveMQTestBase {
}
public Map<Meter.Id, Double> getMetrics() {
return getMetrics(server);
}
public static Map<Meter.Id, Double> getMetrics(ActiveMQServer server) {
Map<Meter.Id, Double> metrics = new HashMap<>();
List<Meter> meters = server.getMetricsManager().getMeterRegistry().getMeters();
assertTrue(meters.size() > 0);