[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
|
@ -34,8 +34,9 @@ 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 |
|
||||
| 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
|
||||
|
||||
|
@ -74,13 +75,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 |
|
||||
|
||||
### 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
|
||||
|
||||
The metrics service was implemented using [Micrometer](https://micrometer.io), which supports a number of [monitoring systems](https://micrometer.io/docs)
|
||||
|
|
|
@ -44,6 +44,18 @@
|
|||
</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>
|
||||
|
|
|
@ -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 + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
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>
|
||||
|
|
Loading…
Reference in New Issue