[metrics] Add Java Management Extensions (JMX) metrics exporter (#11249)
* 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>
This commit is contained in:
parent
ba3a9bb01a
commit
30198e273a
|
@ -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:
|
The following configuration parameters can be set:
|
||||||
|
|
||||||
|Config param|Description|Default value|
|
| Config param | Description | Default value |
|
||||||
|--|--|--|
|
|----------------------|-----------------------------------------------------------------------------------------------------------|---------------|
|
||||||
|influxMetricsEnabled|Enable the Influx (www.influxdata.com) metrics. Further configuration of the InfluxDB instance necessary.|false|
|
| 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.
|
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
|
#### Available configuration parameters
|
||||||
|
|
||||||
There are no Prometheus specific configuration paramters.
|
There are no Prometheus specific configuration parameters.
|
||||||
|
|
||||||
### InfluxDB
|
### InfluxDB
|
||||||
|
|
||||||
|
@ -73,13 +74,21 @@ The InfluxDB exporter service will start as soon as the _influxMetricsEnabled_ c
|
||||||
|
|
||||||
#### Available configuration parameters
|
#### Available configuration parameters
|
||||||
|
|
||||||
|Config param|Description|Default value|
|
| Config param | Description | Default value |
|
||||||
|--|--|--|
|
|-------------------------------|-----------------------------------------------------------------------------------|-----------------------|
|
||||||
|influxURL|The URL of the InfluxDB instance. Defaults to http://localhost:8086|http://localhost:8086|
|
| 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|
|
| influxDB | The name of the database to use. Defaults to "openhab". | openhab |
|
||||||
|influxUsername|InfluxDB user name|n/a|
|
| influxUsername | InfluxDB user name | n/a |
|
||||||
|influxPassword|The InfluxDB password (no default).|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|
|
| 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
|
## Additional metric formats
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,18 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</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>
|
<dependency>
|
||||||
<groupId>io.micrometer</groupId>
|
<groupId>io.micrometer</groupId>
|
||||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||||
|
|
|
@ -25,15 +25,17 @@ public class MetricsConfiguration {
|
||||||
public boolean influxMetricsEnabled = false;
|
public boolean influxMetricsEnabled = false;
|
||||||
public String influxURL = "http://localhost:8086";
|
public String influxURL = "http://localhost:8086";
|
||||||
public String influxDB = "openhab";
|
public String influxDB = "openhab";
|
||||||
public @Nullable String influxPassword = null;
|
public @Nullable String influxPassword;
|
||||||
public @Nullable String influxUsername = null;
|
public @Nullable String influxUsername;
|
||||||
public Integer influxUpdateIntervalInSeconds = 300;
|
public Integer influxUpdateIntervalInSeconds = 300;
|
||||||
|
|
||||||
|
public boolean jmxMetricsEnabled = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MetricsConfiguration{" + "influxMetricsEnabled=" + influxMetricsEnabled + ", influxURL='" + influxURL
|
return "MetricsConfiguration{" + "influxMetricsEnabled=" + influxMetricsEnabled + ", influxURL='" + influxURL
|
||||||
+ '\'' + ", influxDB='" + influxDB + '\'' + ", influxPassword='" + influxPassword + '\''
|
+ '\'' + ", influxDB='" + influxDB + '\'' + ", influxPassword='" + influxPassword + '\''
|
||||||
+ ", influxUsername='" + influxUsername + '\'' + ", influxUpdateIntervalInSeconds="
|
+ ", influxUsername='" + influxUsername + '\'' + ", influxUpdateIntervalInSeconds="
|
||||||
+ influxUpdateIntervalInSeconds + '}';
|
+ influxUpdateIntervalInSeconds + ", jmxMetricsEnabled=" + jmxMetricsEnabled + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ public abstract class MetricsExporter {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(MetricsExporter.class);
|
private final Logger logger = LoggerFactory.getLogger(MetricsExporter.class);
|
||||||
private boolean active = false;
|
private boolean active = false;
|
||||||
protected @Nullable CompositeMeterRegistry meterRegistry = null;
|
protected @Nullable CompositeMeterRegistry meterRegistry;
|
||||||
protected @Nullable MetricsConfiguration config = null;
|
protected @Nullable MetricsConfiguration config;
|
||||||
|
|
||||||
protected abstract void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration);
|
protected abstract void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ package org.openhab.io.metrics;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.security.RolesAllowed;
|
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.monitor.MeterRegistryProvider;
|
||||||
import org.openhab.core.io.rest.RESTConstants;
|
import org.openhab.core.io.rest.RESTConstants;
|
||||||
import org.openhab.io.metrics.exporters.InfluxMetricsExporter;
|
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.Activate;
|
||||||
import org.osgi.service.component.annotations.Component;
|
import org.osgi.service.component.annotations.Component;
|
||||||
import org.osgi.service.component.annotations.Modified;
|
import org.osgi.service.component.annotations.Modified;
|
||||||
|
@ -68,7 +68,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
public class MetricsRestController {
|
public class MetricsRestController {
|
||||||
private final Logger logger = LoggerFactory.getLogger(MetricsRestController.class);
|
private final Logger logger = LoggerFactory.getLogger(MetricsRestController.class);
|
||||||
public static final String PATH_METRICS = "metrics";
|
public static final String PATH_METRICS = "metrics";
|
||||||
private @Nullable CompositeMeterRegistry meterRegistry = null;
|
private @Nullable CompositeMeterRegistry meterRegistry;
|
||||||
private final PrometheusMeterRegistry prometheusMeterRegistry = new PrometheusMeterRegistry(
|
private final PrometheusMeterRegistry prometheusMeterRegistry = new PrometheusMeterRegistry(
|
||||||
PrometheusConfig.DEFAULT);
|
PrometheusConfig.DEFAULT);
|
||||||
private final Set<MetricsExporter> metricsExporters = new HashSet<>();
|
private final Set<MetricsExporter> metricsExporters = new HashSet<>();
|
||||||
|
@ -85,11 +85,13 @@ public class MetricsRestController {
|
||||||
|
|
||||||
@Reference
|
@Reference
|
||||||
public void setMeterRegistryProvider(MeterRegistryProvider meterRegistryProvider) {
|
public void setMeterRegistryProvider(MeterRegistryProvider meterRegistryProvider) {
|
||||||
|
CompositeMeterRegistry meterRegistry = this.meterRegistry;
|
||||||
if (meterRegistry != null) {
|
if (meterRegistry != null) {
|
||||||
Objects.requireNonNull(meterRegistry).remove(prometheusMeterRegistry);
|
meterRegistry.remove(prometheusMeterRegistry);
|
||||||
}
|
}
|
||||||
meterRegistry = meterRegistryProvider.getOHMeterRegistry();
|
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.");
|
logger.debug("Core metrics registry retrieved and Prometheus registry added successfully.");
|
||||||
updateMeterRegistry();
|
updateMeterRegistry();
|
||||||
}
|
}
|
||||||
|
@ -98,6 +100,7 @@ public class MetricsRestController {
|
||||||
protected void activate(Map<@Nullable String, @Nullable Object> configuration) {
|
protected void activate(Map<@Nullable String, @Nullable Object> configuration) {
|
||||||
logger.info("Metrics service activated, serving the following URL(s): /rest/metrics/prometheus");
|
logger.info("Metrics service activated, serving the following URL(s): /rest/metrics/prometheus");
|
||||||
metricsExporters.add(new InfluxMetricsExporter());
|
metricsExporters.add(new InfluxMetricsExporter());
|
||||||
|
metricsExporters.add(new JmxMetricsExporter());
|
||||||
updateConfig(configuration);
|
updateConfig(configuration);
|
||||||
updateMeterRegistry();
|
updateMeterRegistry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
package org.openhab.io.metrics.exporters;
|
package org.openhab.io.metrics.exporters;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
@ -26,15 +25,15 @@ import io.micrometer.influx.InfluxConfig;
|
||||||
import io.micrometer.influx.InfluxMeterRegistry;
|
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
|
* @author Robert Bach - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class InfluxMetricsExporter extends MetricsExporter {
|
public class InfluxMetricsExporter extends MetricsExporter {
|
||||||
|
|
||||||
private @Nullable InfluxMeterRegistry influxMeterRegistry = null;
|
private @Nullable InfluxMeterRegistry influxMeterRegistry;
|
||||||
private @Nullable CompositeMeterRegistry meterRegistry = null;
|
private @Nullable CompositeMeterRegistry meterRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration) {
|
public void start(CompositeMeterRegistry meterRegistry, MetricsConfiguration metricsConfiguration) {
|
||||||
|
@ -44,14 +43,17 @@ public class InfluxMetricsExporter extends MetricsExporter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
|
InfluxMeterRegistry influxMeterRegistry = this.influxMeterRegistry;
|
||||||
if (influxMeterRegistry != null) {
|
if (influxMeterRegistry != null) {
|
||||||
Objects.requireNonNull(influxMeterRegistry).stop();
|
influxMeterRegistry.stop();
|
||||||
|
this.influxMeterRegistry = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompositeMeterRegistry meterRegistry = this.meterRegistry;
|
||||||
if (meterRegistry != null) {
|
if (meterRegistry != null) {
|
||||||
Objects.requireNonNull(meterRegistry).remove(influxMeterRegistry);
|
meterRegistry.remove(influxMeterRegistry);
|
||||||
meterRegistry = null;
|
this.meterRegistry = null;
|
||||||
}
|
}
|
||||||
influxMeterRegistry = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private InfluxConfig getInfluxConfig(MetricsConfiguration metricsConfiguration) {
|
private InfluxConfig getInfluxConfig(MetricsConfiguration metricsConfiguration) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,35 +5,48 @@
|
||||||
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
|
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
|
||||||
https://openhab.org/schemas/config-description-1.0.0.xsd">
|
https://openhab.org/schemas/config-description-1.0.0.xsd">
|
||||||
<config-description uri="io:metrics">
|
<config-description uri="io:metrics">
|
||||||
<parameter name="influxMetricsEnabled" type="boolean">
|
<parameter-group name="influx">
|
||||||
<label>Influx Metrics</label>
|
<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
|
<description>Enable the Influx (www.influxdata.com) Metrics. Further Configuration of the InfluxDB Instance
|
||||||
Necessary.</description>
|
Necessary.</description>
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="influxURL" type="text">
|
<parameter name="influxURL" type="text" groupName="influx">
|
||||||
<label>InfluxDB URL</label>
|
<label>URL</label>
|
||||||
<description>The URL of the InfluxDB Instance. Defaults to http://localhost:8086</description>
|
<description>The URL of the InfluxDB Instance. Defaults to http://localhost:8086</description>
|
||||||
<default>http://localhost:8086</default>
|
<default>http://localhost:8086</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="influxDB" type="text">
|
<parameter name="influxDB" type="text" groupName="influx">
|
||||||
<label>InfluxDB Database Name</label>
|
<label>Database Name</label>
|
||||||
<description>The Name of the Database to Use. Defaults to "openhab".</description>
|
<description>The Name of the Database to Use. Defaults to "openhab".</description>
|
||||||
<default>openhab</default>
|
<default>openhab</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="influxUsername" type="text">
|
<parameter name="influxUsername" type="text" groupName="influx">
|
||||||
<label>InfluxDB User Name</label>
|
<label>User Name</label>
|
||||||
<description>The InfluxDB User Name (No Default).</description>
|
<description>The InfluxDB User Name (No Default).</description>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="influxPassword" type="text">
|
<parameter name="influxPassword" type="text" groupName="influx">
|
||||||
<label>InfluxDB Password</label>
|
<label>Password</label>
|
||||||
<description>The InfluxDB Password (No Default).</description>
|
<description>The InfluxDB Password (No Default).</description>
|
||||||
<context>password</context>
|
<context>password</context>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="influxUpdateIntervalInSeconds" type="integer" unit="s" min="1">
|
<parameter name="influxUpdateIntervalInSeconds" type="integer" unit="s" min="1" groupName="influx">
|
||||||
<label>InfluxDB Update Interval in Seconds</label>
|
<label>Update Interval in Seconds</label>
|
||||||
<description>Controls How Often Metrics Are Exported to InfluxDB (in Seconds). Defaults to 300</description>
|
<description>Controls How Often Metrics Are Exported to InfluxDB (in Seconds). Defaults to 300</description>
|
||||||
<default>300</default>
|
<default>300</default>
|
||||||
</parameter>
|
</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-description:config-descriptions>
|
</config-description:config-descriptions>
|
||||||
|
|
Loading…
Reference in New Issue