2.1 Primer registrador - log4j

Como ya sabes, la historia de los registros comenzó con System.err.println()la salida de un registro a la consola. Todavía se usa activamente para la depuración, por ejemplo, Intellij IDEA lo usa para mostrar mensajes de error en la consola. Pero esta opción no tiene ninguna configuración, así que sigamos adelante.

El primer registrador y el más popular se llamaba Log4j. Era una solución buena y altamente personalizable. Debido a diversas circunstancias, esta decisión nunca llegó al JDK, lo que molestó mucho a toda la comunidad.

Este registrador no solo podía iniciar sesión, sino que fue creado por programadores para programadores y les permitió resolver los problemas que surgían constantemente en relación con el registro.

Como ya sabe, los registros se escriben al final para que alguna persona los lea e intente comprender qué sucedió durante la operación del programa: qué y cuándo salió mal como se esperaba.

Había log4jtres cosas para esto:

  • registro de subpaquetes;
  • conjunto de appenders (resultados);
  • Configuración de recarga en caliente.

En primer lugar, la configuración log4jpodría escribirse de tal manera que permita iniciar sesión en un paquete y deshabilitarlo en otro. Por ejemplo, era posible habilitar el inicio de sesión en com.codegym.server, pero deshabilitarlo en com.codegym.server.payment. Esto hizo posible eliminar rápidamente información innecesaria del registro.

En segundo lugar, log4jpermitía escribir los resultados del registro en varios archivos de registro a la vez. Y la salida a cada uno podría configurarse individualmente. Por ejemplo, en un archivo era posible escribir solo información sobre errores graves, en otro, registros de un módulo específico y en un tercero, registros durante un tiempo determinado.

Por lo tanto, cada archivo de registro se ajustó a un tipo particular de problema esperado. Esto simplifica enormemente la vida de los programadores que no disfrutan mirando manualmente los archivos de registro de gigabytes.

Y finalmente, en tercer lugar, log4jpermitía cambiar la configuración del registro directamente mientras el programa se estaba ejecutando, sin reiniciarlo. Esto fue muy útil cuando era necesario corregir el trabajo de los registros para encontrar información adicional sobre un error específico.

¡Importante! Hay dos versiones del registro log4j: 1.2.xy 2.xx , que son incompatibles entre sí .

Puede conectar el registrador al proyecto usando el código:

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
  </dependency>

  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
  </dependency>
</dependencies>

2.2 Primer registrador oficial - JUL: java.util.logging

Después de que apareció el zoológico de registradores en la comunidad de Java, los desarrolladores JDKdecidieron crear un registrador estándar que todos usarían. Así es como apareció el registrador JUL: paquete java.util.logging.

Sin embargo, durante su desarrollo, los creadores del registrador tomaron como base no log4j, sino una variante del registrador de IBM, lo que influyó en su desarrollo. La buena noticia es que el registrador JULestá incluido JDK, la mala noticia es que pocas personas lo usan.

JUL

Los desarrolladores no solo JULcrearon “otro estándar universal” , sino que también crearon sus propios niveles de registro, que diferían de los aceptados por los registradores populares en ese momento.

Y eso fue un gran problema. Después de todo, los productos Javaa menudo se recopilan de una gran cantidad de bibliotecas, y cada una de esas bibliotecas tenía su propio registrador. Por lo que fue necesario configurar todos los registradores que se encuentran en la aplicación.

Aunque el registrador en sí es bastante bueno. Crear un registrador es más o menos lo mismo. Para hacer esto, necesita importar:


java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());

El nombre de la clase se pasa especialmente para saber de dónde proviene el registro.

Solo con el lanzamiento, los desarrolladores resolvieron problemas importantes, después de lo cual JULes realmente conveniente de usar. Antes de eso, era una especie de registrador de segunda categoría.

Este registrador también admite expresiones lambda y evaluación diferida. A partir de Java 8, puede pasar Supplier<String>. Esto ayuda a leer y crear una cadena solo en el momento en que realmente se necesita, y no siempre, como ocurría antes.

Los métodos con un argumento Supplier<String> msgSupplierse ven así:

public void info(Supplier msgSupplier) {
   log(Level.INFO, msgSupplier);
}

2.3 Primera envoltura de registrador - JCL: registro de jakarta commons

Durante mucho tiempo no hubo un estándar único entre los madereros, JULdebería haberse convertido en uno, pero fue peor log4j, por lo que nunca apareció un estándar único. Pero apareció todo un zoológico de madereros, cada uno de los cuales quería volverse el mismo.

JCL

