* [io.metrics] Fix MetricsService breaking REST API #10640 Signed-off-by: Robert Bach <openhab@mortalsilence.net>
This commit is contained in:
parent
9441cfffe8
commit
582ef280e5
|
@ -46,7 +46,7 @@ For a start, the following formats are supported:
|
|||
### Prometheus
|
||||
|
||||
Once the IO addon is installed, the Prometheus endpoint will be available under:
|
||||
_<openhab_host>:8080/metrics/prometheus_
|
||||
_<openhab_host>:8080/rest/metrics/prometheus_
|
||||
|
||||
Refer to the [Prometheus](https://prometheus.io/) documentation on how to setup a Prometheus instance and add a scrape configuration. A typical scrape config could look like this (excerpt from `/etc/prometheus/prometheus.yml`):
|
||||
|
||||
|
@ -55,7 +55,7 @@ scrape_configs:
|
|||
- job_name: 'openhab'
|
||||
scrape_interval: 1m
|
||||
scheme: http
|
||||
metrics_path: /metrics/prometheus
|
||||
metrics_path: /rest/metrics/prometheus
|
||||
static_configs:
|
||||
- targets:
|
||||
- 'openhab.local:8080'
|
||||
|
|
|
@ -74,5 +74,11 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.core.bundles</groupId>
|
||||
<artifactId>org.openhab.core.io.rest</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -12,7 +12,10 @@
|
|||
*/
|
||||
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;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -23,8 +26,14 @@ import javax.ws.rs.core.MediaType;
|
|||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.auth.Role;
|
||||
import org.openhab.core.config.core.ConfigurableService;
|
||||
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.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Modified;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JSONRequired;
|
||||
|
@ -43,24 +52,27 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* * The {@link MetricsRestController} class implements the REST endpoints for all pull based monitoring systems.
|
||||
* The {@link MetricsRestController} class implements the REST endpoints for all pull based monitoring systems.
|
||||
*
|
||||
* @author Robert Bach - Initial contribution
|
||||
*/
|
||||
@Component(immediate = true, service = MetricsRestController.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + MetricsService.METRICS_APP_NAME + ")")
|
||||
@Path("")
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + RESTConstants.JAX_RS_NAME + ")")
|
||||
@Path(MetricsRestController.PATH_METRICS)
|
||||
@JSONRequired
|
||||
@RolesAllowed({ Role.USER, Role.ADMIN })
|
||||
@Tag(name = MetricsRestController.PATH_METRICS)
|
||||
@NonNullByDefault
|
||||
@ConfigurableService(category = "io", label = "Metrics service", description_uri = "io:metrics")
|
||||
public class MetricsRestController {
|
||||
private final Logger logger = LoggerFactory.getLogger(MetricsRestController.class);
|
||||
public static final String PATH_METRICS = "metrics";
|
||||
private @Nullable CompositeMeterRegistry meterRegistry = null;
|
||||
private final PrometheusMeterRegistry prometheusMeterRegistry = new PrometheusMeterRegistry(
|
||||
PrometheusConfig.DEFAULT);
|
||||
private final Set<MetricsExporter> metricsExporters = new HashSet<>();
|
||||
private @Nullable MetricsConfiguration config;
|
||||
|
||||
@GET
|
||||
@Path("/prometheus")
|
||||
|
@ -79,5 +91,29 @@ public class MetricsRestController {
|
|||
meterRegistry = meterRegistryProvider.getOHMeterRegistry();
|
||||
Objects.requireNonNull(meterRegistry).add(prometheusMeterRegistry);
|
||||
logger.debug("Core metrics registry retrieved and Prometheus registry added successfully.");
|
||||
updateMeterRegistry();
|
||||
}
|
||||
|
||||
@Activate
|
||||
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());
|
||||
updateConfig(configuration);
|
||||
updateMeterRegistry();
|
||||
}
|
||||
|
||||
@Modified
|
||||
protected synchronized void modified(Map<@Nullable String, @Nullable Object> configuration) {
|
||||
updateConfig(configuration);
|
||||
}
|
||||
|
||||
private void updateConfig(@Nullable Map<@Nullable String, @Nullable Object> configuration) {
|
||||
this.config = new Configuration(configuration).as(MetricsConfiguration.class);
|
||||
logger.debug("Configuration: {}", this.config);
|
||||
this.metricsExporters.forEach(e -> e.updateExporterState(config));
|
||||
}
|
||||
|
||||
private void updateMeterRegistry() {
|
||||
this.metricsExporters.forEach(e -> e.setMeterRegistry(meterRegistry));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.core.Application;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.config.core.ConfigurableService;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.io.monitor.MeterRegistryProvider;
|
||||
import org.openhab.io.metrics.exporters.InfluxMetricsExporter;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Deactivate;
|
||||
import org.osgi.service.component.annotations.Modified;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
|
||||
|
||||
/**
|
||||
* The {@link MetricsService} class implements the central component controlling the different metric endpoints/syncers.
|
||||
*
|
||||
* @author Robert Bach - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = MetricsService.class)
|
||||
@ConfigurableService(category = "io", label = "Metrics service", description_uri = "io:metrics")
|
||||
public class MetricsService {
|
||||
public static final String METRICS_APP_NAME = "Metrics";
|
||||
public static final String ROOT = "/metrics";
|
||||
private final Logger logger = LoggerFactory.getLogger(MetricsService.class);
|
||||
private @Nullable ServiceRegistration<Application> restService = null;
|
||||
private @Nullable MetricsConfiguration config;
|
||||
@Reference
|
||||
protected @NonNullByDefault({}) MetricsRestController metrics;
|
||||
private Set<MetricsExporter> metricsExporters = new HashSet<>();
|
||||
private @Nullable CompositeMeterRegistry meterRegistry = null;
|
||||
|
||||
@Activate
|
||||
protected void activate(Map<@Nullable String, @Nullable Object> configuration) {
|
||||
MetricsRestApplication app = new MetricsRestApplication();
|
||||
BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
|
||||
restService = context.registerService(Application.class, app, getServiceProperties());
|
||||
logger.info("Metrics service available under {}.", ROOT);
|
||||
metricsExporters.add(new InfluxMetricsExporter());
|
||||
updateConfig(configuration);
|
||||
updateMeterRegistry();
|
||||
}
|
||||
|
||||
@Modified
|
||||
protected synchronized void modified(Map<@Nullable String, @Nullable Object> configuration) {
|
||||
updateConfig(configuration);
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
protected void deactivate() {
|
||||
if (restService != null) {
|
||||
Objects.requireNonNull(restService).unregister();
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<@Nullable String, @Nullable String> getServiceProperties() {
|
||||
Dictionary<@Nullable String, @Nullable String> dict = new Hashtable<>();
|
||||
dict.put(JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE, ROOT);
|
||||
return dict;
|
||||
}
|
||||
|
||||
@JaxrsName(METRICS_APP_NAME)
|
||||
private class MetricsRestApplication extends Application {
|
||||
@NonNullByDefault({})
|
||||
@Override
|
||||
public Set<Object> getSingletons() {
|
||||
return Set.of(metrics);
|
||||
}
|
||||
}
|
||||
|
||||
@Reference
|
||||
public void setMeterRegistryProvider(MeterRegistryProvider meterRegistryProvider) {
|
||||
meterRegistry = meterRegistryProvider.getOHMeterRegistry();
|
||||
updateMeterRegistry();
|
||||
}
|
||||
|
||||
private void updateConfig(@Nullable Map<@Nullable String, @Nullable Object> configuration) {
|
||||
this.config = new Configuration(configuration).as(MetricsConfiguration.class);
|
||||
logger.debug("Configuration: {}", this.config);
|
||||
this.metricsExporters.forEach(e -> e.updateExporterState(config));
|
||||
}
|
||||
|
||||
private void updateMeterRegistry() {
|
||||
this.metricsExporters.forEach(e -> e.setMeterRegistry(meterRegistry));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue