From 3bd0d8bf38b188f4dca414ba5316aabf342109d5 Mon Sep 17 00:00:00 2001 From: Justin Bertram Date: Tue, 12 May 2020 14:36:36 -0500 Subject: [PATCH] ARTEMIS-2758 support disabling metrics per address --- .../impl/FileConfigurationParser.java | 4 ++ .../core/server/impl/ActiveMQServerImpl.java | 2 +- .../core/server/metrics/MetricsManager.java | 13 +++- .../core/settings/impl/AddressSettings.java | 35 ++++++++++- .../schema/artemis-configuration.xsd | 8 +++ .../config/impl/FileConfigurationTest.java | 2 + .../ConfigurationTest-full-config.xml | 1 + ...nTest-xinclude-config-address-settings.xml | 1 + docs/user-manual/en/address-model.md | 5 ++ docs/user-manual/en/metrics.md | 12 ++-- .../integration/plugin/MetricsPluginTest.java | 59 ++++++++++++------- 11 files changed, 113 insertions(+), 29 deletions(-) diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java index 627975bc6d..1f93ddd944 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java @@ -291,6 +291,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil { private static final String RETROACTIVE_MESSAGE_COUNT = "retroactive-message-count"; + private static final String ENABLE_METRICS = "enable-metrics"; + // Attributes ---------------------------------------------------- @@ -1215,6 +1217,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil { addressSettings.setExpiryQueuePrefix(new SimpleString(getTrimmedTextContent(child))); } else if (EXPIRY_QUEUE_SUFFIX_NODE_NAME.equalsIgnoreCase(name)) { addressSettings.setExpiryQueueSuffix(new SimpleString(getTrimmedTextContent(child))); + } else if (ENABLE_METRICS.equalsIgnoreCase(name)) { + addressSettings.setEnableMetrics(XMLUtil.parseBoolean(child)); } } return setting; diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java index 3a5c68b4c7..2fcd294386 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java @@ -2837,7 +2837,7 @@ public class ActiveMQServerImpl implements ActiveMQServer { * 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()); + metricsManager = new MetricsManager(configuration.getName(), configuration.getMetricsPlugin(), addressSettingsRepository); } registerMeters(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/MetricsManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/MetricsManager.java index b31be729bc..5ce477d190 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/MetricsManager.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/metrics/MetricsManager.java @@ -31,6 +31,8 @@ import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import org.apache.activemq.artemis.api.core.management.ResourceNames; 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; public class MetricsManager { @@ -40,11 +42,16 @@ public class MetricsManager { private final Map> meters = new ConcurrentHashMap<>(); - public MetricsManager(String brokerName, ActiveMQMetricsPlugin metricsPlugin) { + private final HierarchicalRepository addressSettingsRepository; + + public MetricsManager(String brokerName, + ActiveMQMetricsPlugin metricsPlugin, + HierarchicalRepository addressSettingsRepository) { this.brokerName = brokerName; meterRegistry = metricsPlugin.getRegistry(); Metrics.globalRegistry.add(meterRegistry); new JvmMemoryMetrics().bindTo(meterRegistry); + this.addressSettingsRepository = addressSettingsRepository; } public MeterRegistry getMeterRegistry() { @@ -59,7 +66,7 @@ public class MetricsManager { public void registerQueueGauge(String address, String queue, Consumer builder) { final MeterRegistry meterRegistry = this.meterRegistry; - if (meterRegistry == null) { + if (meterRegistry == null || !addressSettingsRepository.getMatch(address).isEnableMetrics()) { return; } final List newMeters = new ArrayList<>(); @@ -85,7 +92,7 @@ public class MetricsManager { public void registerAddressGauge(String address, Consumer builder) { final MeterRegistry meterRegistry = this.meterRegistry; - if (meterRegistry == null) { + if (meterRegistry == null || !addressSettingsRepository.getMatch(address).isEnableMetrics()) { return; } final List newMeters = new ArrayList<>(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java index fb569099ba..4c9205c686 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java @@ -125,6 +125,8 @@ public class AddressSettings implements Mergeable, Serializable public static final SimpleString DEFAULT_DEAD_LETTER_QUEUE_SUFFIX = SimpleString.toSimpleString(""); + public static final boolean DEFAULT_ENABLE_METRICS = true; + private AddressFullMessagePolicy addressFullMessagePolicy = null; private Long maxSizeBytes = null; @@ -247,6 +249,8 @@ public class AddressSettings implements Mergeable, Serializable private SimpleString expiryQueueSuffix = null; + private Boolean enableMetrics = null; + //from amq5 //make it transient private transient Integer queuePrefetch = null; @@ -310,6 +314,7 @@ public class AddressSettings implements Mergeable, Serializable this.defaultGroupBuckets = other.defaultGroupBuckets; this.defaultGroupFirstKey = other.defaultGroupFirstKey; this.defaultRingSize = other.defaultRingSize; + this.enableMetrics = other.enableMetrics; } public AddressSettings() { @@ -882,6 +887,15 @@ public class AddressSettings implements Mergeable, Serializable return this; } + public boolean isEnableMetrics() { + return enableMetrics != null ? enableMetrics : AddressSettings.DEFAULT_ENABLE_METRICS; + } + + public AddressSettings setEnableMetrics(final boolean enableMetrics) { + this.enableMetrics = enableMetrics; + return this; + } + /** * merge 2 objects in to 1 * @@ -1069,6 +1083,9 @@ public class AddressSettings implements Mergeable, Serializable if (expiryQueueSuffix == null) { expiryQueueSuffix = merged.expiryQueueSuffix; } + if (enableMetrics == null) { + enableMetrics = merged.enableMetrics; + } } @Override @@ -1273,6 +1290,10 @@ public class AddressSettings implements Mergeable, Serializable if (buffer.readableBytes() > 0) { maxExpiryDelay = BufferHelper.readNullableLong(buffer); } + + if (buffer.readableBytes() > 0) { + enableMetrics = BufferHelper.readNullableBoolean(buffer); + } } @Override @@ -1334,7 +1355,8 @@ public class AddressSettings implements Mergeable, Serializable SimpleString.sizeofNullableString(deadLetterQueueSuffix) + BufferHelper.sizeOfNullableBoolean(autoCreateExpiryResources) + SimpleString.sizeofNullableString(expiryQueuePrefix) + - SimpleString.sizeofNullableString(expiryQueueSuffix); + SimpleString.sizeofNullableString(expiryQueueSuffix) + + BufferHelper.sizeOfNullableBoolean(enableMetrics); } @Override @@ -1456,6 +1478,8 @@ public class AddressSettings implements Mergeable, Serializable BufferHelper.writeNullableLong(buffer, minExpiryDelay); BufferHelper.writeNullableLong(buffer, maxExpiryDelay); + + BufferHelper.writeNullableBoolean(buffer, enableMetrics); } /* (non-Javadoc) @@ -1525,6 +1549,7 @@ public class AddressSettings implements Mergeable, Serializable result = prime * result + ((autoCreateExpiryResources == null) ? 0 : autoCreateExpiryResources.hashCode()); result = prime * result + ((expiryQueuePrefix == null) ? 0 : expiryQueuePrefix.hashCode()); result = prime * result + ((expiryQueueSuffix == null) ? 0 : expiryQueueSuffix.hashCode()); + result = prime * result + ((enableMetrics == null) ? 0 : enableMetrics.hashCode()); return result; } @@ -1860,6 +1885,12 @@ public class AddressSettings implements Mergeable, Serializable } else if (!expiryQueueSuffix.equals(other.expiryQueueSuffix)) return false; + if (enableMetrics == null) { + if (other.enableMetrics != null) + return false; + } else if (!enableMetrics.equals(other.enableMetrics)) + return false; + return true; } @@ -1985,6 +2016,8 @@ public class AddressSettings implements Mergeable, Serializable expiryQueuePrefix + ", expiryQueueSuffix=" + expiryQueueSuffix + + ", enableMetrics=" + + enableMetrics + "]"; } } diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd index f9fd5ee8c1..048efb0cd0 100644 --- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd +++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd @@ -3583,6 +3583,14 @@ + + + + + whether or not to enable metrics for metrics plugins on the matching address + + + diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java index 2314cbf35d..010c524751 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java @@ -372,6 +372,7 @@ public class FileConfigurationTest extends ConfigurationImplTest { assertEquals(RoutingType.MULTICAST, conf.getAddressesSettings().get("a1").getDefaultAddressRoutingType()); assertEquals(3, conf.getAddressesSettings().get("a1").getDefaultRingSize()); assertEquals(0, conf.getAddressesSettings().get("a1").getRetroactiveMessageCount()); + assertTrue(conf.getAddressesSettings().get("a1").isEnableMetrics()); assertEquals("a2.1", conf.getAddressesSettings().get("a2").getDeadLetterAddress().toString()); assertEquals(true, conf.getAddressesSettings().get("a2").isAutoCreateDeadLetterResources()); @@ -406,6 +407,7 @@ public class FileConfigurationTest extends ConfigurationImplTest { assertEquals(10000, conf.getAddressesSettings().get("a2").getDefaultConsumerWindowSize()); assertEquals(-1, conf.getAddressesSettings().get("a2").getDefaultRingSize()); assertEquals(10, conf.getAddressesSettings().get("a2").getRetroactiveMessageCount()); + assertFalse(conf.getAddressesSettings().get("a2").isEnableMetrics()); assertTrue(conf.getResourceLimitSettings().containsKey("myUser")); assertEquals(104, conf.getResourceLimitSettings().get("myUser").getMaxConnections()); diff --git a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml index 902254a026..2b20140afd 100644 --- a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml +++ b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml @@ -472,6 +472,7 @@ ANYCAST 10000 10 + false diff --git a/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-address-settings.xml b/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-address-settings.xml index fb2186cdd2..5be0f08c01 100644 --- a/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-address-settings.xml +++ b/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-address-settings.xml @@ -77,5 +77,6 @@ ANYCAST 10000 10 + false \ No newline at end of file diff --git a/docs/user-manual/en/address-model.md b/docs/user-manual/en/address-model.md index 97f9e0e5d1..b08c704608 100644 --- a/docs/user-manual/en/address-model.md +++ b/docs/user-manual/en/address-model.md @@ -620,6 +620,7 @@ that would be found in the `broker.xml` file. -1 0 + true ``` @@ -896,3 +897,7 @@ be set to -1. Read more about [ring queues](ring-queues.md). `retroactive-message-count` defines the number of messages to preserve for future queues created on the matching address. Defaults to 0. Read more about [retroactive addresses](retroactive-addresses.md). + +`enable-metrics` determines whether or not metrics will be published to any +configured metrics plugin for the matching address. Default is `true`. Read more +about [metrics](metrics.md). diff --git a/docs/user-manual/en/metrics.md b/docs/user-manual/en/metrics.md index e1ed727d84..66655a9a4c 100644 --- a/docs/user-manual/en/metrics.md +++ b/docs/user-manual/en/metrics.md @@ -86,15 +86,19 @@ JVM memory metrics are exported as well. ## Configuration -In `broker.xml` use the `metrics-plugin` element and specify the `class-name` -attribute to configure your plugin, e.g.: +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`. + +To configure the plugin itself use the `metrics-plugin` element in `broker.xml` +and specify the `class-name` attribute, e.g.: ```xml ``` -As noted, the plugin can also be configured with key/value properties in order -to customize its behavior as necessary, e.g.: +The plugin can also be configured with key/value properties in order to +customize the implementation as necessary, e.g.: ```xml diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/MetricsPluginTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/MetricsPluginTest.java index 5ea14861f0..e3b0aaca3e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/MetricsPluginTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/MetricsPluginTest.java @@ -149,10 +149,21 @@ public class MetricsPluginTest extends ActiveMQTestBase { @Test public void testForBasicMetricsPresenceAndValue() throws Exception { + internalTestForBasicMetrics(true); + } + + @Test + public void testDisablingMetrics() throws Exception { + internalTestForBasicMetrics(false); + } + + private void internalTestForBasicMetrics(boolean enabled) throws Exception { final String data = "Simple Text " + UUID.randomUUID().toString(); final String queueName = "simpleQueue"; final String addressName = "simpleAddress"; + server.getAddressSettingsRepository().getMatch(addressName).setEnableMetrics(enabled); + session.createQueue(new QueueConfiguration(queueName).setAddress(addressName).setRoutingType(RoutingType.ANYCAST)); ClientProducer producer = session.createProducer(addressName); ClientMessage message = session.createMessage(true); @@ -165,14 +176,14 @@ public class MetricsPluginTest extends ActiveMQTestBase { Map metrics = getMetrics(); - checkMetric(metrics, "artemis.message.count", "queue", queueName, 1.0); - checkMetric(metrics, "artemis.messages.added", "queue", queueName, 1.0); - checkMetric(metrics, "artemis.messages.acknowledged", "queue", queueName, 0.0); - checkMetric(metrics, "artemis.durable.message.count", "queue", queueName, 1.0); - checkMetric(metrics, "artemis.delivering.message.count", "queue", queueName, 0.0); - checkMetric(metrics, "artemis.routed.message.count", "address", addressName, 1.0); - checkMetric(metrics, "artemis.unrouted.message.count", "address", addressName, 0.0); - checkMetric(metrics, "artemis.consumer.count", "queue", queueName, 0.0); + checkMetric(metrics, "artemis.message.count", "queue", queueName, 1.0, enabled); + checkMetric(metrics, "artemis.messages.added", "queue", queueName, 1.0, enabled); + checkMetric(metrics, "artemis.messages.acknowledged", "queue", queueName, 0.0, enabled); + checkMetric(metrics, "artemis.durable.message.count", "queue", queueName, 1.0, enabled); + checkMetric(metrics, "artemis.delivering.message.count", "queue", queueName, 0.0, enabled); + checkMetric(metrics, "artemis.routed.message.count", "address", addressName, 1.0, enabled); + checkMetric(metrics, "artemis.unrouted.message.count", "address", addressName, 0.0, enabled); + checkMetric(metrics, "artemis.consumer.count", "queue", queueName, 0.0, enabled); ClientConsumer consumer = session.createConsumer(queueName); session.start(); @@ -180,8 +191,8 @@ public class MetricsPluginTest extends ActiveMQTestBase { assertNotNull(message); metrics = getMetrics(); - checkMetric(metrics, "artemis.delivering.message.count", "queue", queueName, 1.0); - checkMetric(metrics, "artemis.consumer.count", "queue", queueName, 1.0); + checkMetric(metrics, "artemis.delivering.message.count", "queue", queueName, 1.0, enabled); + checkMetric(metrics, "artemis.consumer.count", "queue", queueName, 1.0, enabled); message.acknowledge(); assertEquals(data, message.getBodyBuffer().readString()); @@ -193,14 +204,14 @@ public class MetricsPluginTest extends ActiveMQTestBase { metrics = getMetrics(); - checkMetric(metrics, "artemis.message.count", "queue", queueName, 0.0); - checkMetric(metrics, "artemis.messages.added", "queue", queueName, 1.0); - checkMetric(metrics, "artemis.messages.acknowledged", "queue", queueName, 1.0); - checkMetric(metrics, "artemis.durable.message.count", "queue", queueName, 0.0); - checkMetric(metrics, "artemis.delivering.message.count", "queue", queueName, 0.0); - checkMetric(metrics, "artemis.routed.message.count", "address", addressName, 1.0); - checkMetric(metrics, "artemis.unrouted.message.count", "address", addressName, 0.0); - checkMetric(metrics, "artemis.consumer.count", "queue", queueName, 0.0); + checkMetric(metrics, "artemis.message.count", "queue", queueName, 0.0, enabled); + checkMetric(metrics, "artemis.messages.added", "queue", queueName, 1.0, enabled); + checkMetric(metrics, "artemis.messages.acknowledged", "queue", queueName, 1.0, enabled); + checkMetric(metrics, "artemis.durable.message.count", "queue", queueName, 0.0, enabled); + checkMetric(metrics, "artemis.delivering.message.count", "queue", queueName, 0.0, enabled); + checkMetric(metrics, "artemis.routed.message.count", "address", addressName, 1.0, enabled); + checkMetric(metrics, "artemis.unrouted.message.count", "address", addressName, 0.0, enabled); + checkMetric(metrics, "artemis.consumer.count", "queue", queueName, 0.0, enabled); } @Test @@ -247,13 +258,21 @@ public class MetricsPluginTest extends ActiveMQTestBase { } public void checkMetric(Map metrics, String metric, String tag, String tagValue, Double expectedValue) { + checkMetric(metrics, metric, tag, tagValue, expectedValue, true); + } + + public void checkMetric(Map metrics, String metric, String tag, String tagValue, Double expectedValue, boolean enabled) { OptionalDouble actualValue = metrics.entrySet().stream() .filter(entry -> metric.equals(entry.getKey().getName())) .filter(entry -> tagValue.equals(entry.getKey().getTag(tag))) .mapToDouble(Map.Entry::getValue) .findFirst(); - assertTrue(metric + " for " + tag + " " + tagValue + " not present", actualValue.isPresent()); - assertEquals(metric + " not equal", expectedValue, actualValue.getAsDouble(), 0); + if (enabled) { + assertTrue(metric + " for " + tag + " " + tagValue + " not present", actualValue.isPresent()); + assertEquals(metric + " not equal", expectedValue, actualValue.getAsDouble(), 0); + } else { + assertFalse(metric + " for " + tag + " " + tagValue + " present", actualValue.isPresent()); + } } }