Sin embargo, a los desarrolladores comunes de Java no les gustó que casi todas las bibliotecas tengan su propio registrador y deban configurarse de alguna manera especial. Por lo tanto, la comunidad decidió crear un envoltorio especial sobre otros registradores: así es comoJCL: jakarta commons logging

Y nuevamente, el proyecto, que fue creado para ser un líder, no se convirtió en uno. No puedes crear un ganador, solo puedes convertirte en un ganador. La funcionalidad JCLera muy pobre y nadie quería usarla. El registrador, diseñado para reemplazar a todos los registradores, corrió la misma suerte ya que JULno se usó.

Aunque se ha agregado a muchas bibliotecas lanzadas por la comunidad Apache, el zoológico de registradores solo ha crecido.

2.4 Primero último registrador - Inicio de sesión

Pero eso no es todo. El desarrollador log4jdecidió que él era el más inteligente (bueno, porque la mayoría de la gente usaba su registrador) y decidió escribir un nuevo registrador mejorado que combinaría las ventajas log4jde otros registradores.

El nuevo registrador fue llamado Logback. Era este registrador el que se suponía que se convertiría en el futuro registrador único que todos usarían. Se basó en la misma idea que en log4j.

Puede conectar este registrador al proyecto usando el código:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

Las diferencias estaban en Logback:

  • desempeño mejorado;
  • soporte nativo añadido slf4j;
  • opción de filtrado ampliada.

Otra ventaja de este registrador era que tenía una configuración predeterminada muy buena. Y tenía que configurar el registrador solo si quería cambiar algo en ellos. Además, el archivo de configuración se adaptó mejor al software corporativo: todas sus configuraciones se establecieron como xml/.

De forma predeterminada, Logbackno requiere ninguna configuración y registra todos los registros del nivel DEBUGy superior. Si necesita un comportamiento diferente, se puede configurar a través de xmlla configuración:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
        </encoder>
    </appender>
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

2.5 Registrador universal más reciente - SLF4J: Simple Logging Facade para Java

¿Cuánto tiempo puede ser para encontrar la media dorada...

En 2006, uno de los creadores log4jabandonó el proyecto y decidió volver a intentar crear un registrador universal. Pero esta vez no se trataba de un nuevo registrador, sino de un nuevo estándar universal (envoltorio) que permitía que diferentes registradores interactuaran entre sí.

Este registrador se llamaba slf4j — Simple Logging Facade for Java, era un envoltorio alrededor de log4j, JUL, common-loggins and logback. Este registrador resolvió un problema real: administrar un zoológico de registradores, por lo que todos comenzaron a usarlo de inmediato.

Solucionamos heroicamente los problemas que nos creamos a nosotros mismos. Como puede ver, el progreso ha llegado al punto de que hemos creado un envoltorio sobre el envoltorio...

La envoltura en sí consta de dos partes:

  • API, que se utiliza en aplicaciones;
  • Implementaciones que se agregan como dependencias separadas para cada registrador.

Puede conectar el registrador al proyecto usando el código:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>

Basta con conectar la implementación correcta y listo: todo el proyecto funcionará con él.

2.6 Optimización en slf4j

Slf4jes compatible con todas las funciones nuevas, como el formato de cadena para el registro . Antes de esto había tal problema. Digamos que desea imprimir un mensaje en el registro:

log.debug("User " + user + " connected from " + request.getRemoteAddr());

Hay un problema con este código. Suponga que su aplicación funciona productiony no escribe nada en el registro DEBUG-messages; sin embargo, el método log.debug()aún se llamará y, cuando se llame, también se llamará a los siguientes métodos:

  • user.toString();
  • request.getRemoteAddr();

Llamar a estos métodos ralentiza la aplicación. Su llamada es necesaria solo durante la depuración, pero se les llama de todos modos.

Desde el punto de vista de la lógica, este problema debía resolverse en la propia biblioteca de registro. Y en la primera versión de log4j apareció la solución:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}

En lugar de una línea para el registro, ahora era necesario escribir tres. Lo que empeoró drásticamente la legibilidad del código y redujo la popularidad de log4j.

El registrador slf4jpudo mejorar ligeramente la situación al ofrecer un registro inteligente. Se veía así:

log.debug("User {} connected from {}", user, request.getRemoteAddr());

donde {}denota la inserción de argumentos que se pasan en el método. Es decir, el primero {}corresponde a usuario, el segundo {}a request.getRemoteAddr().

Estos parámetros se concatenarán en un solo mensaje solo si el nivel de registro permite el registro. No perfecto, pero mejor que todas las otras opciones.

Después de eso, SLF4Jcomenzó a crecer rápidamente en popularidad, por el momento esta es la mejor solución.

Por lo tanto, consideraremos iniciar sesión usando el ejemplo de un paquete slf4j-log4j12.