El logging es una parte fundamental que necesitamos en nuestros Servicios Web.
Siempre vamos a tener que echar mano de ellos para consultar algún error inesperado o comprobar el comportamiento de nuestro servicio una vez desplegado.

SpringBoot por defecto utiliza una implementación de slf4j llamada LogBack
Sino configuramos nada, por defecto springboot solo muestra logs por consola y a partir del nivel 'INFO' y posteriores (no se mostrarán los niveles 'TRACE' ni 'DEBUG').

Siempre es bueno recordar los LogLevels ordenados de menor a mayor importacia:

  • trace (the least serious)
  • debug
  • info
  • warn
  • error
  • fatal (the most serious)

Configurando nuestro Logger:

Para configurar como se muestran los mensajes de Logging, con que formato y por donde deben imprimirse (consola y/o archivo) debemos de añadir un archivo con el nombre logback-spring.xml en la carpeta /resources de nuestro proyecto.
Un ejemplo de configuració puede ser esta:

Secciones del archivo logback-spring.xml:

property: Aquí se definen valores que se pueden repetir a lo largo del archivo .xml y en lugar de copiar/pegar dicho valor en todas las partes necesarias se utiliza una propiedad para hacer referencia a dicho valor. Así si el valor cambia solo tendremos que cambiarlo en dicha propiedad sin tener que ir buscando por todo el archivo la cadena correspondiente a modificar.

appender: Los appender sirven para declarar las 'salidas' de nuestros logs.
Se pueden configurar uno o más appenders para mostrar logs por consola o para que se escriban en un archivo. También se define el formato del mensaje y otra opciones como por ejemplo el truncado de nuestros archivos de logs cada cierto tiempo o al llegar a un tamaño en disco determinado.

root: En esta sección se configura el Logging por defecto de nuestra aplicación para cualquier paquete o clase.
Aquí es donde se utilizan los 'appenders' declarados previamente, para indicar cuales serán las salidas de nuestros logs por defecto.
En nuestro archivo .xml hemos definido que por defecto cualquier log que se haga debe salir solo por la consola.
Podríamos haber definido que se guardasen también en un archivo utilizando el appender 'RollingFile' o incluso declarar otro appender para guardarlos en otro archivo distinto y utilizar ambos para guardar los logs en 2 archivos distintos.
Se pueden utilizar tantos appenders como nos hagan falta según nuestras necesidades.
En la propiedad 'level' se indica el nivel de log a partir del cual se mostrarán los mensajes. En nuestro ejemplo solo se mostrarán los mensajes a partir del level 'info' y posteriores (no se mostrarán los logs con level 'trace' o 'debug').

logger: Esta sección sirve para configurar el Logging al igual que en la sección root pero solo para los Loggers que pertenezcan a un paquete y clase específicos.
En el parámetro 'name' se indica el paquete y/o clase correspondiente.
A continuación se indican los appenders que utilizarán los Loggers de dicho paquete y/o clase.
En nuestro arhivo .xml hemos definido que los mensajes de log de todas las clases que pertenezcan al paquete 'net.atopecode' (y descendientes) se escriban por consola y en archivo de disco.
En la propiedad 'level' se indica el nivel de log a partir del cual se mostrarán los mensajes. En nuestro ejemplo se muestran todos los niveles de logging ya que hemos indicado el level 'trace' y posteriores.

Utilizando el Logger desde nuestro código:

Para utilizar el Logger en nuestro código es necesario indicar a que clase pertenece. Dependiendo del paquete/clase a la que pertenece el Logger, a la hora de mostrar el mensaje se utilizará un appender u otro según lo que hayamos configurado en la sección 'logger' de nuestro archivo 'logback-spring.xml'

En este ejemplo se está creando el Logger para la clase 'PruebaLoggingComponent' que coincide que es la misma clase donde se va a utilizar el Logger. Normalmente la clase para la que se define el Logger es la misma en la que se va a utilizar pero no tiene porque ser así.
Lo que importa a la hora de declarar nuestro Logger con respecto a la configuración del archivo .xml es el parámetro '.class' que se para como parámetro en el método 'LoggerFactory.getLogger()'.

En este caso nuestro Logger utilizará la sección

    <logger name="net.atopecode" level="trace" additivity="false">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </logger>

de nuestro archivo 'logback-spring.xml' ya que la clase 'PruebaLoggingComponent' está dentro del paquete '.net.atopecode.*'.
Por lo tanto se escribirán los mensajes de log por consola y en archivo de disco al mismo tiempo.

Propiedad 'additivity':

Hay que tener en cuenta que la sección 'root' de nuestro archivo 'logback-spring.xml' también afecta a nuestro Logger, ya que hace referencia a cualquier Logger definido dentro del proyecto.

Para estos casos se utiliza la propiedad 'additivity' que por defecto vale 'true'. En nuestro caso al asignar additivity="false" estamos indicando que se utilice la sección 'logger' de nuestro archivo .xml que más se ajuste al 'paquete/clase' pero no todas las otras secciones que puedan hacer referencia a nuestro Logger.

Si no hubiésemos indicado additivity="false" en este caso, nuestros mensajes habrían salido por duplicado en la consola (una vez por la sección root y otra por la sección logger) y también se escribirían en un archivo (por la sección logger).

Para entender mejor esta parte pongamos como ejemplo otro archivo .xml igual al anterior, pero esta vez añadiremos otra sección 'logger' indicando el nombre de la clase (somos más restrictivos que solo indicando el paquete) para que se ajuste más a nuestro Logger declarado en el código Java.

Ahora nuestro Logger declarado en la clase Java "PruebaLoggingComponent" utilizará la nueva sección 'logger' de nuestro archivo .xml ya que es la que más se ajusta porque está indicando directamente el nombre de clase:

    <logger name="net.atopecode.authservice.component.PruebaLoggingComponent" level="debug" additivity="false">
        <appender-ref ref="Console" />
    </logger>

Nuestros mensajes saldrán ahora solo por consola y a partir del level debug.

Si no hubiésemeos puesto la propiedad additivity="false", además de nuestra nueva sección se estaría también utilizando la anterior a ella:

    <logger name="net.atopecode" level="trace" additivity="false">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </logger>

En cuyo caso se mostrarían los mensajes en archivo y por duplicado en la consola.
Es una buena práctica utilizar siempre additivity="false" para que solo una sección 'logger' de nuestro archivo xml afecte a los mensajes de nuestros Loggers.

Conclusión:

En este artículo hemos visto una forma básica de configurar los Logs en SpringBoot.
Existen muchas más opciones pero con esta configuración se puede empezar a trabajar en un proyecto guardando los logs en un archivo además de mostrarlos por consola y especificando a partir de que nivel queremos que se muestren.

Espero que este artículo haya sido de utilidad.
A Tope Codear!!!


Enlaces de interés:

-Logging in Spring Boot - Baeldung Blog
-A Guide To Logback - Baeldung Blog
-How can I configure Logback to log different levels for a logger to different destinations?
-Logging In Spring Boot - Reflectoring Blog
-Tracing in Distributed Systems with Spring Cloud Sleuth