Bienvenido al tutorial de ejemplo de Apache Log4j2. Si le preguntas a un desarrollador experto cuál es la cosa más molesta de una aplicación, la respuesta podría estar relacionada con el registro. Si no hay un registro adecuado en una aplicación, el mantenimiento será una pesadilla. La mayoría de las aplicaciones pasan por pruebas de desarrollo, pruebas unitarias y pruebas de integración. Pero cuando se trata de producción, siempre te enfrentarás a escenarios únicos y excepciones. Por lo tanto, la única forma de averiguar qué sucedió en un caso específico es depurar a través de los registros. Muchos marcos proporcionan alguna forma de registro predeterminado, pero siempre es mejor optar por el mecanismo de registro estándar de la industria. Apache Log4j es uno de los marcos de registro más utilizados. Apache Log4j 2 es la siguiente versión, que es mucho mejor que Log4j.
Tutorial de ejemplo de Log4j
En este tutorial de ejemplo de Log4j2, aprenderá a comenzar a utilizar Apache Log4j2 . También exploraremos la arquitectura de Log4j2, la configuración de Log4j2, los niveles de registro de Log4j2, los anexos, los filtros y mucho más.
- Descripción general de Log4j2
- Arquitectura Log4j2
- Configuración de Log4j2
- Niveles de Log4j2
- Búsquedas en Log4j2
- Anexos de Log4j2
- Filtros Log4j2
- Diseños de Log4j2
- ¿Qué nivel de Log4j2 debería utilizar?
- Resumen del tutorial de Log4j2
Descripción general de Log4j2
El uso de la API de registro en una aplicación no es un lujo, es una necesidad. Log4j es una biblioteca de código abierto publicada y licenciada bajo Apache Software . Puede depurar una aplicación utilizando Eclipse Debugging o algunas otras herramientas, pero eso no es suficiente ni factible en un entorno de producción. El mecanismo de registro le proporcionará varios beneficios que no encontrará en la depuración normal.
| Categoría/Operación (depuración, registro) | Depuración | Explotación florestal |
|---|---|---|
| Intervención humana | Es necesaria la intervención humana. | No es necesaria la intervención humana |
| Medio persistente | No se puede integrar con el almacenamiento persistente | Se puede integrar con almacenamiento persistente (archivos, bases de datos, bases de datos NoSQL, etc.) |
| Puede utilizarse para auditoría | No se puede utilizar para lograr auditoría | Se puede utilizar para lograr auditoría si se utiliza de manera eficiente. |
| Suficiente para estructuras y flujos complicados. | No es suficiente; puedes perderte en el flujo. | Suficiente |
| Productividad | Menos productivo | Más productivo |
Como puede ver arriba, el uso del mecanismo de registro será más eficiente y tendrá un menor costo de mantenimiento. Apache Log4j es la herramienta líder para el registro en aplicaciones Java, por lo que debería usarla.
Arquitectura Log4j2
Antes de continuar con el tutorial de ejemplo de Log4j, es bueno analizar la arquitectura de Log4j2. La siguiente imagen muestra las clases importantes de la API de Log4j2. Aquí se incluye una explicación detallada de la arquitectura que se muestra arriba:
-
Las aplicaciones solicitarán
LogManagerunLoggernombre específico. -
LogManagerlocalizará el apropiadoLoggerContexty luegoLoggerlo obtendrá. -
Si aún no se ha creado el registrador, se creará y se asociará con LoggerConfig según las tres opciones siguientes:
- Se creará una instancia de Logger y se asociará con el LoggerConfig que tenga el mismo nombre. Por ejemplo, App.class
getLogger(App.class)se evaluará como una Stringcom.journaldev.App. El nombre de LoggerConfig es idéntico al nombre de clase completo (componente de software). - Se creará una instancia de Logger y se asociará con LoggerConfig que tenga el mismo paquete principal de Loggers. Por ejemplo,
com.journaldevengetLogger("com.journaldev") - Se creará una instancia del registrador y se asociará con Root LoggerConfig . Root LoggerConfig se utilizará cuando no haya un archivo de configuración o cuando se obtenga un registrador con un nombre no definido en las declaraciones del registrador.
- Se creará una instancia de Logger y se asociará con el LoggerConfig que tenga el mismo nombre. Por ejemplo, App.class
-
LoggerConfigLos objetos se crean a partir de la declaración de Logger en el archivo de configuración. LoggerConfig también se utiliza para manejarlosLogEventsy delegarlos para sus Appenders Log4j2 definidos . -
El registrador raíz es un caso excepcional en cuanto a su existencia. Siempre existe y se encuentra en la cima de cualquier jerarquía de registradores.
-
Puede obtener el registrador raíz utilizando las siguientes declaraciones:
Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);Logger logger = LogManager.getRootLogger(); -
Los nombres de los registradores log4j2 distinguen entre mayúsculas y minúsculas.
-
A excepción del registrador raíz, todos los registradores se pueden obtener pasando su nombre a
LogManager.getLogger(). -
LoggerContext es un punto de referencia para el sistema de registro, ya que puede tener varios LoggerContext dentro de su aplicación. Se debe establecer una configuración activa para cada LoggerContext.
-
La configuración de Log4j2 contiene todos los activos del sistema de registro: LoggerConfig(s), Appender(s), Filter(s) y muchos otros.
-
Llamar a LogManager.getLogger() pasando el mismo nombre siempre devolverá la referencia para la misma instancia exacta del registrador.
-
La configuración del sistema de registro se realiza normalmente con la inicialización de la aplicación. Esto puede realizarse de distintas formas: mediante programación o leyendo un archivo de configuración log4j2.
Cada registrador está asociado con un objeto LoggerConfig, un conjunto de objetos LoggerConfig que forman una jerarquía de registradores. Este concepto se conoce como jerarquía de registradores . La jerarquía de registradores está formada por un conjunto de objetos LoggerConfig con una relación padre-hijo. El elemento superior de cada jerarquía de registradores es el registrador raíz. Si Log4j2 no encuentra el archivo de configuración, solo se utilizará el registrador raíz para el registro con el nivel de registro como ERROR. La siguiente imagen muestra el mensaje de advertencia que recibirá en este caso. Error StatusLogger No se encontró el archivo de configuración de log4j2. Uso de la configuración predeterminada: registro solo de errores en la consola. La siguiente tabla muestra la relación padre-hijo en la jerarquía de registradores.
| LoggerConfig (es un) | Raíz | con | com.journaldev | com.journaldev.logging |
|---|---|---|---|---|
| Raíz | incógnita | Niño | descendiente | descendiente |
| con | Padre | incógnita | Niño | descendiente |
| com.journaldev | Antepasado | Padre | incógnita | Niño |
| com.journaldev.logging | Antepasado | Antepasado | Padre | incógnita |
Para aclarar la relación padre-hijo, la tabla anterior se leería de la siguiente manera:
- Root es el padre de com.
- Root es un antecesor de com.journaldev.
- Root es un antecesor de com.journaldev.logging.
- com es un hijo de Root.
- com es un padre de com.journaldev.
- com es un antecesor de com.journaldev.logging.
- com.journaldev.logging es un hijo de com.journaldev y así sucesivamente.
Se dice que una instancia de LoggerConfig es un antecesor de otro LoggerConfig si su nombre seguido de un punto es un prefijo para el nombre del descendiente. Se dice que una instancia de LoggerConfig es un padre de otro LoggerConfig si no hay nombres intercalados entre ambos.
Configuración de Log4j2
Hay muchas formas de utilizar la configuración de Log4j2 en su aplicación.
- Utilizando un archivo de configuración escrito en XML, JSON, YAML o archivo de propiedades.
- Mediante programación, mediante la creación de una fábrica de configuración y la implementación de la configuración.
- Programáticamente, llamando a las API expuestas en la interfaz de configuración.
- Programáticamente, llamando a métodos en la clase del registrador interno.
Nos centraremos principalmente en el archivo de configuración. Sin embargo, también es bueno conocer el enfoque de programación, en caso de que desee configurar una estrategia de registro específica para algún registrador específico. En primer lugar, consideremos el caso en el que no proporcionó un archivo de configuración. La implementación de Log4j2 supone que existe una variable del sistema llamada log4j.configurationFile para indicar la ubicación del archivo de configuración de Log4j2.
package com.journaldev;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;public class App{ public static void main( String[] args ) { Logger logger = LogManager.getRootLogger(); logger.trace("Configuration File Defined To Be :: "+System.getProperty("log4j.configurationFile")); }}
Un archivo de configuración log4j2 simple se verá como el siguiente: configuration.xml:
?xml version="1.0" encoding="UTF-8"?Configuration Appenders Console name="Console" PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/ /Console /Appenders Loggers Root level="trace" AppenderRef ref="Console"/ /Root /Loggers/Configuration
Y aquí está la explicación detallada del código mencionado anteriormente:
- La aplicación ha hecho referencia al registrador raíz llamando
getRootLoggeral método LogManager. - La referencia del registrador desde LogManager ha iniciado el sistema Log4j.
- Log4j inspeccionará la propiedad del sistema log4j.configurationFile para determinar el archivo de configuración log4j2. La configuración de Log4j se puede escribir en JSON, YAML y XML.
- Podemos configurar la propiedad del sistema log4j.configurationFile a través de
System.setProperties("log4j.configurationFile","FILE_PATH")o pasándola como un parámetro de JVM como se ve en la figura siguiente. Observe también el prefijo del protocolo de archivo.
- En caso de que no se defina ninguna propiedad del sistema, el orden de configuración tendrá prioridad a continuación:
- La propiedad ConfigurationFactory la buscará
log4j2-test.propertiesen el classpath. - YAML ConfigurationFactory buscará log4j2-test.yaml o log4j2-test.yml en la ruta de clase.
- JSON ConfigurationFactory buscará log4j2-test.jsn o log4j2-test.json en el classpath.
- XML ConfigurationFactory buscará log4j2-test.xml en el classpath.
- La propiedad ConfigurationFactory buscará
log4j2.propertiesen el classpath - YAML ConfigurationFactory buscará log4j2.yml o log4j2.yaml en la ruta de clase.
- JSON ConfigurationFactory buscará log4j2.jsn o log4j2.json en el classpath.
- XML ConfigurationFactory buscará log4j2.xml en el classpath.
- Si no se proporcionó ningún archivo de configuración, se ejecuta la configuración predeterminada y esto lo llevará a un conjunto de comportamientos predeterminados:
- Se utilizará el registrador raíz.
- El nivel del registrador raíz se establecerá en ERROR .
- El registrador raíz propagará mensajes de registro en la consola.
- PatternLayout está configurado para ser
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
- La propiedad ConfigurationFactory la buscará
El uso del archivo de configuración log4j2 hace que la configuración de log4j2 sea muy sencilla, pero veamos cómo podemos configurarlo mediante programación. Se trata de usar ConfigurationFactory.
package com.journaldev;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import org.apache.logging.log4j.Level;import org.apache.logging.log4j.core.Logger;import org.apache.logging.log4j.core.LoggerContext;import org.apache.logging.log4j.core.appender.ConsoleAppender;import org.apache.logging.log4j.core.config.Configuration;import org.apache.logging.log4j.core.config.ConfigurationFactory;import org.apache.logging.log4j.core.config.ConfigurationSource;import org.apache.logging.log4j.core.config.LoggerConfig;import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory;import org.apache.logging.log4j.core.layout.PatternLayout;public class App{ public static void main( String[] args ) throws FileNotFoundException, IOException { // Get instance of configuration factory; your options are default ConfigurationFactory, XMLConfigurationFactory, // YamlConfigurationFactory JsonConfigurationFactory ConfigurationFactory factory = XmlConfigurationFactory.getInstance(); // Locate the source of this configuration, this located file is dummy file contains just an empty configuration Tag ConfigurationSource configurationSource = new ConfigurationSource(new FileInputStream(new File("C:/dummyConfiguration.xml"))); // Get a reference from configuration Configuration configuration = factory.getConfiguration(configurationSource); // Create default console appender ConsoleAppender appender = ConsoleAppender.createDefaultAppenderForLayout(PatternLayout.createDefaultLayout()); // Add console appender into configuration configuration.addAppender(appender); // Create loggerConfig LoggerConfig loggerConfig = new LoggerConfig("com",Level.FATAL,false); // Add appender loggerConfig.addAppender(appender,null,null); // Add logger and associate it with loggerConfig instance configuration.addLogger("com", loggerConfig); // Get context instance LoggerContext context = new LoggerContext("JournalDevLoggerContext"); // Start logging system context.start(configuration); // Get a reference for logger Logger logger = context.getLogger("com"); // LogEvent of DEBUG message logger.log(Level.FATAL, "Logger Name :: "+logger.getName()+" :: Passed Message ::"); // LogEvent of Error message for Logger configured as FATAL logger.log(Level.ERROR, "Logger Name :: "+logger.getName()+" :: Not Passed Message ::"); // LogEvent of ERROR message that would be handled by Root logger.getParent().log(Level.ERROR, "Root Logger :: Passed Message As Root Is Configured For ERROR Level messages"); }}
- Puede utilizar cualquiera de los ConfigurationFactory proporcionados por Log4j2 o utilizar el predeterminado. Hemos utilizado
XMLConfigurationFactorypara obtener una instancia de ConfigurationFactory. - Factory le proporcionará una instancia de la referencia de configuración requerida pasándole el archivo de configuración correspondiente.
- La instancia de configuración se utilizará junto con LoggerContext para iniciar el sistema de registro.
- Se ha configurado un Appender de consola y se ha agregado a la instancia de configuración con el diseño predeterminado. Este Appender imprimirá mensajes en su consola.
- Se ha creado una instancia de LoggerConfig con el nombre y el NIVEL proporcionados y sin utilizar ningún filtro. El apéndice creado se asignará a esta instancia de LoggerConfig.
- Se agregó instancia de LoggerConfig a la instancia de configuración.
- Se crea una nueva instancia de LoggerContext con el nombre definido.
- La instancia de configuración se ha pasado para la instancia de LoggerContext y se invoca el inicio en esta última.
- Se ha adquirido una instancia de registrador de LoggerContext. Esta instancia de registrador se utilizará para activar un conjunto de eventos de registro.
- La instancia del registrador ha activado tres eventos que se explicarán en la sección Niveles de Log4j2.
- com logger se ha configurado para imprimir mensajes cuyos niveles sean FATALES.
- De forma predeterminada, Root logger está configurado para imprimir mensajes cuyos niveles son ERROR.
- Los mensajes de ERROR no serán registrados por el registrador ‘com’ porque su nivel es FATAL.
La misma configuración se puede realizar mediante el uso de YAML, JSON o archivo de propiedades. Sin embargo, la configuración del archivo de propiedades de log4j2 es diferente de la del archivo de propiedades de log4j, así que asegúrese de no intentar usar la configuración del archivo de propiedades de log4j con log4j2. Se generará el siguiente error:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
Al procesar el código anterior obtendría el siguiente resultado:
Logger Name :: com :: Passed Message ::00:01:27.705 [main] ERROR - Root Logger:: Passed Message As Root Is Configured For ERROR Level messages
La primera línea de registros es de com logger y la segunda es de Root Logger. El mensaje de error de com logger no se imprime porque su nivel es Fatal.
Niveles de Log4j2
En los ejemplos de código anteriores, puede ver que cada vez que definimos un LoggerConfig, también proporcionamos el nivel de registro. De forma predeterminada, el registro de log4j2 es aditivo. Esto significa que todos los registradores principales también se utilizarán cuando se utilice un registrador específico. La siguiente imagen aclara esta situación. Y aquí se incluyen puntos de aclaración:
- Como hemos indicado anteriormente, cada registrador se ha asociado con una instancia de LoggerConfig. Esta loggerConfig se ha definido en el ámbito de configuración.
- El nivel de registro se puede determinar en el ámbito LoggerConfig.
- Puede obtener el registrador por su nombre, paquete principal o apuntando al registrador raíz mismo.
- Root Logger es el nodo de nivel superior para cada jerarquía de LoggerConfig.
- Una vez que obtenga el
com.journaldevregistrador e inicie un logEvent para el registro, loggerConfig (net.journaldev) registrará el mensaje y este se propagará también hacia arriba en la jerarquía sin tener en cuenta los niveles de registro de los padres. Por lo tanto, el evento de registro se propagará a los registradores com y Root y también registrarán el mensaje respectivamente de acuerdo con los niveles definidos. - Una vez que obtenga el registrador com e inicie un logEvent para el registro, loggerConfig(com) registrará el mensaje y este se propagará hacia arriba en la jerarquía sin tener en cuenta los niveles de registro de los padres. Es decir, el registrador raíz propagará el evento de registro y también registrará el mensaje.
- El mismo caso para la jerarquía net.journaldev.
- En las siguientes secciones se agregarán más aclaraciones sobre el concepto aditivo.
- Existe la posibilidad de que el padre ignore el mensaje utilizando el concepto de filtro o configurando el indicador aditivo en falso, de modo que los eventos de registro no se propaguen a los padres.
- Existe la posibilidad de que el registrador ignore el mensaje si el nivel de loggerConfig respectivo es MAYOR QUE el nivel de eventos de registro.
Ahora, veamos el ejemplo que está asociado con el concepto de aditividad explicado anteriormente:
import net.NetApp;import net.journaldev.NetJournalDevApp;import com.ComApp;import com.journaldev.ComJournalDevApp;public class Main {public static void main(String [] args){new ComApp();new ComJournalDevApp();new NetApp();new NetJournalDevApp();}}
package com.journaldev;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;public class ComJournalDevApp {public ComJournalDevApp(){Logger logger = LogManager.getLogger(ComJournalDevApp.class);logger.trace("COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::");}}
package net;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;public class NetApp {public NetApp(){Logger logger = LogManager.getLogger(NetApp.class);logger.error("NET :: LEVEL :: NetApp ERROR Message ::");}}
package net.journaldev;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;public class NetJournalDevApp {public NetJournalDevApp(){Logger logger = LogManager.getLogger(NetJournalDevApp.class);logger.error("NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::");}}
Mientras que el archivo de configuración log4j2 se ve así:
?xml version="1.0" encoding="UTF-8"?Configuration Appenders Console name="Console" PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/ /Console /Appenders Loggers Root level="ERROR" AppenderRef ref="Console"/ /Root logger name="com" level="TRACE" AppenderRef ref="Console"/ /logger logger name="com.journaldev" level="TRACE" AppenderRef ref="Console"/ /logger logger name="net" level="ERROR" AppenderRef ref="Console"/ /logger logger name="net.journaldev" level="ERROR" AppenderRef ref="Console"/ /logger /Loggers/Configuration
Si ejecuta la clase principal, encontrará los siguientes resultados:
10:34:47.168 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::10:34:47.168 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::10:34:47.170 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::10:34:47.170 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::10:34:47.170 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::10:34:47.171 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::10:34:47.171 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::10:34:47.171 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::10:34:47.171 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::10:34:47.171 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
A continuación se muestra una explicación detallada del código mencionado anteriormente:
- El archivo de configuración contiene cinco instancias de loggerConfig definidas: Root, com, com.journaldev, net y net.journaldev. Tal como la jerarquía de registradores que se muestra arriba.
- El nivel de raíz está configurado para ser ERROR y ese es en realidad el valor predeterminado.
- Los niveles com y com.journaldev están configurados para ser TRACE.
- Los niveles net y net.journaldev están configurados para ser ERROR.
- Es posible que hayas notado que los mensajes de los registradores ComAPP y ComJournalDevApp se han mostrado dos y tres veces respectivamente. Estos mensajes se muestran de acuerdo con la jerarquía de registradores de ComApp y ComJournalDevApp, donde se encuentran en los paquetes com y com.journalDev respectivamente. Tenemos un caso similar con las clases NetApp y NetJournalDevApp.
- Los padres se propagan ya que el indicador aditivo se establece en verdadero de forma predeterminada.
El espacio de registro tiene en cuenta los niveles de los eventos de registro y el nivel de loggerConfig además de la jerarquía del registrador.
¿Y qué pasa si cambiamos LoggerConfig para com a INFO y dejamos todo el programa como está?
?xml version="1.0" encoding="UTF-8"?Configuration Appenders Console name="Console" PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/ /Console /Appenders Loggers Root level="ERROR" AppenderRef ref="Console"/ /Root logger name="com" level="INFO" AppenderRef ref="Console"/ /logger logger name="com.journaldev" level="TRACE" AppenderRef ref="Console"/ /logger logger name="net" level="ERROR" AppenderRef ref="Console"/ /logger logger name="net.journaldev" level="ERROR" AppenderRef ref="Console"/ /logger /Loggers/Configuration
Entonces el resultado sería como el siguiente:
11:08:10.305 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::11:08:10.305 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::11:08:10.305 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::11:08:10.307 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::11:08:10.307 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::11:08:10.308 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::11:08:10.308 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::11:08:10.308 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
- Seguramente notarás que el evento de registro de ComAPP se ha ignorado y eso se debe al nivel definido de loggerConfig para el paquete com. El nivel INFO (400) es menor que el nivel del evento de registro, que aquí es TRACE(600). Por lo tanto, el mensaje de ComApp ya no se mostrará y para que se muestre, debes modificar el nivel de LoggerConfig para com para que sea TRACE(600) o ALL(Integer.MAX_VALUE).
Para asegurarse de que se hayan mostrado los eventos de registro, el nivel de LoggerConfig debe ser mayor o igual al nivel del evento de registro.
La siguiente tabla muestra los niveles de log4j2 y el peso de cada uno de ellos:
| NIVEL | Peso |
|---|---|
| APAGADO | 0 |
| FATAL | 100 |
| ERROR | 200 |
| ADVERTIR | 300 |
| INFORMACIÓN | 400 |
| DEPURAR | 500 |
| RASTRO | 600 |
| TODO | Entero.MAX_VALUE |
Seguramente la tabla anterior aclara mucho más que las palabras y brinda la causa principal por la cual el evento de registro TRACE no se muestra mientras el nivel de LoggerConfig es INFO.
Tenga en cuenta que la propagación de eventos de registro en la jerarquía del registrador está más allá de este cálculo e ignora los niveles.
Pero, ¿qué sucede si eliminamos LoggerConfig de com.journaldev de la configuración y agregamos uno nuevo para com.journaldev.logging para que el archivo de configuración se vea como se muestra a continuación?
?xml version="1.0" encoding="UTF-8"?Configuration Appenders Console name="Console" PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/ /Console /Appenders Loggers Root level="ERROR" AppenderRef ref="Console"/ /Root logger name="com" level="TRACE" AppenderRef ref="Console"/ /logger logger name="com.journaldev.logging" level="TRACE" AppenderRef ref="Console"/ /logger logger name="net" level="ERROR" AppenderRef ref="Console"/ /logger logger name="net.journaldev" level="ERROR" AppenderRef ref="Console"/ /logger /Loggers/Configuration
Puede que la siguiente figura le resulte más útil para comprender lo que sucedió en la configuración de log4j2 anterior. A continuación, se ofrecen algunas aclaraciones sobre la figura que se muestra arriba y cómo puede afectar el comportamiento de los eventos de registro:
- Cuando los eventos de registro son lanzados por un Logger llamado com.journaldev.logging, el LoggerConfig asociado con ese nombre (es decir, com.journaldev.logging) se ha utilizado para manejarlo e imprimir el mensaje.
- Como el atributo aditivo de LoggerConfig com.journaldev.logging está establecido de manera predeterminada en verdadero, el evento de registro se ha propagado para el padre que, en este caso, hace referencia a com.journaldev.
- Como com.journaldev LoggerConfig no está definido en la configuración, no ocurre ninguna acción y el evento Log se propagará hasta las instancias com y luego a Root LoggerConfig.
- Com Root recibirá el evento de registro y lo imprimirá independientemente del nivel con el que se envíe.
Como resultado de los puntos mencionados, verás los siguientes resultados:
14:08:37.634 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::14:08:37.634 [main] TRACE com.ComApp - COM :: LEVEL :: ComApp TRACE Message ::14:08:37.636 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::14:08:37.636 [main] TRACE com.journaldev.ComJournalDevApp - COM :: JournalDev :: LEVEL :: ComJournalDevApp TRACE Message ::14:08:37.637 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::14:08:37.637 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::14:08:37.637 [main] TRACE com.journaldev.logging.ComJounralDevLoggingApp - COM :: JournalDev :: LOGGING :: LEVEL :: ComJounralDevLoggingApp TRACE Message ::14:08:37.638 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::14:08:37.638 [main] ERROR net.NetApp - NET :: LEVEL :: NetApp ERROR Message ::14:08:37.640 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::14:08:37.640 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::14:08:37.640 [main] ERROR net.journaldev.NetJournalDevApp - NET :: JournalDev :: LEVEL :: NetJournalDevApp ERROR Message ::
Y es posible que notes lo siguiente:
- El evento de registro en el paquete com se ha mostrado dos veces. Una para com y la segunda para Root.
- El evento de registro en com.journaldev se ha mostrado dos veces. Una para com y la segunda para Root. Aunque antes se mostraba tres veces, por ahora no hay LoggerConfig de com.journaldev, por lo que es posible que no se haya producido ningún registro en el paquete com.journaldev y el evento se haya propagado para com y Root.
- El evento de registro en com.journaldev.logging se ha mostrado tres veces, una para el paquete com.journaldev.logging, la segunda para com y la tercera para Root. Según la propagación de la jerarquía de registradores, debería mostrarse cuatro veces, pero debido a la ausencia de com.journaldev LoggerConfig, se muestra tres veces.
En caso de que haya definido una instancia de LoggerConfig com.journaldev sin ningún nivel especificado, heredará el nivel de su padre.
Pero, ¿qué sucede si definió com.journaldev LoggerConfig en su archivo de configuración y olvidó especificar el nivel de LoggerConfig? Afortunadamente, el concepto de jerarquía de registradores lo salvará en este caso y com.journaldev heredará su valor de nivel de su padre. A continuación, se incluye un archivo de configuración de muestra seguido de la tabla para el nivel de registro de cada configuración de registrador.
?xml version="1.0" encoding="UTF-8"?Configuration Appenders