La configuración de logging en aplicaciones Java se gestiona frecuentemente mediante Logback, cuyo archivo central es logback.xml. Este documento describe sus componentes y cómo estructurarlos.
Elementos raíz del archivo de configuración
El elemento principal es <configuration>, el cual admite atributos que controlan su comportamiento:
scan: Si estrue, Logback verifica cambios en el archivo y lo recarga automáticamente. Por defecto estrue.scanPeriod: Define el intervalo para comprobar modificaciones cuandoscanestá habilitado. El valor por defecto es un minuto.debug: Al activarse (true), muestra registros internos de Logback para depuración. Desactivado por defecto.
<configuracion scan="true" scanPeriod="30 seconds" debug="false">
<!-- Resto de la configuración -->
</configuracion>
Componentes appender para registro de salida
Los appenders determinan dónde y cómo se escribe cada evento de log. Cada uno requiere un nombre único y la clase que lo implementa.
Consola (ConsoleAppender)
Envía los registros a la salida estándar. Sus subelementos son:
<encoder>: Define el formato del mensaje.<target>: EspecificaSystem.out(por defecto) oSystem.err.
Ejemplo para volcar mensajes DEBUG y superiores en consola:
<configuracion>
<appender nombre="SALIDA_CONSOLA" clase="ch.qos.logback.core.ConsoleAppender">
<codificador>
<patron>%-4relative [%hilo] %-5nivel %logger{35} - %mensaje %n</patron>
</codificador>
</appender>
<raiz nivel="DEBUG">
<appender-ref ref="SALIDA_CONSOLA" />
</raiz>
</configuracion>
Archivo simple (FileAppender)
Escribe eventos en un archivo específico. Los eleemntos principales son:
<file>: Ruta del archivo de log.<append>: Si estrue, añade al final; si esfalse, sobreescribe. Default:true.<encoder>: Formatea los mensajes.<prudent>: Modo seguro para escrituras concurrentes. Default:false.
Ejemplo que escribe DEBUG y niveles superiores en aplicacion.log:
<configuracion>
<appender nombre="ARCHIVO" clase="ch.qos.logback.core.FileAppender">
<archivo>aplicacion.log</archivo>
<anexar>true</anexar>
<codificador>
<patron>%-4relative [%hilo] %-5nivel %logger{35} - %mensaje%n</patron>
</codificador>
</appender>
<raiz nivel="DEBUG">
<appender-ref ref="ARCHIVO" />
</raiz>
</configuracion>
Archivo rotativo (RollingFileAppender)
Permite crear nuevos archivos basados en condiciones como tiempo o tamaño. Su política de rotación se define en <rollingPolicy>.
Rotación basada en teimpo
Usa la clase TimeBasedRollingPolicy. Los nodos importantes:
<fileNamePattern>: Patrón para nombres de archivo archivados, usando%dpara fechas.<maxHistory>: Número máximo de archivos históricos a conservar.
Configuración para guardar logs diarios durante un mes:
<appender nombre="ARCHIVO_ROTATIVO" clase="ch.qos.logback.core.rolling.RollingFileAppender">
<politicaRotativa clase="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<patronArchivo>logs/registro.%d{yyyy-MM-dd}.log</patronArchivo>
<historialMaximo>30</historialMaximo>
</politicaRotativa>
<codificador>
<patron>%d{HH:mm:ss.SSS} [%hilo] %-5nivel %logger - %mensaje%n</patron>
</codificador>
</appender>
Rotación basada en tamaño
La clase SizeBasedTriggeringPolicy crea un nuevo archivo cuando el actual supera un tamaño límite.
<triggerPolicy clase="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<tamanoMaxArchivo>20MB</tamanoMaxArchivo>
</triggerPolicy>
Definición de loggers
Los <logger> controlan el nivel de log para paquetes o clases específicos. Sus atributos son:
name: Nombre del paquete o clase.level: Nivel de log deseado (TRACE, DEBUG, INFO, WARN, ERROR).additivity: Si estrue, los eventos se propagan al logger padre. Default:true.
El logger raíz <root> es el padre de todos y establece el nivel por defecto.
Ejemplo para ajustar niveles en bibliotecas específicas:
<logger name="org.hibernate.SQL" level="DEBUG"/>
<logger name="com.miempresa.servicios" level="INFO"/>
<raiz nivel="WARN">
<appender-ref ref="ARCHIVO_ROTATIVO"/>
</raiz>
Variables y contexto
Se pueden definir variables con <property> y usarlas mediante ${}.
<configuracion>
<propiedad nombre="DIR_LOGS" valor="/var/log/miapp"/>
<contextoNombre>Produccion</contextoNombre>
<appender nombre="ARCHIVO" clase="ch.qos.logback.core.FileAppender">
<archivo>${DIR_LOGS}/eventos.log</archivo>
<!-- ... -->
</appender>
</configuracion>
La etiqueta <timestamp> permite obtener la fecha actual como variable.
<timestamp clave="marcaTiempo" patronFecha="yyyyMMdd"/>
<contextoNombre>App_${marcaTiempo}</contextoNombre>
Configuración completa de ejemplo
Combinación típica que usa consola y archivo rotativo diario:
<?xml version="1.0" encoding="UTF-8"?>
<configuracion debug="false">
<propiedad nombre="RUTA_BASE" valor="/home/usuario/logs"/>
<appender nombre="SALIDA_CONSOLA" clase="ch.qos.logback.core.ConsoleAppender">
<codificador clase="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<patron>%d{HH:mm:ss.SSS} [%hilo] %-5nivel %logger{60} - %mensaje%n</patron>
</codificador>
</appender>
<appender nombre="LOG_DIARIO" clase="ch.qos.logback.core.rolling.RollingFileAppender">
<politicaRotativa clase="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<patronArchivo>${RUTA_BASE}/diario.%d{yyyy-MM-dd}.log</patronArchivo>
<historialMaximo>15</historialMaximo>
</politicaRotativa>
<codificador clase="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<patron>%d{yyyy-MM-dd HH:mm:ss} [%hilo] %-5nivel %logger{50} - %mensaje%n</patron>
</codificador>
<triggerPolicy clase="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<tamanoMaxArchivo>50MB</tamanoMaxArchivo>
</triggerPolicy>
</appender>
<logger name="org.springframework" level="WARN"/>
<logger name="com.miapp.persistencia" level="DEBUG"/>
<raiz nivel="INFO">
<appender-ref ref="SALIDA_CONSOLA"/>
<appender-ref ref="LOG_DIARIO"/>
</raiz>
</configuracion>
Flujo de resolución de registros
Cuando se genera un evento de log, se busca el logger más específico. Si este tiene appendesr asignados, los utiliza. De lo contrario, según la bandera additivity, el evento puede propagarse al logger padre hasta llegar a <root>, que siempre debe tener al menos un appender configurado.
Los niveles de log, por orden de severidad, son: TRACE, DEBUG, INFO, WARN, ERROR. Configurar un nivel implica que se capturarán todos los eventos con igual o mayor prioridad. En producción, generalmente se establece WARN o INFO para evitar saturar los archivos.