Monitoreo con actuador Spring Boot

M

Visión general

En este artículo, analizaremos Actuador de arranque de resorte, que proporciona puntos finales integrados listos para la producción que se pueden usar para monitorear y controlar su aplicación.

Las aplicaciones de monitoreo pueden incluir algo tan simple como conocer el estado y la información de algunos datos complejos, como comprender el tráfico y las métricas para nuestra aplicación. Por ejemplo, cuántos recursos (CPU, RAM, etc.) está utilizando la aplicación.

Puede optar por interactuar con actuadores con puntos finales HTTP o con beans JMX. En este tutorial, estaríamos usando los puntos finales HTTP.

En Spring Boot 1, el actuador solo se podía usar con Spring MVC. Pero con Spring Boot 2 y la introducción de WebFlux, su soporte se ha ampliado y también se puede utilizar con el Jersey framework sin la necesidad de Spring MVC en el classpath.

Actuador de arranque de resorte

Para demostrar el funcionamiento del actuador, utilizaremos un servicio simple basado en Spring REST, que se ejecuta en el puerto predeterminado (8080) con un único punto final de /hello que devuelve un mensaje de cadena.

Para agregar actuador, simplemente agregamos la dependencia a nuestro pom.xml archivo:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>${VERSION}</version>
</dependency>

Todos los puntos finales caen bajo un prefijo común de /actuator. Para comprobarlo, naveguemos por nuestro navegador hasta http://localhost:8080/actuator:

Nota: En Spring Boot 1, todos los puntos finales del actuador estaban en la ruta base raíz, es decir /, pero en Spring Boot 2, todos ellos están agrupados por defecto en /actuator.

Puede cambiar la ruta base de los puntos finales del actuador agregando las siguientes propiedades en el application.properties:

management.endpoints.web.base-path=/admin
management.server.port=8090

Ahora, todos los puntos finales del actuador estarán bajo el /admin prefijo, lo cual tiene sentido ya que solo un administrador debe tener acceso a métricas como estas. Para este tutorial, lo dejaremos bajo el valor predeterminado /actuator.

De forma predeterminada, los puntos finales de administración están disponibles en el mismo puerto que el de su aplicación, pero puede optar por exponerlos en un puerto HTTP diferente configurando el management.server.port a un puerto HTTP de su elección.

No lo cambiaremos, ya que es preferible el comportamiento predeterminado, especialmente si está ejecutando en la nube.

Puntos finales del actuador

Se puede ver una lista completa de los puntos finales disponibles en el documentación oficial. Es posible que haya notado que, aunque hay muchos puntos finales disponibles, el resultado de http://localhost:8080/actuator solo muestra /health y /info.

Dado que los puntos finales del actuador contienen información confidencial, hemos tenido que exponer explícitamente cada uno de ellos; de lo contrario, solo podremos ver información rudimentaria que ya es evidente.

Navegue nuestro navegador a http://localhost:8080/actuator/health:

Ahora, revisemos el /info de manera similar y notará que devuelve una respuesta vacía.

Esto se debe a que no hemos proporcionado ninguna información al respecto a Spring. Esto se puede hacer agregando propiedades al info prefijo en el application.properties:

info.name= Test Spring Service
info.more.detail= This is a demo for Spring Actuator

Puede estructurar la clave JSON según sus necesidades.

Exponer puntos finales

Para exponer los puntos finales, Spring proporciona 2 propiedades que podemos usar individualmente o en combinación:

  • management.endpoints.web.exposure.exclude: Se utiliza para excluir una lista de puntos finales que no queremos exponer. El valor predeterminado está vacío.
  • management.endpoints.web.exposure.include: Se utiliza para incluir una lista de puntos finales que queremos exponer. El valor predeterminado es info, health. Es por eso que ambos puntos finales estaban disponibles de forma predeterminada.

Nota: exclude tiene prioridad sobre include

Entonces, modifiquemos la configuración para que queramos exponer todos los puntos finales excepto info y health:

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=info,health

Nota: Si está utilizando un archivo de propiedades basado en YAML, * tiene un significado especial y solo se puede usar con comillas:

management:
  endpoints:
    web:
      exposure:
        exclude: "*"

Para este tutorial, expondremos todos los puntos finales de nuestro actuador. Así que agreguemos el siguiente punto final en nuestro application.properties:

management.endpoints.web.exposure.include= *

Ahora, revisemos el punto final del actuador nuevamente abriendo http://localhost:8080/actuator:

Habilitación de terminales

Además de exponer los puntos finales, también podemos habilitarlos y deshabilitarlos. Mientras que exponer solo regula si podemos verlos o no, habilitar regula si existen como un bean en el contexto de Spring.

