Para integrar SLF4J con Logback en un proyecto de Spring Boot, el archivo de configuración debe ubicarse en el directorio src/main/resources y nombrares específicamente como logback-spring.xml. Esta nomenclatura permite aprovechar las etiquetas nativas de Spring para definir estrategias de registro diferenciadas y dinámicas según el perfil de ejecución activo.
Configuración Básica con Rotación por Tiempo
El siguiente ejemplo demuestra cómo separar los registros en archivos distintos basándose en su nivel de severidad, utilizando una política de rotación diaria para mantener el historial organizado.
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<property name="RUTA_BASE_LOGS" value="/var/log/sistema" />
<appender name="archivoInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${RUTA_BASE_LOGS}/app-info-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="archivoError" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${RUTA_BASE_LOGS}/app-error-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.springframework.web" level="WARN" />
<root level="INFO">
<appender-ref ref="archivoInfo" />
<appender-ref ref="archivoError" />
</root>
</configuration>
Estrategia Multi-entorno con Spring Profiles
En escenarios de producción, es crucial adaptar la salida de los logs según el entorno. A continuación, se presenta una configuración avanzada que utiliza <springProfile> para definir un comportamiento distinto para desarrollo local (solo consola con colores) y producción (consola, archivos con rotación por tamaño y tiempo, y segregación de logs de colas de mensajes mediante evaluadores).
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="DIRECTORIO_LOGS" value="/opt/miapp/logs" />
<springProfile name="local">
<appender name="consola" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%cyan(%d{HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.hibernate" level="WARN" />
<root level="DEBUG">
<appender-ref ref="consola" />
</root>
</springProfile>
<springProfile name="prod">
<appender name="consolaProd" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="rolloverGeneral" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DIRECTORIO_LOGS}/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${DIRECTORIO_LOGS}/application-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>15</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="rolloverError" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${DIRECTORIO_LOGS}/error-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="trazaMensajeria" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator>
<matcher>
<Name>filtroCola</Name>
<regex>.*\[MQ-TRACE\].*</regex>
</matcher>
<expression>filtroCola.matches(formattedMessage)</expression>
</evaluator>
<OnMatch>ACCEPT</OnMatch>
<OnMismatch>DENY</OnMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${DIRECTORIO_LOGS}/messaging-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>20MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.apache.kafka" level="WARN" />
<logger name="org.springframework.amqp" level="INFO" />
<root level="INFO">
<appender-ref ref="consolaProd" />
<appender-ref ref="rolloverGeneral" />
<appender-ref ref="rolloverError" />
<appender-ref ref="trazaMensajeria" />
</root>
</springProfile>
</configuration>