/kpis metrics endpoint

This commit is contained in:
Michele Artini 2021-11-29 13:37:27 +01:00
parent e0a3e6a14f
commit e127a7e73c
14 changed files with 52 additions and 60 deletions

View File

@ -4,6 +4,7 @@ import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
@ -25,6 +26,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableElasticsearchRepositories(basePackageClasses = {
Event.class, Notification.class
})
@ComponentScan(basePackages = "eu.dnetlib")
public class LiteratureBrokerServiceConfiguration extends AbstractElasticsearchConfiguration {
@Autowired

View File

@ -4,6 +4,7 @@ import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
@ -25,6 +26,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableElasticsearchRepositories(basePackageClasses = {
Event.class, Notification.class
})
@ComponentScan(basePackages = "eu.dnetlib")
public class BrokerConfiguration extends AbstractElasticsearchConfiguration {
@Autowired

View File

@ -3,6 +3,7 @@ package eu.dnetlib.organizations;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import eu.dnetlib.common.app.AbstractDnetApp;
@ -12,10 +13,11 @@ import springfox.documentation.service.ApiInfo;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication(scanBasePackages = "eu.dnetlib")
@SpringBootApplication
@EnableSwagger2
@EnableCaching
@EnableScheduling
@ComponentScan(basePackages = "eu.dnetlib")
public class MainApplication extends AbstractDnetApp {
public static void main(final String[] args) {

View File

@ -8,16 +8,13 @@ import eu.dnetlib.organizations.repository.OrganizationRepository;
import eu.dnetlib.organizations.utils.OrganizationStatus;
@Component("valid_organizations_total")
public class ValidOrganizationsMetric extends MetricInfo {
public class ValidOrganizationsMetric implements MetricInfo {
@Autowired
private OrganizationRepository organizationRepository;
@Override
public double obtainValue() {
System.out.println("xxxxxxxxxxxxxx");
return organizationRepository.countByStatus(OrganizationStatus.approved.toString());
}

View File

@ -1,31 +1,30 @@
package eu.dnetlib.organizations.controller;
package eu.dnetlib.common.metrics;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import eu.dnetlib.common.metrics.MetricUtils;
import io.prometheus.client.exporter.common.TextFormat;
@Controller
public class KpiMetricsController {
@Autowired
private MetricUtils metricUtils;
@ResponseBody
@RequestMapping(value = "/kpis", method = RequestMethod.GET, produces = "*/*")
public ResponseEntity<String> kpiMetrics(
@RequestParam(value = "name[]", required = false, defaultValue = "") final Set<String> name,
@RequestHeader(value = "Accept", required = false, defaultValue = "") final String accept) {
public ResponseEntity<String> kpiMetrics(@RequestHeader(value = "Accept", required = false, defaultValue = "") final String accept) {
final String contentType = TextFormat.chooseContentType(accept);
final String result = MetricUtils.output(name, contentType);
final String result = metricUtils.output(contentType);
return ResponseEntity.ok()
.header(CONTENT_TYPE, contentType)
.body(result);

View File

@ -1,32 +1,7 @@
package eu.dnetlib.common.metrics;
import javax.annotation.PostConstruct;
public abstract interface MetricInfo {
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanNameAware;
public abstract class MetricInfo implements BeanNameAware {
private static final Log log = LogFactory.getLog(MetricInfo.class);
private String beanName;
abstract public double obtainValue();
public String getBeanName() {
return beanName;
}
@Override
public void setBeanName(final String beanName) {
this.beanName = beanName;
}
@PostConstruct
public void register() {
log.info("Prometheus - new metric registered: " + getBeanName());
MetricUtils.register(beanName, this);
}
double obtainValue();
}

View File

@ -3,28 +3,43 @@ package eu.dnetlib.common.metrics;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Set;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Gauge;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import io.micrometer.core.instrument.Metrics;
import io.prometheus.client.Collector.MetricFamilySamples;
import io.prometheus.client.GaugeMetricFamily;
import io.prometheus.client.exporter.common.TextFormat;
@Component
public class MetricUtils {
private static final CompositeMeterRegistry meterRegistry = new CompositeMeterRegistry();
private static final CollectorRegistry collectorRegistry = new CollectorRegistry(true);
@Autowired(required = false)
private Map<String, MetricInfo> kpiMetrics;
public static MetricInfo register(final String name, final MetricInfo metric) {
final MetricInfo meter = meterRegistry.gauge(name, metric, MetricInfo::obtainValue);
Gauge.build(name, name).register(collectorRegistry);
return meter;
@PostConstruct
public void registerToMainEndpoint() {
if (kpiMetrics != null) {
kpiMetrics.forEach((k, v) -> Metrics.gauge(k, v, o -> o.obtainValue()));
}
}
public static String output(final Set<String> metricsToInclude, final String contentType) {
public String output(final String contentType) {
try {
final List<MetricFamilySamples> samples = new ArrayList<>();
if (kpiMetrics != null) {
kpiMetrics.forEach((k, v) -> samples.add(new GaugeMetricFamily(k, "", v.obtainValue())));
}
final Writer writer = new StringWriter();
TextFormat.writeFormat(contentType, writer, collectorRegistry.filteredMetricFamilySamples(metricsToInclude));
TextFormat.writeFormat(contentType, writer, Collections.enumeration(samples));
return writer.toString();
} catch (final IOException e) {
// This actually never happens since StringWriter::write() doesn't throw any IOException

View File

@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
import eu.dnetlib.common.metrics.MetricInfo;
@Component("provide_broker_last_metrics_updater_run_timestamp_seconds")
public class LastUpdateMetric extends MetricInfo {
public class LastUpdateMetric implements MetricInfo {
@Autowired
private MetricsCacheUtils metricsCacheUtils;

View File

@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
import eu.dnetlib.common.metrics.MetricInfo;
@Component("provide_broker_datasources_with_events")
public class TotalDatasourcesWithEventsMetric extends MetricInfo {
public class TotalDatasourcesWithEventsMetric implements MetricInfo {
@Autowired
private MetricsCacheUtils metricsCacheUtils;

View File

@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
import eu.dnetlib.common.metrics.MetricInfo;
@Component("provide_broker_datasources_with_subscriptions")
public class TotalDatasourcesWithSubscriptionsMetric extends MetricInfo {
public class TotalDatasourcesWithSubscriptionsMetric implements MetricInfo {
@Autowired
private MetricsCacheUtils metricsCacheUtils;

View File

@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
import eu.dnetlib.common.metrics.MetricInfo;
@Component("provide_broker_events")
public class TotalEventsMetric extends MetricInfo {
public class TotalEventsMetric implements MetricInfo {
@Autowired
private MetricsCacheUtils metricsCacheUtils;

View File

@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
import eu.dnetlib.common.metrics.MetricInfo;
@Component("provide_broker_notifications")
public class TotalNotificationsMetric extends MetricInfo {
public class TotalNotificationsMetric implements MetricInfo {
@Autowired
private MetricsCacheUtils metricsCacheUtils;

View File

@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
import eu.dnetlib.common.metrics.MetricInfo;
@Component("provide_broker_subscribers")
public class TotalSubscribersMetric extends MetricInfo {
public class TotalSubscribersMetric implements MetricInfo {
@Autowired
private MetricsCacheUtils metricsCacheUtils;

View File

@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
import eu.dnetlib.common.metrics.MetricInfo;
@Component("provide_broker_subscriptions")
public class TotalSubscriptionsMetric extends MetricInfo {
public class TotalSubscriptionsMetric implements MetricInfo {
@Autowired
private MetricsCacheUtils metricsCacheUtils;