APM con Spring Boot, Micrometer y Prometheus/Grafana

ANDERSEN AIR FORCE BASE, GUAM -- A B-1B Lancer soars over the Pacific Ocean after air refueling training here Sept. 30. The B1B Bomber is deployed to Andersen Air Force Base, Guam, as part of the Pacific Commands continuous bomber presence in the Asia-Pacific region, enhancing regional security and the U.S. commitment to the Western Pacific. The B1 is from the 37th Bomb Squadron, Ellsworth Air Force Base, South Dakota. (U.S. Air Force Photo by Staff Sgt. Bennie J. Davis III)

La monitorización de las aplicaciones es un elemento fundamental en la puesta en producción de los sistemas y más en particular de los microservicios. Desde hace un tiempo se comenzó a hablar sobre el término de APM, cuyo significado es Monitorización de Aplicaciones; es, en sí un área dentro de TI encargada de monitorizar las aplicaciones para verificar que se comporten como se esperan.

Sistemas para hacer APM hay muchos, algunos de pago como New Relic que es uno de los más empleados y otros de código abierto, a los cuales se les denomina de forma general OpenAPM.

En el proceso de APM existen varios componentes, los más comunes son:

  • Agentes: Encargados de recolectar datos del performance de las aplicaciones, son usados en arquitecturas más tradicionales.
  • Librerías: Son componentes de instrumentación que se incluyen en las aplicaciones para recopilar la información a monitorizar de acuerdo a las necesidades del negocio, por ejemplo en un sistema de ventas, pudiera medirse cada vez que se vende un producto o servicio.
  • Sistemas de transporte: Son el elemento que llevará los datos desde donde son capturados hasta el sistema de almacenamiento.
  • Colectores: Se encargan de recopilar datos de los sistemas de instrumentación, agentes o fuentes de datos.
  • Procesadores: Su función dentro de APM es transformar datos desde un stream o fuente de datos para formatearlos.
  • Almacenamiento: Es el componente que se encarga de la persistencia de los datos. Su función es almacenar para que otros componentes puedan realizar consultas sobre los datos y extraer información. Son muy usados sistema de almacenamiento de serie de tiempo.
  • Visualización/Dashboard: Permiten presentar la información en diferentes formatos, gráficas, etc.
  • Alertas: Sirven para definir alertas en base a los datos existentes, por ejemplo ante el cumplimiento de determinado umbral en una métrica emitir un mensaje de correo electrónico o tomar una acción sobre un sistema (monitoreo activo).

El grupo de herramientas de código abierto existente para hacer APM puede ser consultado acá.

Micrometer

Micrometer es una librería de instrumentación para sistemas construidos sobre la máquina virtual de Java, es un facade para los sistemas de APM más populares, hemos probado micrometer con persistencia a InfluxDb y Prometheus con buenos resultados. La lista completa de soporte de micrometer puede ser consultada acá.

Spring Boot actuator

En alguna ocasión acá en el blog ya hemos hablado de Actuator, es básicamente un starter de Spring Boot que nos permite de una forma muy sencilla monitorizar nuestros microservicios o aplicaciones a través de endpoints, hace un tiempo atrás usábamos Spring Boot Admin, que por cierto ha modernizado su UI para leer lo que nos provee Spring Boot Actuator, pero desde que comenzamos a usar micrometer lo hemos dejado, no deja de ser una buena solución aunque un poco limitada.

Prometheus / Grafana

Dentro del ecosistema de soluciones de OpenAPM encontramos a Prometheus (sistema de almacenamiento o persistencia) y a Grafana como solución de dashboard para crear y visualizar métricas, estas dos soluciones las usaremos en este sencillo ejemplo.

Integrando Spring Boot / Actuator / Micrometer / Prometheus / Grafana para crear una solución de APM en menos de 5 minutos

Lo primero que haremos es describir en un gráfico como es el flujo de información entre todos estos componentes.

El sentido de la flecha indica quién realiza la petición de información.

Creando la aplicación Spring Boot

La aplicación Spring Boot debe incluir las siguientes dependencias en el POM.

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

Web proveerá soporte MVC, Actuator permitirá obtener métricas y micrometer-registry-prometheus es el facade de micrometer para almacenar las métricas en Prometheus, habilita además un endpoint de Spring Boot Actuator con la información de prometheus. La data puede visualizarse por GET en:

GET http://IP:8081/actuator/prometheus

Previamente debemos agregar en la configuración de nuestros proyectos ( application.properties o application.yml) que se habilite el endpoint de prometheus.

management.endpoints.web.exposure.include=*
management.metrics.tags.application=test

ADVERTENCIA: En el exposure.include en producción no deben habilitarse todos los endpoints, solo habilitar para este propósito prometheus.

El tags application sirve para si tenemos varias apps poder filtrar las métricas de cada una.

Esto es todo lo que debemos poner en nuestra aplicación Spring Boot. Micrometer ofrece la anotación @Timed para hacer extracción de métricas personalizadas en el flujo de ejecución del programa, puede verse la documentación para más detalles.

Instalando Prometheus & Grafana

La instalación de Prometehus y Grafana la realizaremos desde docker compose, por ello emplearemos un proyecto de terceros ya pre-configurado, el mismo puede ser puesto en operación siguiendo los siguientes pasos:

git clone https://github.com/stefanprodan/dockprom
cd dockprom
# Ejecutamos en la terminal
ADMIN_USER=admin ADMIN_PASSWORD=admin docker-compose up -d

Una vez seguidos los pasos anteriores tendremos ya Prometheus y Grafana levantados (y otros componentes de APM que no abordaremos acá, por ahora).

Podemos entrar a Grafana desde nuestro localhost por el puerto 3000 (http://localhost:3000), usaremos las credenciales del entorno que hemos especificado (admin:admin), nos pedirá un cambio de password en el primer inicio de sesión. A Prometheus por su parte podemos acceder por el puerto 9090 (http://localhost:9090).

Conectando Prometheus con Spring Boot

Ahora solo nos resta decirle a Prometheus y que obtenga las métricas de nuestra instancia de proyecto de Spring Boot que hemos creado. Suponiendo que nuestro proyecto Spring Boot se está ejecutando por el puerto 8081 debemos ir en la carpeta dockprom que hemos clonado desde github y movernos a /prometheus/prometheus.yml y agregar la siguiente entrada de configuración.

  - job_name: 'spring-actuator'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['192.168.1.5:8081']

En el target por su puesto debe el IP:Puerto de la aplicación a monitorizar, una vez creado esto reiniciamos el contenedor de Prometheus, al arrancar podemos verificar si esta funcionando correctamente entrando a http://localhost:9090/targets y debemos ver los siguiente:

Ahora para visualizar las métricas volvamos a Grafana e importemos un dashboard ya preparado para visualizar métricas de Micrometer almacenadas en Prometheus. Para ello importemos en Grafana el dashboard disponible aquí.

Luego de importar podrás acceder a las gráficas de inmediato, algunas capturas de debajo.

Estas y otras gráficas estarán disponibles al instante. Por cierto si quieres conocer un poco más sobre la JVM te invito a leer esta entrada en la que hablamos de la JVM y sus componentes, o en este otro que tratamos el Recolector de Basura.

Espero te haya sido útil este artículo. Deja tus preguntas en los comentarios.