created prometheus reports and /metrics

This commit is contained in:
Konstantinos Spyrou 2021-07-26 11:34:42 +00:00
parent 84df31c87a
commit 500c379b8c
7 changed files with 225 additions and 36 deletions

25
pom.xml
View File

@ -295,6 +295,31 @@
<version>2.26.0</version>
<scope>test</scope>
</dependency>
<!-- Enable micrometer >> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>2.1.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<version>2.1.18.RELEASE</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.7.2</version>
<scope>compile</scope>
</dependency>
<!-- << Enable micrometer -->
</dependencies>
<build>

View File

@ -60,11 +60,14 @@ public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.anonymous().disable()
http
.csrf().disable()
.authorizeRequests()
.regexMatchers("/actuator/.*").permitAll()
.regexMatchers("/metrics").permitAll()
.anyRequest().authenticated()
.and()
// .anonymous().disable()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint())
.and()

View File

@ -0,0 +1,39 @@
package eu.dnetlib.repo.manager.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.PublicMetricsAutoConfiguration;
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import java.util.Collection;
@Configuration
@EnableWebMvc
@Import({
EndpointAutoConfiguration.class,
PublicMetricsAutoConfiguration.class,
// HealthIndicatorAutoConfiguration.class
})
public class ActuatorConfig { // TODO: remove this with migration to Spring Boot 2
@Bean
@Autowired
public EndpointHandlerMapping endpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints) {
return new EndpointHandlerMapping(endpoints);
}
@Bean
@Autowired
public EndpointMvcAdapter metricsEndPoint(MetricsEndpoint delegate) {
return new EndpointMvcAdapter(delegate);
}
}

View File

@ -0,0 +1,55 @@
package eu.dnetlib.repo.manager.controllers;
import eu.dnetlib.repo.manager.service.PiWikService;
import io.micrometer.core.instrument.binder.jvm.DiskSpaceMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
import io.micrometer.core.instrument.binder.system.UptimeMetrics;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.exporter.common.TextFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
@RestController
@RequestMapping("/actuator/prometheus")
public class PrometheusController { // TODO: remove this with migration to Spring Boot 2
private final PiWikService piWikService;
@Autowired
public PrometheusController(PiWikService piWikService) {
this.piWikService = piWikService;
}
@RequestMapping(method = RequestMethod.GET, path = "", produces = MediaType.TEXT_PLAIN_VALUE)
public String getPiwikMetrics() {
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
registry.counter("total").increment(piWikService.getTotal());
registry.counter("validated").increment(piWikService.getValidated(true));
return registry.scrape(TextFormat.CONTENT_TYPE_004);
}
@RequestMapping(method = RequestMethod.GET, path = "metrics", produces = MediaType.TEXT_PLAIN_VALUE)
public String getMetrics() {
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
new JvmThreadMetrics().bindTo(registry);
new JvmGcMetrics().bindTo(registry);
new JvmMemoryMetrics().bindTo(registry);
new DiskSpaceMetrics(new File("/")).bindTo(registry);
new ProcessorMetrics().bindTo(registry); // metrics related to the CPU stats
new UptimeMetrics().bindTo(registry);
return registry.scrape(TextFormat.CONTENT_TYPE_004);
}
}

View File

@ -27,4 +27,8 @@ public interface PiWikService {
ResponseEntity<Object> markPiwikSiteAsValidated(String repositoryId) throws RepositoryServiceException;
PiwikInfo enableMetricsForRepository(String officialName, String repoWebsite, PiwikInfo piwikInfo) throws RepositoryServiceException;
Integer getTotal();
Integer getValidated(boolean validated);
}

View File

