add micrometer to collect metrics for prometheus

This commit is contained in:
Alexios Symeonidis 2024-08-01 12:00:17 +03:00
parent c1baa3a631
commit af13405065
8 changed files with 83 additions and 2 deletions

15
pom.xml
View File

@ -163,6 +163,21 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- Add dump schema dependency -->
<dependency>
<groupId>eu.dnetlib.dhp</groupId>

View File

@ -2,8 +2,10 @@ package eu.openaire.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy
public class OpenaireRestApiApplication {
public static void main(String[] args) {

View File

@ -0,0 +1,50 @@
package eu.openaire.api.config.metrics;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class MetricsAspect {
private final MeterRegistry meterRegistry;
@Autowired
public MetricsAspect(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
/***
* Advice for timing methods annotated with {@link Timed}.
*/
@Around("@annotation(io.micrometer.core.annotation.Timed)")
public Object timeAnnotatedMethods(ProceedingJoinPoint joinPoint) throws Throwable {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = method.getName();
String timerName = className + "." + methodName;
Timer.Sample sample = Timer.start(meterRegistry);
try {
return joinPoint.proceed();
} finally {
sample.stop(Timer.builder(timerName)
.tags("application", "openaire-search-api")
.tags("class", className)
.tags("method", methodName)
.publishPercentiles(0.5, 0.95)
.register(meterRegistry));
}
}
}

View File

@ -11,6 +11,7 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.DatasourceMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -37,6 +38,7 @@ public class DataSourceService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public Datasource getById(String id) {
var doc = solrRepository.getById(id);
@ -48,6 +50,7 @@ public class DataSourceService {
}
@SneakyThrows
@Timed
public SearchResponse<Datasource> search(DataSourceRequest request) {
SolrQueryParams solrQueryParams = dataSourceRequestMapper.toSolrQuery(request);

View File

@ -11,6 +11,7 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.OrganizationMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -37,6 +38,7 @@ public class OrganizationService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public Organization getById(String id) {
var doc = solrRepository.getById(id);
@ -48,6 +50,7 @@ public class OrganizationService {
}
@SneakyThrows
@Timed
public SearchResponse<Organization> search(OrganizationRequest request) {
SolrQueryParams solrQueryParams = organizationRequestMapper.toSolrQuery(request);

View File

@ -11,6 +11,7 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.ProjectMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -37,6 +38,7 @@ public class ProjectService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public Project getById(String id) {
var doc = solrRepository.getById(id);
@ -48,6 +50,7 @@ public class ProjectService {
}
@SneakyThrows
@Timed
public SearchResponse<Project> search(ProjectRequest request) {
SolrQueryParams solrQueryParams = projectRequestMapper.toSolrQuery(request);

View File

@ -11,6 +11,7 @@ import eu.openaire.api.mappers.response.ResponseResultsMapper;
import eu.openaire.api.mappers.response.entities.ResearchProductMapper;
import eu.openaire.api.repositories.SolrRepository;
import eu.openaire.api.solr.SolrQueryParams;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.logging.log4j.LogManager;
@ -37,6 +38,7 @@ public class ResearchProductService {
private final Logger log = LogManager.getLogger(this.getClass());
@SneakyThrows
@Timed
public GraphResult getById(String id) {
var doc = solrRepository.getById(id);
@ -49,6 +51,7 @@ public class ResearchProductService {
}
@SneakyThrows
@Timed
public SearchResponse<GraphResult> search(ResearchProductsRequest request) {
SolrQueryParams solrQueryParams = researchProductsRequestMapper.toSolrQuery(request);

View File

@ -15,8 +15,10 @@ server.error.include-stacktrace=never
# Enable the health endpoint
management.endpoint.health.enabled=true
# Expose the health endpoint
management.endpoints.web.exposure.include=health,info
# Expose health, info and metrics endpoint
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true
# Customize health endpoint settings
management.endpoint.health.show-details=always