Publikacja własnych metryk z użyciem Micrometer do Prometheus

Publikacja metryk z użyciem Micrometer do Prometheus

Micrometer to zestaw bibliotek javy które pozwalają na publikacje rozmaitych metryk do różnych narzędzi tj. jak np. Prometheus. Prometheus zaś to ekosystem krótego celem jest monitoring systemów informatycznych. Jedną z kluczowych cech Prometheusa jest to, że zbiera on metryki z monitorowanych systemów, za pomocą protokołu HTTP. W tym artykule napiszemy aplikację w Spring Boot i podepniemy do niej monitoring. Metryki wyślemy do Prometheusa. Dodajmy następujące zależności:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
 
<dependency>
	<groupId>io.micrometer</groupId>
	<artifactId>micrometer-registry-prometheus</artifactId>
	<scope>runtime</scope>
</dependency>

Pierwsza z zależności zawiera wsparcie dla micrometer-core:

io.micrometer:micrometer-core

natomiast druga z zależności daje wsparcie dla Prometheusa. Dodajemy zatem do konfiguracji Actuatora w pliku konfiguracyjnym application.properties endpoint prometheus:

management.endpoints.web.exposure.include=health,info,prometheus

Przykładowe metryki dostępne są teraz pod adresem:

http://localhost:8080/actuator/prometheus

jedną z nich jest np:

application_ready_time_seconds{main_application_class="pl.javaleader.monitoringmicrometer.MonitoringMicrometerApplication",} 4.671

Utwórzmy własną metrykę! Na początek dodajemy wsparcie dla programowania aspektowego:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

skonfigurujmy beana timedAspect:

@Configuration
public class ConfigurationBeans {
    @Bean
    public TimedAspect timedAspect(MeterRegistry registry) {
        return new TimedAspect(registry);
    }
}

Dodajemy przykładowy serwis:

@Service
public class SendEmail {
    @Timed(value = "email.delivery.time", description = "Time taken to send email")
    public void sendEmail(int amount) {
        for (int i = 0; i < amount; i++) {
            try {
                sleep(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

oraz klasę RestControllera:

@RestController
public class EmailController {
 
    SendEmail sendEmail;
 
    public EmailController(SendEmail sendEmail) {
        this.sendEmail = sendEmail;
    }
 
    @GetMapping("/send-email")
    public void sendEmail(@RequestParam int emailAmount) {
        sendEmail.sendEmail(emailAmount);
    }
}

Nasza nowa metryka widoczna jest pod endpointem:

http://localhost:8080/actuator/prometheus

przykładowy wynik:

# TYPE email_delivery_time_seconds summary
email_delivery_time_seconds_count{class="pl.javaleader.monitoringmicrometer.service.SendEmail",exception="none",method="sendEmail",} 16.0
email_delivery_time_seconds_sum{class="pl.javaleader.monitoringmicrometer.service.SendEmail",exception="none",method="sendEmail",} 6.9005318
# HELP email_delivery_time_seconds_max Time taken to send email
# TYPE email_delivery_time_seconds_max gauge
email_delivery_time_seconds_max{class="pl.javaleader.monitoringmicrometer.service.SendEmail",exception="none",method="sendEmail",} 0.149322

Wyślijmy te dane do Prometheusa! W tym celu z użyciem dockera pobierzemy obraz Prometheusa:

Plik konfiguracyjny prometheus.yml:

global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).
 
scrape_configs:
  - job_name: 'spring boot scrape'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['host.docker.internal:8080']

Plik docker-compose.yml:

version: "3"
 
services:
  prometheus:
    image: prom/prometheus:v2.21.0
    network_mode: host
    ports:
      - 9000:9090
    volumes:
      - prometheus_data:/prometheus
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command: 
      - "--config.file=/etc/prometheus/prometheus.yml"
    extra_hosts:
      - "host.docker.internal:host-gateway"
 
volumes:
  prometheus_data: {}

uruchamiamy poleceniem:

docker compose up

Pod adresem:

http://127.0.0.1:9090

dostępna jest konsola Prometheusa, przejdźmy do zakładki ./target gdzie widać prawidłowe połączenie do parsowania z ang. „scrapowania” dostępnych metryk pod endpointem :

http://localhost:8080/actuator/prometheus

przykładowy wydruk z monitoringu naszej nowo dodanej metryki – „email.delivery.time” – monitorujemy ile razy została wykonana metoda – „sendEmail„:

Zobacz kod na GitHubie i zapisz się na bezpłatny newsletter!

.


Leave a comment

Your email address will not be published.


*