@ -67,9 +67,9 @@ public class PiWikServiceImpl implements PiWikService {
@Override
public PiwikInfo getPiwikSiteForRepo(String repositoryId) {
try{
try {
return new JdbcTemplate(dataSource).queryForObject(GET_PIWIK_SITE, new String[]{repositoryId}, new int[]{Types.VARCHAR}, piwikRowMapper);
}catch (EmptyResultDataAccessException e){
} catch (EmptyResultDataAccessException e) {
return null;
}
}
@ -86,59 +86,59 @@ public class PiWikServiceImpl implements PiWikService {
@Override
public List<PiwikInfo> getPiwikSitesForRepos(OrderByField orderByField, OrderByType orderByType, int from, int quantity, String searchField) {
try{
String finalizedQuery = GET_PIWIK_SITES + " where ("+
try {
String finalizedQuery = GET_PIWIK_SITES + " where (" +
" repositoryid ilike ? " +
" or siteid ilike ?" +
" or requestorname ilike ?" +
" or requestoremail ilike ?" +
" or comment ilike ?" +
" or repositoryname ilike ?"+
" or repositoryname ilike ?" +
" or country ilike ?"
+") order by "+orderByField + " " + orderByType + " offset ? limit ?";
+ ") order by " + orderByField + " " + orderByType + " offset ? limit ?";
return new JdbcTemplate(dataSource).query(finalizedQuery, preparedStatement -> {
preparedStatement.setString(1,"%"+searchField+"%");
preparedStatement.setString(2,"%"+searchField+"%");
preparedStatement.setString(3,"%"+searchField+"%");
preparedStatement.setString(4,"%"+searchField+"%");
preparedStatement.setString(5,"%"+searchField+"%");
preparedStatement.setString(6,"%"+searchField+"%");
preparedStatement.setString(7,"%"+searchField+"%");
preparedStatement.setInt(8,from);
preparedStatement.setInt(9,quantity);
preparedStatement.setString(1, "%" + searchField + "%");
preparedStatement.setString(2, "%" + searchField + "%");
preparedStatement.setString(3, "%" + searchField + "%");
preparedStatement.setString(4, "%" + searchField + "%");
preparedStatement.setString(5, "%" + searchField + "%");
preparedStatement.setString(6, "%" + searchField + "%");
preparedStatement.setString(7, "%" + searchField + "%");
preparedStatement.setInt(8, from);
preparedStatement.setInt(9, quantity);
}, piwikRowMapper);
}catch (EmptyResultDataAccessException e){
} catch (EmptyResultDataAccessException e) {
return null;
}
}
@Override
public int getPiwikSitesTotals(String searchField){
try{
String finalizedQuery = GET_PIWIK_SITES_TOTAL + " where ("+
public int getPiwikSitesTotals(String searchField) {
try {
String finalizedQuery = GET_PIWIK_SITES_TOTAL + " where (" +
" repositoryid ilike ? " +
" or siteid ilike ?" +
" or requestorname ilike ?" +
" or requestoremail ilike ?" +
" or comment ilike ?" +
" or repositoryname ilike ?"+
" or repositoryname ilike ?" +
" or country ilike ?)";
return new JdbcTemplate(dataSource).query(finalizedQuery, preparedStatement -> {
preparedStatement.setString(1,"%"+searchField+"%");
preparedStatement.setString(2,"%"+searchField+"%");
preparedStatement.setString(3,"%"+searchField+"%");
preparedStatement.setString(4,"%"+searchField+"%");
preparedStatement.setString(5,"%"+searchField+"%");
preparedStatement.setString(6,"%"+searchField+"%");
preparedStatement.setString(7,"%"+searchField+"%");
},rowMapper -> {
preparedStatement.setString(1, "%" + searchField + "%");
preparedStatement.setString(2, "%" + searchField + "%");
preparedStatement.setString(3, "%" + searchField + "%");
preparedStatement.setString(4, "%" + searchField + "%");
preparedStatement.setString(5, "%" + searchField + "%");
preparedStatement.setString(6, "%" + searchField + "%");
preparedStatement.setString(7, "%" + searchField + "%");
}, rowMapper -> {
rowMapper.next();
return rowMapper.getInt("totals");
});
}catch (EmptyResultDataAccessException e){
} catch (EmptyResultDataAccessException e) {
return 0;
}
}
@ -146,8 +146,8 @@ public class PiWikServiceImpl implements PiWikService {
@Override
@PreAuthorize("hasAuthority('SUPER_ADMINISTRATOR') or hasAuthority('CONTENT_PROVIDER_DASHBOARD_ADMINISTRATOR')")
public ResponseEntity<Object> approvePiwikSite(String repositoryId) {
new JdbcTemplate(dataSource).update(APPROVE_PIWIK_SITE, new Object[] {repositoryId}, new int[] {Types.VARCHAR});
return new ResponseEntity<>("OK",HttpStatus.OK);
new JdbcTemplate(dataSource).update(APPROVE_PIWIK_SITE, new Object[]{repositoryId}, new int[]{Types.VARCHAR});
return new ResponseEntity<>("OK", HttpStatus.OK);
}
@Override
@ -175,7 +175,7 @@ public class PiWikServiceImpl implements PiWikService {
LOGGER.error("Error while sending email to administrator or user about the enabling of metrics", e);
emailUtils.reportException(e);
}
return new ResponseEntity<>("OK",HttpStatus.OK);
return new ResponseEntity<>("OK", HttpStatus.OK);
}
@Override
@ -188,7 +188,7 @@ public class PiWikServiceImpl implements PiWikService {
+ URLEncoder.encode(repoWebsite, "UTF-8");
Map map = new ObjectMapper().readValue(new URL(URL), Map.class);
String siteId = null;
if(map.get("value")!=null) {
if (map.get("value") != null) {
siteId = map.get("value").toString();
}
piwikInfo.setSiteId(siteId);
@ -217,5 +217,14 @@ public class PiWikServiceImpl implements PiWikService {
return piwikInfo;
}
@Override
public Integer getTotal() {
return new JdbcTemplate(dataSource).queryForObject(GET_PIWIK_SITES_TOTAL, new Object[]{}, Integer.class);
}
@Override
public Integer getValidated(boolean validated) {
String finalizedQuery = GET_PIWIK_SITES_TOTAL + " where validated = ?";
return new JdbcTemplate(dataSource).queryForObject(finalizedQuery, new Object[]{validated}, Integer.class);
}
}

View File

@ -0,0 +1,54 @@
package metrics;
import eu.dnetlib.repo.manager.controllers.PrometheusController;
import eu.dnetlib.repo.manager.service.PiWikService;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
@Component
public class PrometheusTest {
private static final int TOTAL = 10;
private static final int VALIDATED = 8;
@Autowired
@Mock
PiWikService piWikService;
@Autowired
@InjectMocks
private PrometheusController prometheusController;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(piWikService.getTotal()).thenReturn(TOTAL);
when(piWikService.getValidated(true)).thenReturn(VALIDATED);
when(piWikService.getValidated(false)).thenReturn(TOTAL - VALIDATED);
}
@Test
public void testMetrics() {
String report = prometheusController.getMetrics();
assertTrue(report.startsWith("#"));
System.out.println(report);
}
@Test
public void testPiwikMetrics() {
assertTrue(piWikService.getValidated(false).equals(TOTAL - VALIDATED));
String report = prometheusController.getPiwikMetrics();
assertTrue(report.contains("total_total " + TOTAL));
assertTrue(report.contains("validated_total " + VALIDATED));
System.out.println(report);
}
}