sábado, 5 de diciembre de 2020

Apache Camel: Crea tu propia métrica con Micrometer

Hoy vamos a ver un post muy completo sobre Apache Camel y Micrometer, y como podemos presentar distintas métricas en Prometheus y Grafana. Pero en el que no podremos hacer nada si no es por el uso de Spring Actuator. Antes de empezar a indicar como podemos lograrlo, vamos a dar una pequeña introducción a cada uno de los componentes para tener un idea de que son y para que sirven. 

Spring Actuator es un módulo más de Spring Boot que habilita la creación de endpoints asociados a nuestra aplicación que nos darán información de la aplicación, su estado y métrica sobre la misma. 

Micrometer es un software que nos permite enviar información y métrica de una aplicación a otro software de métrica especializado. La idea principal se emplea en utilizar Micrometer como usariamos si usaramos una API neutra para la generación de métrica. Y a través de la cual nos podremos comunicar facilmente con múltitud de otros softwares dedicados exclusivamente a la métrica, como puede ser Prometheus, Elastic, Graphite y muchos más. 

Prometheus es un importante software especializado en la monitorización y generación de alertas. Es una excelente herramienta para el registro de series de tiempo numéricas. Especializado en la supervisión de servicios dinámicos, esta diseñado para dar confianza sobre el estado de la aplicación y el mantenimiento predictivo. 

Y por último Grafana es otro software libre que permite la visualización de métrica. Permitiendo crear cuadros de mando y gráficos a partir de múltiples fuentes como Prometheus, Graphite, InfluxDB, etc. 

Teniendo ya los conceptos más claros, vamos a ver como podemos llevarlo a cabo. Lo primero será añadir las dependencias necesarias. Necesitaremos la librería para habilitar Spring Actuator, la librería para habilitar el componente de Micrometer en Apache Camel y la librería para permitir la exportación a Prometheus a través de Micrometer. 

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
      <groupId>org.apache.camel.springboot</groupId>
      <artifactId>camel-micrometer-starter</artifactId>
</dependency>
<dependency>
      <groupId>io.micrometer</groupId>
      <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

Ya hemos hablado anteriormente, que Spring Actuator nos habilita diferentes endpoints. Por defecto nos habilita el propio '/actuator', pero también '/info' y '/health'. A través del fichero de configuración de Spring le debemos indicar que habilite también el endpoint para Prometheus, de la siguiente forma.

#SPRING CONFIGURATION
management.endpoints.web.exposure.include=info, health, prometheus

Si arrancamos la aplicación ahora, y accedemos a la URL http://localhost:8080/actuator/prometheus veremos distintas métricas disponibles para Prometheus. Y esto es importante, porque Prometheus leerá toda esta información que le estamos dando a través de dicha URL. 

Y aunque no entraremos al detalle en la configuración de Prometheus y Grafana, los cuales podemos arrancar los dos fácilmente a través de un docker-compose. Para ver la importancia de la URL de Spring Actuator, veremos un ejemplo de como podemos configurar Prometheus para que pueda leer toda la métrica asociada a una aplicación concreta. Esto lo haremos a través del fichero de configuración prometheus.yml. 

scrape_configs:
  - job_name: 'prometheus'
    scrape_interval: 1m
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'camel-app'
    scrape_interval: 1m
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['localhost:8080']
  - job_name: 'grafana'
    scrape_interval: 1m
    metrics_path: '/metrics'
    static_configs:
      - targets: ['localhost:3000']

Una vez arrancado Prometheus, si accediésemos a la pantalla principal veríamos un indicador de si los sistemas estan levantados y hay conexión con ellos. 

Ahora viene el apartado principal de este post, la creación de nuestras propias métricas gracias a Micrometer. Y es que este pone a nuestra disposición tres opciones de crear métrica, estas son: 

  • Counter: Nos permitirá contar el número de invocaciones a un servicio. 
  • Timer: Nos permitirá medir el tiempo de ejecución de determinadas operaciones. 
  • Summary: Nos permite añadir los valores que indiquemos. 
Por tanto, para probar su eficacia vamos a crear un mock, que nos permita contar el número de veces que va a ser invocado:

@Component
public class MockRouter extends RouteBuilder {
 @Override
 public void configure() throws Exception {
  restConfiguration().component("servlet").bindingMode(RestBindingMode.json);

  rest("/mockCounter").get().produces(MediaType.APPLICATION_JSON_VALUE).route()
  .to("micrometer:counter:simpleCounterMock").setBody(simple("{\"msg\":\"Hello World\"}")).unmarshal().json();
 }
}

En el código anterior, hemos creado un counter a través del componente de Micrometer denominado simpleCounterMock. Y si accedemos a la URL de Prometheus que nos proporciona Spring Actuator, podremos ver información sobre el mismo:

# HELP simpleCounterMock_total  
# TYPE simpleCounterMock_total counter
simpleCounterMock_total{camelContext="camel-1",} 3.0

Ahora que estamos generando métricas, el siguiente paso será poder visualizarlas, y para eso usaremos Grafana. Dentro de Grafana el primer paso será crear un Data Source que tenga como origen Prometheus. 


El siguiente será crear un dashboard a través del cual poder visualizar los datos. En el dashboard tendremos que indicar la fuente de los datos y la métrica que queremos visualizar. Para nuestro ejemplo realizaremos dos tipos de gráficas. La primera que nos permitirá ver el incremento del contador y la segunda que será simplemente el contador. Si os fijais, en la parte inferior de cada gráfico viene la fórmula utilizada. La generación de las gráficas en función del uso de las formulas esta fuera del alcance de este post. 


Ahora veremos como podemos realizar por ejemplo una métrica que nos mida el tiempo de una determinada operación. Para este caso deberemos invocar a Micrometer dos veces, la primera vez antes de empezar a medir el tiempo y la segunda vez para indicar que deje de contar. 

rest("/mockTimer").get().produces(MediaType.APPLICATION_JSON_VALUE).route()
 .to("micrometer:timer:simpleTimerMock?action=start")
 .delay(1000).setBody(simple("{\"msg\":\"Hello World\"}"))
 .to("micrometer:timer:simpleTimerMock?action=stop").unmarshal().json();

El siguiente paso será generar otros dashboards en Grafana que nos permitan visualizar las métricas generadas. 


Por último indicar que desde el mismo Prometheus también puedes hacer uso de dichas fórmulas y visualizar las métricas. 


Espero que haya sido un post útil, que haya permitido dar a conocer importantes herramientas a la hora del manejo de métrica. Y a la vez, aprender a generar nuestras propias métricas que nos ayuden en el mantenimiento y control de nuestras aplicaciones. 

Como siempre, todo el código lo puedes ver aquí

No hay comentarios:

Publicar un comentario