De forma predeterminada, todos los puntos finales están habilitados excepto uno, el shutdown punto final. Puede habilitar / deshabilitar cada punto final configurando el management.endpoint.<id>.enabled propiedad:

management.endpoint.shutdown.enabled=true
management.endpoint.beans.enabled=false

También puede deshabilitar todos los puntos finales configurando management.endpoints.enabled-by-default a false y luego habilite individualmente las propiedades que desee. Para este tutorial, iríamos con la configuración predeterminada.

Nota: La desactivación de los puntos finales los eliminará como beans del contexto por completo y no importaría si los ha expuesto.

Soporte de caché

Todos los puntos finales (que son operaciones READ y no toman ningún parámetro) también tienen soporte básico de almacenamiento en caché.

Cada punto final tiene una propiedad de cache.time-to-live que se genera automáticamente para usted, que puede usarse para especificar el tiempo de caché:

management.endpoint.beans.cache.time-to-live=10s

Asegurar los puntos finales del actuador

A estas alturas, habría quedado claro que estos puntos finales almacenan información confidencial sobre nuestra aplicación y sería una buena idea protegerlos.

Para hacerlo, simplemente podemos agregar seguridad de Spring a nuestra aplicación agregando el spring-boot-starter-security dependencia en nuestra pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>${VERSION}</version>
</dependency>

De forma predeterminada, con solo importarlo, todos los puntos finales de nuestra aplicación estarán protegidos.

Pero supongamos que queremos nuestro /health punto final disponible para todos, pero el resto de ellos para ser seguro. Esto garantiza un filtro personalizado para permitir que ciertos usuarios pasen y retener a otros.

Para eso tenemos que agregar un @Configuration clase que extiende el WebSecurityConfigurerAdapter, como con cualquier otra aplicación Spring Boot que queramos proteger con Spring Security.

Entonces necesitamos anular el .configure() método donde definimos la configuración de seguridad para nuestra aplicación:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll()
            .requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated()
            .and()
            .httpBasic();
    }
}

El código anterior se explica por sí mismo, donde permitimos cualquier HealthEndpoint para estar disponible públicamente, mientras que otros requieren cierta autenticación básica. Además, tenga en cuenta que EndpointRequest.to() es un método conveniente que se encarga automáticamente de la URL final de los puntos finales de su actuador porque es posible que haya cambiado la ruta base de la misma en su aplicación.

Reiniciemos nuevamente y revisemos los registros:

Debido a que Spring Security está en la ruta de clases, crea automáticamente un nombre de usuario de user y una contraseña que se genera aleatoriamente al inicio de la aplicación, como se muestra en los registros.

Vamos a comprobar el /health endpoint y verá la salida sin ningún cuadro de autenticación. Ahora intentemos cualquier otro punto final, digamos /env y se le pedirá que se autentique:

Ingrese el nombre de usuario y la contraseña y podrá ver la respuesta adecuada:

Si desea definir su propio nombre de usuario y contraseña, puede hacerlo fácilmente a través del application.properties:

spring.security.user.name=user
spring.security.user.password=password

Crear puntos finales personalizados

Esto se puede lograr agregando el @Endpoint y @Component anotación a tu clase. Después de eso, puede crear métodos y anotarlos con @ReadOperation, @WriteOperationo @DeleteOperation en consecuencia. Por supuesto, puede tener varios métodos con diferentes operaciones.

La idea de tener múltiples operaciones es mapear a diferentes métodos de solicitud HTTP:

  • @ReadOperation se asigna a HTTP GET
  • @WriteOperation se asigna a HTTP POST
  • @DeleteOperation se asigna a HTTP DELETE

Creemos un punto final personalizado simple:

@Component
@Endpoint(id = "details")
public class DetailsEndpoint {

    @ReadOperation
    public String details() {
        return "My App Details";
    }
}

Reinicie la aplicación y navegue hasta su navegador para http://localhost:8080/actuator/details:

Conclusión

Las aplicaciones de monitoreo pueden incluir algo tan simple como conocer el estado y la información de algunos datos complejos, como comprender el tráfico y las métricas para nuestra aplicación. Por ejemplo, cuántos recursos (CPU, RAM, etc.) está utilizando la aplicación.

Spring Boot Actuator proporciona puntos finales integrados listos para la producción que se pueden usar para monitorear y controlar su aplicación, como /info, /health, /scheduledTasksetc.

También podemos definir nuestros propios puntos finales para cumplir con ciertos requisitos simplemente anotando clases con el @Endpoint anotación.

Como siempre, el código de los ejemplos utilizados en este artículo se puede encontrar en GitHub.

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad