"¡Oh, ahí estás! ¿Recordaste que tenemos otra lección hoy?"

"No, solo te estaba buscando. Casi..."

"Excelente, entonces comencemos. Hoy quiero hablarles sobre el registro".

"El registro es una lista de los eventos que han ocurrido. Casi como el registro de un barco o un diario. O Twitter, tal vez puedas identificarte mejor con eso. Como era de esperar, un registrador es un objeto que usas para registrar".

"En programación, se acostumbra registrar casi todo. Y en Java, registramos todo e incluso un poco más".

"El hecho es que los programas Java suelen ser grandes aplicaciones de servidor sin interfaz de usuario, consola, etc. Procesan miles de solicitudes de usuarios al mismo tiempo y, a menudo, hay varios errores. Especialmente cuando diferentes subprocesos comienzan a interferir entre sí".

"De hecho, la única forma de buscar errores y fallas raramente reproducibles en estas circunstancias es registrar todo lo que sucede en cada subproceso".

"La mayoría de las veces, el registro contiene información sobre los argumentos del método, los errores detectados y mucha información intermedia".

"Cuanto más completo sea el registro, más fácil será reproducir una secuencia de eventos y rastrear las causas de fallas o errores".

"A veces, los registros alcanzan varios gigabytes por día. Esto es normal".

"¿Unos cuantos gigas? O_o"

"Sí. La mayoría de las veces, los archivos de registro se archivan automáticamente, con una indicación de la fecha relevante".

"Guau".

"Ajá. Inicialmente, Java no tenía su propio registrador. Como resultado, se escribieron varios registradores independientes. El más común de ellos fue log4j".

"Unos años más tarde, Java obtuvo un registrador propio, pero su funcionalidad era muy inferior y no se usaba mucho".

"Es un hecho que Java tiene un registrador oficial, pero toda la comunidad de programadores de Java prefiere usar otros registradores " .

"Más tarde, se escribieron varios registradores más basados ​​en log4j".

"Luego, se escribió para todos ellos el registrador universal especial slf4j, que ahora se usa ampliamente. Es muy similar a log4j, así que lo usaré como ejemplo cuando explique el registro".

"Todo el proceso de registro consta de tres partes".

" Primero , recopilar información".

" En segundo lugar , filtrar la información recopilada".

" Tercero , registre la información seleccionada".

"Comencemos con la colección. Aquí hay un ejemplo típico de una clase que registra:"

Clase con registro
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.complete();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

"Presta atención a las palabras resaltadas en rojo".

" Línea 3  : cree el objeto registrador . ¡Este objeto estático se crea en casi todas las clases! Bueno, excepto en las clases que no hacen nada más que almacenar datos".

" LoggerFactory es una clase especial para crear registradores, y getLogger es uno de sus métodos estáticos. Por lo general, se pasa el objeto actual, pero son posibles varias opciones".

" Línea 7 : la información sobre la llamada al método se escribe en el registrador. Tenga en cuenta que esta es la primera línea del método. Tan pronto como se llama al método, inmediatamente escribimos información en el registro".

"Llamamos al método de depuración, lo que significa que la importancia de la información es el nivel DEBUG. Esto se usa para filtrar. Te lo contaré en un par de minutos".

" Línea 17 : capturamos una excepción y... ¡la escribimos inmediatamente en el registro! Esto es exactamente lo que se debe hacer".

"Esta vez llamamos al método de error, que inmediatamente indica que la información es de nivel ERROR"

Registrador - 1

"Todo parece claro por ahora. Bueno, en la medida en que pueda quedar claro en medio de nuestra conversación".

"Genial, entonces pasemos al filtrado de mensajes".

"Por lo general, cada mensaje de registro tiene su propio nivel de importancia, que puede usar para descartar algunos de los mensajes. Estos son los niveles de importancia que mencioné:"

Nivel de importancia Descripción
TODO Todos los mensajes
RASTRO Mensajes de depuración detallados
DEPURAR Mensajes de depuración importantes
INFORMACIÓN Mensajes informativos
ADVERTIR Advertencias
ERROR errores
FATAL Errores fatales
APAGADO Ningún mensaje

Estos niveles también se utilizan al filtrar mensajes.

Suponga que establece el nivel de registro en WARN. Entonces todos los mensajes que sean menos importantes que WARN serán descartados: TRACE, DEBUG, INFO.

Si establece el nivel de filtrado en FATAL, incluso los mensajes de ERROR se descartarán.

"Hay dos niveles de importancia más que se usan al filtrar: APAGADO, que descarta todos los mensajes; y TODOS, que muestra todos los mensajes (no se descarta nada)".

"¿Cómo y dónde configuro el filtrado?"

"Te lo diré sin más preámbulos".

"Por lo general, la configuración del registrador log4j se especifica en el archivo log4j.properties".

Puede especificar varios objetos appender en este archivo. Los datos se escriben en estos objetos. Hay fuentes de datos y agregadores: objetos que tienen propósitos opuestos. Objetos en los que fluyen los datos como el agua.

"Aquí hay unos ejemplos:"

Iniciar sesión en la consola
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

Líneas 1 y 4 – Estos son comentarios

Línea 2 – Indicamos el nivel de registro que queremos. Todos los niveles menos importantes (DEBUG, TRACE) serán descartados.

En el mismo lugar, agregamos una coma y luego indicamos el nombre del objeto (que creamos nosotros mismos) en el que se escribirá el registro. Las líneas 5-9 contienen su configuración.

Línea 5: especificamos el tipo de appender ( ConsoleAppender ).

Línea 6 – Indicamos exactamente donde estamos escribiendo ( System.out. ).

Línea 7: configuramos la clase que administrará los patrones de conversión (PatternLayout).

Línea 8: establecemos el patrón de conversión que se utilizará para escribir. En el ejemplo anterior, es la fecha y la hora.

"Y así es como se ve escribir en un archivo:"

Iniciar sesión en un archivo
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

"La línea 2 establece el nivel de filtrado de mensajes y el nombre del objeto agregador (sumidero)".

"Línea 5: especificamos el tipo de agregador de archivos ( RollingFileAppender )".

"Línea 6: especificamos el nombre del archivo en el que se escribirá el registro".

"Línea 7: especificamos el tamaño máximo de registro. Cuando se supera este límite de tamaño, se crea un nuevo archivo".

"Línea 8: especificamos la cantidad de archivos de registro antiguos que se almacenarán".

"Líneas 9-10: establezca el patrón de conversión".

"No sé qué está pasando aquí, pero puedo adivinar. Eso es alentador".

"Eso es genial. Entonces aquí hay un ejemplo de cómo escribir un registro en un archivo y la consola:"

Iniciar sesión en la consola y un archivo
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

"Ah, ¿así que puedes hacer eso? ¡Eso es genial!"

"Sí. Puedes declarar tantos appenders como quieras y personalizar cada uno".

Además, cada agregador puede tener configuraciones muy flexibles para el filtrado de mensajes. ¡No solo podemos asignar un nivel de filtrado de mensajes individual a cada agregador, sino que también podemos filtrar mensajes por paquete! Es por eso que necesita especificar una clase al crear un registrador (estoy hablando de LoggerFactory.getLogger ).

"Por ejemplo:"

Iniciar sesión en la consola y un archivo
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

"Líneas 6 y 15: establecemos nuestro propio nivel de filtrado para cada agregador".

"Líneas 20-23: especificamos el nombre del paquete y el nivel de filtrado de sus mensajes. Log4j.logger es un prefijo: el nombre del paquete está resaltado en naranja".

"¿En serio? Incluso puedes hacer eso. Bueno, ¡genial!"

"Por cierto, ni log4j ni slf4j están incluidos en el JDK. Deberá descargarlos por separado. Puede hacerlo aquí . Pero hay otra manera:"

" Paso 1. Agregar importaciones a la clase:"

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

" Paso 2. Coloque el cursor sobre estas líneas y presione Alt+Enter en IntelliJ IDEA"

Paso 3. Elija el elemento de menú 'Archivo jar en la web'.

" Paso 4. Elija 'slf4j-log4j13.jar'"

" Paso 5. Especificar dónde descargar la biblioteca (jar)"

" Paso 6. Usa las clases que necesites".

"¡Vaya! ¡Qué día ha sido este! ¡Hay tantas cosas nuevas y tantas cosas geniales!"

"Aquí hay otro buen artículo sobre registro: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC "

"Está bien, eso es suficiente. Ve a relajarte, programador".