kpi_metrics_separated #3

Merged
michele.artini merged 4 commits from kpi_metrics_separated into master 2021-11-30 14:10:36 +01:00
16 changed files with 107 additions and 40 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;
@ -16,6 +17,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2
@EnableCaching
@EnableScheduling
@ComponentScan(basePackages = "eu.dnetlib")
public class MainApplication extends AbstractDnetApp {
public static void main(final String[] args) {

View File

@ -49,7 +49,7 @@ public class MockSecurityConfig extends WebSecurityConfigurerAdapter {
.hasAnyRole(OpenOrgsConstants.VALID_ROLES)
.antMatchers("/registration_api/**")
.hasRole(OpenOrgsConstants.NOT_AUTORIZED_ROLE)
.antMatchers("/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/dbmodel/**")
.antMatchers("/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/kpis", "/dbmodel/**")
.permitAll()
.antMatchers("/oa_api/**")
.permitAll()

View File

@ -62,7 +62,7 @@ public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter {
.hasAnyRole(OpenOrgsConstants.VALID_ROLES)
.antMatchers("/registration_api/**")
.hasRole(OpenOrgsConstants.NOT_AUTORIZED_ROLE)
.antMatchers("/", "/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/dbmodel/**")
.antMatchers("/", "/common/**", "/resources/**", "/webjars/**", "/metrics", "/health", "/kpis", "/dbmodel/**")
.permitAll()
.antMatchers("/oa_api/**")
.hasIpAddress(openaireApiValidSubnet)

View File

@ -7,8 +7,8 @@ import eu.dnetlib.common.metrics.MetricInfo;
import eu.dnetlib.organizations.repository.OrganizationRepository;
import eu.dnetlib.organizations.utils.OrganizationStatus;
@Component("valid_organizations_total")
public class ValidOrganizationsMetric extends MetricInfo {
@Component("openorgs_valid_organizations")
public class ValidOrganizationsMetric implements MetricInfo {
@Autowired
private OrganizationRepository organizationRepository;

View File

@ -0,0 +1,32 @@
package eu.dnetlib.common.metrics;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
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.ResponseBody;
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(@RequestHeader(value = "Accept", required = false, defaultValue = "") final String accept) {
final String contentType = TextFormat.chooseContentType(accept);
final String result = metricUtils.output(contentType);
return ResponseEntity.ok()
.header(CONTENT_TYPE, contentType)
.body(result);
}
}

View File

@ -1,34 +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;
import io.micrometer.core.instrument.Metrics;
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());
Metrics.gauge(getBeanName(), this, o -> obtainValue());
}
double obtainValue();
}

View File

@ -0,0 +1,56 @@
package eu.dnetlib.common.metrics;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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 {
@Autowired(required = false)
private Map<String, MetricInfo> kpiMetrics;
private static final Log log = LogFactory.getLog(MetricUtils.class);
@PostConstruct
public void registerToMainEndpoint() {
if (kpiMetrics != null) {
kpiMetrics.forEach((k, v) -> Metrics.gauge(k, v, o -> o.obtainValue()));
log.info("KPI METRICS REGISTERED: " + StringUtils.join(kpiMetrics.keySet(), ", "));
}
}
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, Collections.enumeration(samples));
return writer.toString();
} catch (final IOException e) {
// This actually never happens since StringWriter::write() doesn't throw any IOException
throw new RuntimeException("Writing metrics failed", e);
}
}
}

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;