]> git.basschouten.com Git - openhab-addons.git/commitdiff
[metrics] Add Java Management Extensions (JMX) metrics exporter (#11249)
authorWouter Born <github@maindrain.net>
Thu, 16 Sep 2021 07:11:12 +0000 (09:11 +0200)
committerGitHub <noreply@github.com>
Thu, 16 Sep 2021 07:11:12 +0000 (09:11 +0200)
* Add Java Management Extensions (JMX) metrics exporter
* Use groups in metrics add-on configuration
* Improve null annotations
* Update documentation

Signed-off-by: Wouter Born <github@maindrain.net>
bundles/org.openhab.io.metrics/README.md
bundles/org.openhab.io.metrics/pom.xml
bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsConfiguration.java
bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsExporter.java
bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/MetricsRestController.java
bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/InfluxMetricsExporter.java
bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/JmxMetricsExporter.java [new file with mode: 0644]
bundles/org.openhab.io.metrics/src/main/resources/OH-INF/config/config.xml

index 5060d45048c7d83b5d1b8116191cac98df6d15c4..1ed329104183703c07594660a423d348a92d73d4 100644 (file)
@@ -33,9 +33,10 @@ Support for push-based monitoring systems (e. g. InfluxDB) have to be enabled se
 
 The following configuration parameters can be set:
 
-|Config param|Description|Default value|
-|--|--|--|
-|influxMetricsEnabled|Enable the Influx (www.influxdata.com) metrics. Further configuration of the InfluxDB instance necessary.|false|
+| Config param         | Description                                                                                               | Default value |
+|----------------------|-----------------------------------------------------------------------------------------------------------|---------------|
+| influxMetricsEnabled | Enable the Influx (www.influxdata.com) metrics. Further configuration of the InfluxDB instance necessary. | false         |
+| jmxMetricsEnabled    | Enable the Java Management Extensions (JMX) metrics.                                                      | false         |
 
 Refer to the corresponding monitoring system sections for monitoring system specific configuration parameters.  
 
@@ -65,7 +66,7 @@ Replace `openhab.local` by the openhab host.
 
 #### Available configuration parameters
 
-There are no Prometheus specific configuration paramters.
+There are no Prometheus specific configuration parameters.
 
 ### InfluxDB
 
@@ -73,13 +74,21 @@ The InfluxDB exporter service will start as soon as the _influxMetricsEnabled_ c
 
 #### Available configuration parameters
 
-|Config param|Description|Default value|
-|--|--|--|
-|influxURL|The URL of the InfluxDB instance. Defaults to http://localhost:8086|http://localhost:8086|
-|influxDB|The name of the database to use. Defaults to "openhab".|openhab|
-|influxUsername|InfluxDB user name|n/a|
-|influxPassword|The InfluxDB password (no default).|n/a|
-|influxUpdateIntervalInSeconds|Controls how often metrics are exported to InfluxDB (in seconds). Defaults to 300|300|
+| Config param                  | Description                                                                       | Default value         |
+|-------------------------------|-----------------------------------------------------------------------------------|-----------------------|
+| influxURL                     | The URL of the InfluxDB instance. Defaults to http://localhost:8086               | http://localhost:8086 |
+| influxDB                      | The name of the database to use. Defaults to "openhab".                           | openhab               |
+| influxUsername                | InfluxDB user name                                                                | n/a                   |
+| influxPassword                | The InfluxDB password (no default).                                               | n/a                   |
+| influxUpdateIntervalInSeconds | Controls how often metrics are exported to InfluxDB (in seconds). Defaults to 300 | 300                   |
+
+### JMX
+
+The Java Management Extensions (JMX) exporter service will start as soon as the _jmxMetricsEnabled_ configuration parameter is set to true.
+
+You can monitor the JMX metrics using a tool like [JConsole](https://docs.oracle.com/en/java/javase/11/management/using-jconsole.html) or [VisualVM](https://visualvm.github.io/) (after installing the VisualVM-MBeans plugin).
+When the JMX exporter is enabled, the metrics will be available under the "metrics" MBean.
+JConsole and VisualVM will only be able to connect using JMX when openHAB is started in debug mode (use `start_debug.sh` or `start_debug.bat`).
 
 ## Additional metric formats
 
index 439c3506bf8b0d8b9557bb0ccc7566d8bfa41baa..91540d606f72bd42c6928a92bb4a7a3b35cf5225 100644 (file)
         </exclusion>
       </exclusions>
     </dependency>
+    <dependency>
+      <groupId>io.dropwizard.metrics</groupId>
+      <artifactId>metrics-jmx</artifactId>
+      <version>4.0.7</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.micrometer</groupId>
+      <artifactId>micrometer-registry-jmx</artifactId>
+      <version>${micrometer.version}</version>
+      <scope>compile</scope>
+    </dependency>
     <dependency>
       <groupId>io.micrometer</groupId>
       <artifactId>micrometer-registry-prometheus</artifactId>
index 08daf12192bfc4286dcd8ad418a595191d9df9db..b40ce1d6c36365f9ce0f472f0b8ae7855353469c 100644 (file)
@@ -25,15 +25,17 @@ public class MetricsConfiguration {
     public boolean influxMetricsEnabled = false;
     public String influxURL = "http://localhost:8086";
     public String influxDB = "openhab";
-    public @Nullable String influxPassword = null;
-    public @Nullable String influxUsername = null;
+    public @Nullable String influxPassword;
+    public @Nullable String influxUsername;
     public Integer influxUpdateIntervalInSeconds = 300;
 
+    public boolean jmxMetricsEnabled = false;
+
     @Override
     public String toString() {
         return "MetricsConfiguration{" + "influxMetricsEnabled=" + influxMetricsEnabled + ", influxURL='" + influxURL
                 + '\'' + ", influxDB='" + influxDB + '\'' + ", influxPassword='" + influxPassword + '\''
                 + ", influxUsername='" + influxUsername + '\'' + ", influxUpdateIntervalInSeconds="
-                + influxUpdateIntervalInSeconds + '}';
+                + influxUpdateIntervalInSeconds + ", jmxMetricsEnabled=" + jmxMetricsEnabled + '}';
     }
 }
index cc1c644d8f6c239dffc697c6f1f579eca00c3f86..6d6acad131ad9464f547458374821a24de7d3ed6 100644 (file)
@@ -31,8 +31,8 @@ public abstract class MetricsExporter {
 
     private final Logger logger = LoggerFactory.getLogger(MetricsExporter.class);
     private boolean active = false;
-    protected @Nullable CompositeMeterRegistry meterRegistry = null;
-    protected @Nullable MetricsConfiguration config = null;
+    protected @Nullable CompositeMeterRegistry meterRegistry;
+    protected @Nullable MetricsConfiguration config;
 
     protected abstract void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration);
 
index b13b73ca435d24e8a380280bac1f8649a867ed3e..6d42edd5bbf31523144968720ea5ab88eab1b726 100644 (file)
@@ -14,7 +14,6 @@ package org.openhab.io.metrics;
 
 import java.util.HashSet;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 
 import javax.annotation.security.RolesAllowed;
@@ -31,6 +30,7 @@ import org.openhab.core.config.core.Configuration;
 import org.openhab.core.io.monitor.MeterRegistryProvider;
 import org.openhab.core.io.rest.RESTConstants;
 import org.openhab.io.metrics.exporters.InfluxMetricsExporter;
+import org.openhab.io.metrics.exporters.JmxMetricsExporter;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Modified;
@@ -68,7 +68,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 public class MetricsRestController {
     private final Logger logger = LoggerFactory.getLogger(MetricsRestController.class);
     public static final String PATH_METRICS = "metrics";
-    private @Nullable CompositeMeterRegistry meterRegistry = null;
+    private @Nullable CompositeMeterRegistry meterRegistry;
     private final PrometheusMeterRegistry prometheusMeterRegistry = new PrometheusMeterRegistry(
             PrometheusConfig.DEFAULT);
     private final Set<MetricsExporter> metricsExporters = new HashSet<>();
@@ -85,11 +85,13 @@ public class MetricsRestController {
 
     @Reference
     public void setMeterRegistryProvider(MeterRegistryProvider meterRegistryProvider) {
+        CompositeMeterRegistry meterRegistry = this.meterRegistry;
         if (meterRegistry != null) {
-            Objects.requireNonNull(meterRegistry).remove(prometheusMeterRegistry);
+            meterRegistry.remove(prometheusMeterRegistry);
         }
         meterRegistry = meterRegistryProvider.getOHMeterRegistry();
-        Objects.requireNonNull(meterRegistry).add(prometheusMeterRegistry);
+        meterRegistry.add(prometheusMeterRegistry);
+        this.meterRegistry = meterRegistry;
         logger.debug("Core metrics registry retrieved and Prometheus registry added successfully.");
         updateMeterRegistry();
     }
@@ -98,6 +100,7 @@ public class MetricsRestController {
     protected void activate(Map<@Nullable String, @Nullable Object> configuration) {
         logger.info("Metrics service activated, serving the following URL(s): /rest/metrics/prometheus");
         metricsExporters.add(new InfluxMetricsExporter());
+        metricsExporters.add(new JmxMetricsExporter());
         updateConfig(configuration);
         updateMeterRegistry();
     }
index 8b02eac05e30dd20c72e0cf191514a756408846d..24e710408862095bd33291aeb74b0bc3ad0215f0 100644 (file)
@@ -13,7 +13,6 @@
 package org.openhab.io.metrics.exporters;
 
 import java.time.Duration;
-import java.util.Objects;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -26,15 +25,15 @@ import io.micrometer.influx.InfluxConfig;
 import io.micrometer.influx.InfluxMeterRegistry;
 
 /**
- * The {@link InfluxMetricsExporter} class implements a MetricsExporter for InfluxDB
+ * The {@link InfluxMetricsExporter} class implements a MetricsExporter for InfluxDB.
  *
  * @author Robert Bach - Initial contribution
  */
 @NonNullByDefault
 public class InfluxMetricsExporter extends MetricsExporter {
 
-    private @Nullable InfluxMeterRegistry influxMeterRegistry = null;
-    private @Nullable CompositeMeterRegistry meterRegistry = null;
+    private @Nullable InfluxMeterRegistry influxMeterRegistry;
+    private @Nullable CompositeMeterRegistry meterRegistry;
 
     @Override
     public void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration) {
@@ -44,14 +43,17 @@ public class InfluxMetricsExporter extends MetricsExporter {
 
     @Override
     public void shutdown() {
+        InfluxMeterRegistry influxMeterRegistry = this.influxMeterRegistry;
         if (influxMeterRegistry != null) {
-            Objects.requireNonNull(influxMeterRegistry).stop();
+            influxMeterRegistry.stop();
+            this.influxMeterRegistry = null;
         }
+
+        CompositeMeterRegistry meterRegistry = this.meterRegistry;
         if (meterRegistry != null) {
-            Objects.requireNonNull(meterRegistry).remove(influxMeterRegistry);
-            meterRegistry = null;
+            meterRegistry.remove(influxMeterRegistry);
+            this.meterRegistry = null;
         }
-        influxMeterRegistry = null;
     }
 
     private InfluxConfig getInfluxConfig(MetricsConfiguration metricsConfiguration) {
diff --git a/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/JmxMetricsExporter.java b/bundles/org.openhab.io.metrics/src/main/java/org/openhab/io/metrics/exporters/JmxMetricsExporter.java
new file mode 100644 (file)
index 0000000..8644a19
--- /dev/null
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.io.metrics.exporters;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.io.metrics.MetricsConfiguration;
+import org.openhab.io.metrics.MetricsExporter;
+
+import io.micrometer.core.instrument.Clock;
+import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
+import io.micrometer.jmx.JmxConfig;
+import io.micrometer.jmx.JmxMeterRegistry;
+
+/**
+ * The {@link JmxMetricsExporter} class implements a MetricsExporter for Java Management Extensions (JMX).
+ *
+ * @author Wouter Born - Initial contribution
+ */
+@NonNullByDefault
+public class JmxMetricsExporter extends MetricsExporter {
+
+    private @Nullable JmxMeterRegistry jmxMeterRegistry;
+    private @Nullable CompositeMeterRegistry meterRegistry;
+
+    @Override
+    public void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration) {
+        jmxMeterRegistry = new JmxMeterRegistry(getJmxConfig(), Clock.SYSTEM);
+        meterRegistry.add(jmxMeterRegistry);
+    }
+
+    @Override
+    public void shutdown() {
+        JmxMeterRegistry jmxMeterRegistry = this.jmxMeterRegistry;
+        if (jmxMeterRegistry != null) {
+            jmxMeterRegistry.stop();
+            this.jmxMeterRegistry = null;
+        }
+
+        CompositeMeterRegistry meterRegistry = this.meterRegistry;
+        if (meterRegistry != null) {
+            meterRegistry.remove(jmxMeterRegistry);
+            this.meterRegistry = null;
+        }
+    }
+
+    private JmxConfig getJmxConfig() {
+        return new JmxConfig() {
+            @Override
+            @io.micrometer.core.lang.Nullable
+            @Nullable
+            public String get(@Nullable String k) {
+                return null; // accept the rest of the defaults
+            }
+        };
+    }
+
+    @Override
+    protected boolean isEnabled(MetricsConfiguration config) {
+        return config.jmxMetricsEnabled;
+    }
+}
index dd30657702bfc6c96f52d95f3c814af7d1e363bf..9d32dd65d096173e7bcccc98a46bafd7a047af02 100644 (file)
@@ -5,35 +5,48 @@
        xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
                https://openhab.org/schemas/config-description-1.0.0.xsd">
        <config-description uri="io:metrics">
-               <parameter name="influxMetricsEnabled" type="boolean">
+               <parameter-group name="influx">
                        <label>Influx Metrics</label>
+               </parameter-group>
+               <parameter-group name="jmx">
+                       <label>JMX Metrics</label>
+               </parameter-group>
+
+               <parameter name="influxMetricsEnabled" type="boolean" groupName="influx">
+                       <label>Enabled</label>
                        <description>Enable the Influx (www.influxdata.com) Metrics. Further Configuration of the InfluxDB Instance
                                Necessary.</description>
                        <default>false</default>
                </parameter>
-               <parameter name="influxURL" type="text">
-                       <label>InfluxDB URL</label>
+               <parameter name="influxURL" type="text" groupName="influx">
+                       <label>URL</label>
                        <description>The URL of the InfluxDB Instance. Defaults to http://localhost:8086</description>
                        <default>http://localhost:8086</default>
                </parameter>
-               <parameter name="influxDB" type="text">
-                       <label>InfluxDB Database Name</label>
+               <parameter name="influxDB" type="text" groupName="influx">
+                       <label>Database Name</label>
                        <description>The Name of the Database to Use. Defaults to "openhab".</description>
                        <default>openhab</default>
                </parameter>
-               <parameter name="influxUsername" type="text">
-                       <label>InfluxDB User Name</label>
+               <parameter name="influxUsername" type="text" groupName="influx">
+                       <label>User Name</label>
                        <description>The InfluxDB User Name (No Default).</description>
                </parameter>
-               <parameter name="influxPassword" type="text">
-                       <label>InfluxDB Password</label>
+               <parameter name="influxPassword" type="text" groupName="influx">
+                       <label>Password</label>
                        <description>The InfluxDB Password (No Default).</description>
                        <context>password</context>
                </parameter>
-               <parameter name="influxUpdateIntervalInSeconds" type="integer" unit="s" min="1">
-                       <label>InfluxDB Update Interval in Seconds</label>
+               <parameter name="influxUpdateIntervalInSeconds" type="integer" unit="s" min="1" groupName="influx">
+                       <label>Update Interval in Seconds</label>
                        <description>Controls How Often Metrics Are Exported to InfluxDB (in Seconds). Defaults to 300</description>
                        <default>300</default>
                </parameter>
+
+               <parameter name="jmxMetricsEnabled" type="boolean" groupName="jmx">
+                       <label>Enabled</label>
+                       <description>Enable the Java Management Extensions (JMX) Metrics.</description>
+                       <default>false</default>
+               </parameter>
        </config-description>
 </config-description:config-descriptions>