Desea mirar un marco de registro, y tal vez un marco de fachada de registro.
Existen múltiples marcos de registro, a menudo con funcionalidades superpuestas, tanto que con el tiempo muchos evolucionaron para depender de una API común, o se han utilizado a través de un marco de fachada para abstraer su uso y permitir que se intercambien en su lugar si es necesario.
Marcos
Algunos marcos de registro
Algunas fachadas de registro
Uso
Ejemplo básico
La mayoría de estos marcos te permitirían escribir algo del formulario (aquí usando slf4j-api
y logback-core
):
package chapters.introduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// copied from: http://www.slf4j.org/manual.html
public class HelloWorld {
public static void main(String[] args) {
final Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.debug("Hello world, I'm a DEBUG level message");
logger.info("Hello world, I'm an INFO level message");
logger.warn("Hello world, I'm a WARNING level message");
logger.error("Hello world, I'm an ERROR level message");
}
}
Tenga en cuenta el uso de una clase actual para crear un registrador dedicado, que permitiría que SLF4J / LogBack formatee la salida e indique de dónde proviene el mensaje de registro.
Como se señala en el manual SLF4J , un patrón de uso típico en una clase suele ser:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyClass {
final Logger logger = LoggerFactory.getLogger(MyCLASS.class);
public void doSomething() {
// some code here
logger.debug("this is useful");
if (isSomeConditionTrue()) {
logger.info("I entered by conditional block!");
}
}
}
Pero, de hecho, es aún más común declarar el registrador con el formulario:
private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);
Esto permite que el registrador también se use desde métodos estáticos, y se comparte entre todas las instancias de la clase. Es muy probable que esta sea su forma preferida. Sin embargo, como señaló Brendan Long en los comentarios, desea asegurarse de comprender las implicaciones y decidir en consecuencia (esto se aplica a todos los marcos de registro después de estos modismos).
Hay otras formas de crear instancias de registradores, por ejemplo, mediante el uso de un parámetro de cadena para crear un registrador con nombre:
Logger logger = LoggerFactory.getLogger("MyModuleName");
Niveles de depuración
Los niveles de depuración varían de un marco a otro, pero los más comunes son (en orden de criticidad, de benignos a malos, y probablemente de muy comunes a, con suerte, muy raros):
TRACE
Información muy detallada. Debe escribirse solo en los registros. Se usa solo para rastrear el flujo del programa en los puntos de control.
DEBUG
Información detallada. Debe escribirse solo en los registros.
INFO
Eventos notables de tiempo de ejecución. Debe ser visible de inmediato en una consola, por lo tanto, use con moderación.
WARNING
Runtime rarezas y errores recuperables.
ERROR
Otros errores de tiempo de ejecución o condiciones inesperadas.
FATAL
Errores graves que causan terminación prematura.
Bloques y guardias
Ahora, supongamos que tiene una sección de código donde está a punto de escribir una serie de declaraciones de depuración. Esto podría afectar rápidamente su rendimiento, tanto por el impacto del registro en sí como por la generación de cualquier parámetro que pueda estar pasando al método de registro.
Para evitar este tipo de problema, a menudo desea escribir algo del formulario:
if (LOGGER.isDebugEnabled()) {
// lots of debug logging here, or even code that
// is only used in a debugging context.
LOGGER.debug(" result: " + heavyComputation());
}
Si no hubiera utilizado esta protección antes de su bloque de sentencias de depuración, aunque los mensajes no se envíen (si, por ejemplo, su registrador está configurado actualmente para imprimir solo cosas por encima del INFO
nivel), el heavyComputation()
método aún se habría ejecutado .
Configuración
La configuración depende bastante de su marco de registro, pero ofrecen principalmente las mismas técnicas para esto:
- configuración programática (en tiempo de ejecución, a través de una API, permite cambios en tiempo de ejecución ),
- configuración declarativa estática (en el momento del inicio, generalmente a través de un archivo XML o de propiedades, probablemente sea lo que necesita al principio ).
También ofrecen principalmente las mismas capacidades:
- configuración del formato del mensaje de salida (marcas de tiempo, marcadores, etc.),
- configuración de los niveles de salida,
- configuración de filtros de grano fino (por ejemplo, para incluir / excluir paquetes o clases),
- configuración de apéndices para determinar dónde iniciar sesión (para consola, para archivar, para un servicio web ...) y posiblemente qué hacer con registros más antiguos (por ejemplo, con archivos automáticos).
Aquí hay un ejemplo común de una configuración declarativa, usando un logback.xml
archivo.
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Como se mencionó, esto depende de su marco y puede haber otras alternativas (por ejemplo, LogBack también permite usar un script Groovy). El formato de configuración XML también puede variar de una implementación a otra.
Para obtener más ejemplos de configuración, consulte (entre otros) a:
Un poco de diversión histórica
Tenga en cuenta que Log4J está viendo una actualización importante en este momento, la transición de la versión 1.x de 2.x . Es posible que desee echar un vistazo a ambos para obtener más diversión histórica o confusión, y si elige Log4J, probablemente prefiera ir con la versión 2.x.
Vale la pena señalar, como Mike Partridge mencionó en los comentarios, que LogBack fue creado por un ex miembro del equipo Log4J. Que fue creado para abordar las deficiencias del marco de registro de Java. Y que la próxima versión principal de Log4J 2.x está integrando algunas características tomadas de LogBack.
Recomendación
En pocas palabras, manténgase desacoplado tanto como pueda, juegue con algunos y vea qué funciona mejor para usted. Al final es solo un marco de registro . Excepto si tiene una razón muy específica, además de la facilidad de uso y la preferencia personal, cualquiera de estos sería bastante correcto, por lo que no tiene sentido estar pendiente de él. La mayoría de ellos también se pueden extender a sus necesidades.
Aún así, si tuviera que elegir una combinación hoy, iría con LogBack + SLF4J. Pero si me hubieras preguntado unos años más tarde, te habría recomendado Log4J con Apache Commons Logging, así que vigila tus dependencias y evoluciona con ellas.