¿Logs en Spring Boot? Así los controlas desde application.properties

Estás desarrollando en Spring Boot y necesitas ajustar los logs para depurar o simplemente tener un control decente. Te muestro cómo hacerlo de forma simple y sin dar mil vueltas, directo desde application.properties.

A ver, me ha pasado varias veces, tanto en proyectos míos como revisando código de clientes: estás enfrascado en un bug, o necesitas entender por qué diantres una parte de tu aplicación se comporta raro. ¿Y qué es lo primero que uno mira? Los logs, obvio. Pero a veces, el nivel por defecto es una lata, o te inunda de información inútil, o simplemente no te muestra lo que necesitas. La pregunta clásica es: ¿cómo ajusto el nivel de logging, o dónde se guardan los archivos de log, sin tener que irme a configurar XMLs de frameworks que son un dolor de cabeza?

Esto antes era un cacho, de hecho. Si trabajaste con versiones de Spring Boot anteriores a la 1.2.0, no te quedaba otra que meterte con los archivos de configuración de tu framework de logging específico, ya sea log4j.xml o logback.xml, y meterlos en src/main/resources. Una paja, porque implicaba añadir más archivos y más configuración ajena a lo que ya tenías en application.properties.

La vida es más simple con Spring Boot 1.2+

Por suerte, desde Spring Boot 1.2.0.RELEASE en adelante, la cosa se simplificó un montón. Ya no necesitas esos XML adicionales para las configuraciones básicas. Puedes hacer todo lo esencial directamente desde tu application.properties (o .yml, si eres de esos, aunque yo prefiero properties, es más directo).

En mi caso, cuando necesito subir el nivel de detalle para depurar, lo primero que hago es ir a application.properties y poner algo así:


# Nivel de log global (root)
logging.level.root=INFO

# Nivel de log para paquetes específicos (aquí es donde se pone bueno)
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=WARN
logging.level.cl.1up.miaplicacion=DEBUG

Con logging.level.root, defines el nivel por defecto para toda la aplicación. Pero lo realmente útil es poder especificar niveles para paquetes concretos. Por ejemplo, si estoy con un problema en algún controlador REST, subo el nivel a DEBUG solo para org.springframework.web. Si Hibernate me está volviendo loco con queries, lo subo para org.hibernate. Esto me permite ver más detalle justo donde lo necesito, sin que el resto del log se llene de ruido.

¿Y dónde guardo los logs?

También puedes definir fácilmente dónde quieres que se guarden tus logs. De forma predeterminada, Spring Boot los manda a la consola. Pero si necesitas un archivo, con esto basta:


# Para guardar en un archivo, con ruta relativa (en la carpeta donde se ejecuta la app)
logging.file.name=logs/mi-app.log

# O una ruta absoluta (ojo con los permisos del directorio)
# logging.file.path=/var/log/mi-app

# Si solo defines logging.file.path, el nombre del archivo por defecto es spring.log
# Si usas logging.file.name, puedes poner el path completo ahí mismo
# logging.file.name=/var/log/mi-app/mi-app.log

Un tip que aprendí medio tarde: si solo necesitas activar el debug logging de Spring Boot de forma rápida, puedes iniciar tu aplicación con el flag --debug desde la línea de comandos. Esto activa un montón de información útil sobre la configuración de Spring Boot sin tocar tu application.properties. De hecho, a veces es lo primero que pruebo antes de empezar a cambiar cosas.

Perfiles: el juego de los entornos

Aquí es donde la cosa se pone más interesante si trabajas con distintos entornos (desarrollo, producción, testing, etc.). No quieres el mismo nivel de logs en producción que en desarrollo, ¿verdad? En producción, prefieres ERROR o WARN para no saturar los discos y por seguridad. En desarrollo, te viene bien el DEBUG. Para eso, usamos perfiles:

  • Crea un archivo application-dev.properties para tu entorno de desarrollo.
  • Crea un application-prod.properties para producción.

Así, en application-dev.properties, podrías tener:


logging.level.root=DEBUG
logging.file.name=
# Vacío significa que no se escribe a archivo, solo a consola

Y en application-prod.properties:


logging.level.root=ERROR
logging.file.name=/var/log/mi-app-prod/mi-app.log

Para activar un perfil, lo pasas como argumento al iniciar la JVM, por ejemplo:


java -Dspring.profiles.active=dev -jar mi-app.jar

O si estás usando Maven:


mvn spring-boot:run -Dspring-boot.run.profiles=dev

Esto es súper práctico para tener configuraciones específicas sin andar comentando y descomentando líneas cada vez. Y sí, ayuda a la performance en producción, porque no estás escribiendo logs a cada rato, y ojo que también alarga un poco la vida de los SSDs en servidores, un detalle que a veces se olvida.

Mi recomendación concreta

Si la pregunta es simple y solo necesitas controlar los niveles de log y la salida a archivo, mi recomendación es siempre partir por application.properties directamente. Define tu logging.level.root y luego los niveles para los paquetes específicos que te interesan. Si necesitas un archivo, usa logging.file.name. Solo si la complejidad de tu proyecto o los requisitos de los entornos lo ameritan, te lanzas con los perfiles. La sobreingeniería a veces solo trae más problemas. Manténlo simple y funcional, que eso es lo que de verdad sirve.

Jorge RequenaDeveloper full-stack · Chile