This is an automated email from the ASF dual-hosted git repository.

robbie pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 661a4e6fdc ARTEMIS-4655 report logging metrics
661a4e6fdc is described below

commit 661a4e6fdc1d10b115c209a25e96e6b97e75e8e6
Author: Justin Bertram <[email protected]>
AuthorDate: Thu Feb 22 15:25:05 2024 -0600

    ARTEMIS-4655 report logging metrics
    
    It may be useful to configure alerts for ERROR or WARN events in the log
    which may go unnoticed otherwise.
---
 .../api/config/ActiveMQDefaultConfiguration.java   | 10 +++
 .../artemis/core/config/MetricsConfiguration.java  | 10 +++
 .../deployers/impl/FileConfigurationParser.java    |  2 +
 .../core/server/metrics/MetricsManager.java        |  4 +
 .../resources/schema/artemis-configuration.xsd     |  8 ++
 .../config/impl/DefaultsFileConfigurationTest.java |  2 +
 .../core/config/impl/FileConfigurationTest.java    |  1 +
 .../resources/ConfigurationTest-full-config.xml    |  1 +
 .../ConfigurationTest-xinclude-config.xml          |  1 +
 ...gurationTest-xinclude-schema-config-metrics.xml |  1 +
 artemis-server/src/test/resources/metrics.xml      |  1 +
 docs/user-manual/metrics.adoc                      | 13 ++-
 .../integration/plugin/LoggingMetricsTest.java     | 99 ++++++++++++++++++++++
 13 files changed, 152 insertions(+), 1 deletion(-)

diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
index 1a6a8f47e7..0fe9cd90bb 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
@@ -676,6 +676,9 @@ public final class ActiveMQDefaultConfiguration {
    // Whether or not to report uptime metrics
    private static final boolean DEFAULT_UPTIME_METRICS = false;
 
+   // Whether or not to report logging metrics
+   private static final boolean DEFAULT_LOGGING_METRICS = false;
+
    // How often (in ms) to scan for expired MQTT sessions
    private static long DEFAULT_MQTT_SESSION_SCAN_INTERVAL = 500;
 
@@ -1865,6 +1868,13 @@ public final class ActiveMQDefaultConfiguration {
       return DEFAULT_UPTIME_METRICS;
    }
 
+   /**
+    * Whether or not to report logging metrics
+    */
+   public static Boolean getDefaultLoggingMetrics() {
+      return DEFAULT_LOGGING_METRICS;
+   }
+
    /**
     * How often (in ms) to scan for expired MQTT sessions
     */
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/MetricsConfiguration.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/MetricsConfiguration.java
index aa1173048e..566b1a25bd 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/MetricsConfiguration.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/MetricsConfiguration.java
@@ -30,6 +30,7 @@ public class MetricsConfiguration implements Serializable {
    private boolean fileDescriptors = 
ActiveMQDefaultConfiguration.getDefaultFileDescriptorsMetrics();
    private boolean processor = 
ActiveMQDefaultConfiguration.getDefaultProcessorMetrics();
    private boolean uptime = 
ActiveMQDefaultConfiguration.getDefaultUptimeMetrics();
+   private boolean logging = 
ActiveMQDefaultConfiguration.getDefaultLoggingMetrics();
    private ActiveMQMetricsPlugin plugin;
 
    public boolean isJvmMemory() {
@@ -95,6 +96,15 @@ public class MetricsConfiguration implements Serializable {
       return this;
    }
 
+   public boolean isLogging() {
+      return logging;
+   }
+
+   public MetricsConfiguration setLogging(boolean logging) {
+      this.logging = logging;
+      return this;
+   }
+
    public ActiveMQMetricsPlugin getPlugin() {
       return plugin;
    }
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 7ec64918f4..527afd5f37 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
@@ -1012,6 +1012,8 @@ public final class FileConfigurationParser extends 
XMLConfigurationUtil {
                metricsConfiguration.setProcessor(XMLUtil.parseBoolean(child));
             } else if (child.getNodeName().equals("uptime")) {
                metricsConfiguration.setUptime(XMLUtil.parseBoolean(child));
+            } else if (child.getNodeName().equals("logging")) {
+               metricsConfiguration.setLogging(XMLUtil.parseBoolean(child));
             } else if (child.getNodeName().equals("plugin")) {
                metricsConfiguration.setPlugin(parseMetricsPlugin(child, 
config));
             }
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 5d2ca011d2..bc688f99cc 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
@@ -32,6 +32,7 @@ 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 io.micrometer.core.instrument.binder.logging.Log4j2Metrics;
 import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics;
 import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
 import io.micrometer.core.instrument.binder.system.UptimeMetrics;
@@ -86,6 +87,9 @@ public class MetricsManager {
          if (metricsConfiguration.isUptime()) {
             new UptimeMetrics().bindTo(meterRegistry);
          }
+         if (metricsConfiguration.isLogging()) {
+            new Log4j2Metrics().bindTo(meterRegistry);
+         }
       }
    }
 
diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd 
b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
index 7355fdbeed..7bca911b28 100644
--- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd
+++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
@@ -4836,6 +4836,14 @@
                </xsd:annotation>
             </xsd:element>
 
+            <xsd:element name="logging" type="xsd:boolean" default="false" 
maxOccurs="1" minOccurs="0">
+               <xsd:annotation>
+                  <xsd:documentation>
+                     whether or not to report logging metrics
+                  </xsd:documentation>
+               </xsd:annotation>
+            </xsd:element>
+
             <xsd:element name="plugin" maxOccurs="1" minOccurs="0">
                <xsd:complexType>
                   <xsd:annotation>
diff --git 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DefaultsFileConfigurationTest.java
 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DefaultsFileConfigurationTest.java
index 6704763752..4bed395d56 100644
--- 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DefaultsFileConfigurationTest.java
+++ 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/DefaultsFileConfigurationTest.java
@@ -147,6 +147,8 @@ public class DefaultsFileConfigurationTest extends 
ConfigurationImplTest {
       
Assert.assertEquals(ActiveMQDefaultConfiguration.getDefaultProcessorMetrics(), 
conf.getMetricsConfiguration().isProcessor());
 
       
Assert.assertEquals(ActiveMQDefaultConfiguration.getDefaultUptimeMetrics(), 
conf.getMetricsConfiguration().isUptime());
+
+      
Assert.assertEquals(ActiveMQDefaultConfiguration.getDefaultLoggingMetrics(), 
conf.getMetricsConfiguration().isLogging());
    }
 
    // Protected 
---------------------------------------------------------------------------------------------
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 48516272d5..60a6a0e2d9 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
@@ -584,6 +584,7 @@ public class FileConfigurationTest extends 
ConfigurationImplTest {
       assertTrue(metricsConfiguration.isFileDescriptors());
       assertTrue(metricsConfiguration.isProcessor());
       assertTrue(metricsConfiguration.isUptime());
+      assertTrue(metricsConfiguration.isLogging());
    }
 
    private void verifyAddresses() {
diff --git 
a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml 
b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
index 704cb58e0b..137ddfa4c6 100644
--- a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
+++ b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
@@ -384,6 +384,7 @@
          <file-descriptors>true</file-descriptors>
          <processor>true</processor>
          <uptime>true</uptime>
+         <logging>true</logging>
          <plugin 
class-name="org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin">
             <property key="foo" value="x"/>
             <property key="bar" value="y"/>
diff --git 
a/artemis-server/src/test/resources/ConfigurationTest-xinclude-config.xml 
b/artemis-server/src/test/resources/ConfigurationTest-xinclude-config.xml
index 44961398de..6193b1086c 100644
--- a/artemis-server/src/test/resources/ConfigurationTest-xinclude-config.xml
+++ b/artemis-server/src/test/resources/ConfigurationTest-xinclude-config.xml
@@ -265,6 +265,7 @@
          <file-descriptors>true</file-descriptors>
          <processor>true</processor>
          <uptime>true</uptime>
+         <logging>true</logging>
          <plugin 
class-name="org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin">
             <property key="foo" value="x"/>
             <property key="bar" value="y"/>
diff --git 
a/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-metrics.xml
 
b/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-metrics.xml
index 98b815ec19..d396cdcaa0 100644
--- 
a/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-metrics.xml
+++ 
b/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-metrics.xml
@@ -22,6 +22,7 @@
    <file-descriptors>true</file-descriptors>
    <processor>true</processor>
    <uptime>true</uptime>
+   <logging>true</logging>
    <plugin 
class-name="org.apache.activemq.artemis.core.server.metrics.plugins.SimpleMetricsPlugin">
       <property key="foo" value="x"/>
       <property key="bar" value="y"/>
diff --git a/artemis-server/src/test/resources/metrics.xml 
b/artemis-server/src/test/resources/metrics.xml
index c4277e2249..671407fe9f 100644
--- a/artemis-server/src/test/resources/metrics.xml
+++ b/artemis-server/src/test/resources/metrics.xml
@@ -27,6 +27,7 @@
          <file-descriptors>true</file-descriptors>
          <processor>true</processor>
          <uptime>true</uptime>
+         <logging>true</logging>
          <plugin 
class-name="org.apache.activemq.artemis.core.config.impl.FileConfigurationTest$FakeMetricPlugin">
             <property key="key1" value="value1"/>
             <property key="key2" value="value2"/>
diff --git a/docs/user-manual/metrics.adoc b/docs/user-manual/metrics.adoc
index dcae56ecd5..4930eb8edc 100644
--- a/docs/user-manual/metrics.adoc
+++ b/docs/user-manual/metrics.adoc
@@ -118,13 +118,23 @@ Uptime::
 Gauges process start time and uptime.
 +
 Disabled by default.
+Logging::
+Counts the number of logging events per logging category (e.g. `WARN`, 
`ERROR`, etc.).
++
+Disabled by default.
++
+[WARNING]
+====
+This works _exclusively_ with Log4j2 (i.e the default logging implementation 
shipped with the broker).
+If you're embedding the broker and using a different logging implementation 
(e.g. Log4j 1.x, JUL, Logback, etc.) and you enable these metrics then the 
broker will fail to start with a `java.lang.NoClassDefFoundError` as it 
attempts to locate Log4j2 classes that don't exist on the classpath.
+====
 
 == Configuration
 
 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`.
 
-In `broker.xml` use the `metrics` element to configure which JVM metrics are 
reported and to configure the plugin itself.
+In `broker.xml` use the `metrics` element to configure which general broker 
and JVM metrics are reported and to configure the plugin itself.
 Here's a configuration with all optional metrics:
 
 [,xml]
@@ -137,6 +147,7 @@ Here's a configuration with all optional metrics:
    <file-descriptors>true</file-descriptors> <!-- defaults to false -->
    <processor>true</processor> <!-- defaults to false -->
    <uptime>true</uptime> <!-- defaults to false -->
+   <logging>true</logging> <!-- defaults to false -->
    <plugin 
class-name="org.apache.activemq.artemis.core.server.metrics.plugins.LoggingMetricsPlugin"/>
 </metrics>
 ----
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/LoggingMetricsTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/LoggingMetricsTest.java
new file mode 100644
index 0000000000..3c8a9f76b0
--- /dev/null
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/plugin/LoggingMetricsTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.tests.integration.plugin;
+
+import java.lang.invoke.MethodHandles;
+
+import io.micrometer.core.instrument.Meter;
+import io.micrometer.core.instrument.Tag;
+import io.micrometer.core.instrument.Tags;
+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.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LoggingMetricsTest extends ActiveMQTestBase {
+
+   @Override
+   @Before
+   public void setUp() throws Exception {
+      super.setUp();
+   }
+
+   @Test
+   public void testLoggingMetrics() throws Exception {
+      final String idName = "log4j2.events";
+      final Tag brokerTag = Tag.of("broker", "localhost");
+      final String levelName = "level";
+      int start = 0;
+      String message = "";
+      ActiveMQServer server = createServer(false, createDefaultInVMConfig()
+         .setMetricsConfiguration(new MetricsConfiguration()
+                                     .setPlugin(new 
SimpleMetricsPlugin().init(null))
+                                     .setLogging(true)));
+      server.start();
+
+      Configurator.setLevel(MethodHandles.lookup().lookupClass(), Level.TRACE);
+      final Logger logger = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+      Meter.Id trace = new Meter.Id(idName, Tags.of(brokerTag, 
Tag.of(levelName, "trace")), null, null, null);
+      assertTrue(MetricsPluginTest.getMetrics(server).containsKey(trace));
+      start = MetricsPluginTest.getMetrics(server).get(trace).intValue();
+      logger.trace(message);
+      logger.trace(message);
+      logger.trace(message);
+      assertEquals(3, 
MetricsPluginTest.getMetrics(server).get(trace).intValue() - start);
+
+      Meter.Id debug = new Meter.Id(idName, Tags.of(brokerTag, 
Tag.of(levelName, "debug")), null, null, null);
+      assertTrue(MetricsPluginTest.getMetrics(server).containsKey(debug));
+      start = MetricsPluginTest.getMetrics(server).get(debug).intValue();
+      logger.debug(message);
+      logger.debug(message);
+      logger.debug(message);
+      assertEquals(3, 
MetricsPluginTest.getMetrics(server).get(debug).intValue() - start);
+
+      Meter.Id info = new Meter.Id(idName, Tags.of(brokerTag, 
Tag.of(levelName, "info")), null, null, null);
+      assertTrue(MetricsPluginTest.getMetrics(server).containsKey(info));
+      start = MetricsPluginTest.getMetrics(server).get(info).intValue();
+      logger.info(message);
+      logger.info(message);
+      logger.info(message);
+      assertEquals(3, 
MetricsPluginTest.getMetrics(server).get(info).intValue() - start);
+
+      Meter.Id warn = new Meter.Id(idName, Tags.of(brokerTag, 
Tag.of(levelName, "warn")), null, null, null);
+      assertTrue(MetricsPluginTest.getMetrics(server).containsKey(warn));
+      start = MetricsPluginTest.getMetrics(server).get(warn).intValue();
+      logger.warn(message);
+      logger.warn(message);
+      logger.warn(message);
+      assertEquals(3, 
MetricsPluginTest.getMetrics(server).get(warn).intValue() - start);
+
+      Meter.Id error = new Meter.Id(idName, Tags.of(brokerTag, 
Tag.of(levelName, "error")), null, null, null);
+      assertTrue(MetricsPluginTest.getMetrics(server).containsKey(error));
+      start = MetricsPluginTest.getMetrics(server).get(error).intValue();
+      logger.error(message);
+      logger.error(message);
+      logger.error(message);
+      assertEquals(3, 
MetricsPluginTest.getMetrics(server).get(error).intValue() - start);
+   }
+}

Reply via email to