¿Qué pasa con el registro en Java? [cerrado]

117

¿Por qué uno usaría uno de los siguientes paquetes en lugar del otro?

  • Registro de Java
  • Registro de bienes comunes
  • Log4j
  • SLF4j
  • Volver a iniciar sesión
Loki
fuente
4
Es posible que desee stackoverflow.com/questions/873051 , que compara SLF4j con Commons Logging.
James McMahon
24
¡¿Por qué diablos ha creado Ceki 3 marcos de registro ?! eso es una locura ...
mP.
6
@mP. - log4j fue el primero, luego surgió un desacuerdo y se escribió slf4j + logback. slf4j es la API y registra la implementación de la API. Independientemente de todo lo demás, slf4j es extremadamente útil.
Thorbjørn Ravn Andersen
3
Para obtener detalles sobre por qué Ceki Gülcü creó SLF4J + Logback, consulte la siguiente charla de Devoxx
bitek
Lo mejor que puede surgir de esto es la API slf4j que, con suerte, unificará el mundo del registro. Creo que logback aún no ha alcanzado una masa crítica con los desarrolladores.
Thorbjørn Ravn Andersen

Respuestas:

86

En orden cronológico de aparición de api (hasta donde yo sé):

  • Log4j porque casi todo el mundo lo usa (en mi experiencia)
  • Commons Logging porque los proyectos de código abierto lo usan (para que puedan integrarse con cualquier marco de registro que se use en la solución integrada); especialmente válido si eres un API / Framework / OSS y confías en otros paquetes que usan Commons Logging.
  • Commons Logging porque no quiere "bloquearse" en un marco de registro en particular (así que, en su lugar, se limita a lo que Commons Logging le brinda); no creo que sea sensato decidir usar este punto como razón.
  • Registro de Java porque no desea agregar un frasco adicional.
  • SLF4j porque es más nuevo que Commons Logging y proporciona registro parametrizado:

logger.debug("The entry is {}.", entry);
//which expands effectively to
if (logger.isDebugEnabled()){
    // Note that it's actually *more* efficient than this - see Huxi's comment below...
    logger.debug("The entry is " + entry + "."); 
}
  • Logback porque es más nuevo que log4j y, nuevamente, admite el registro parametrizado, ya que implementa SLF4j directamente
  • SLF4j / Logback porque está escrito por el mismo tipo que hizo log4j, por lo que lo ha mejorado (según Ken G , gracias. Parece encajar al mirar sus publicaciones de noticias anteriores )
  • SLF4j porque también publican un adaptador log4j para que no tenga que "cambiar" log4j en un código anterior, simplemente haga que log4j.properties use SLF4j y su configuración
Stephen
fuente
3
Por lo que puedo decir, la idea detrás del registro de commons es que debería usarse en bibliotecas. De esta manera, la biblioteca siempre puede usar el mismo marco de registro (a través del registro común) que usa la aplicación de alojamiento.
Joachim Sauer
Muchas gracias a Loki por la pregunta. Ahora sé que ya no usaré log4j como mi marco predeterminado. SLF4j FTW! También gracias a Ken G por señalar que SLF4j está escrito por el mismo tipo que log4j
Stephen
3
El comentario en su ejemplo de código no es 100% correcto. Logback realiza el formateo real del mensaje de forma perezosa, por lo que solo sucederá si el evento es realmente manejado por un appender y el appender requiere el mensaje formateado, lo que no sucedería en el caso de, por ejemplo, un SocketAppender ya que el evento se serializa usando el patrón de mensaje sin cambios + los argumentos como cadenas. Aunque supongo que depende de cómo se defina "efectivamente". Sin duda, emitiría el mismo mensaje (al menos si la entrada y el objeto son lo mismo;)) así que, por favor, perdóneme.
Huxi
6
SLF4J en realidad es solo una API que se encuentra encima de otros marcos de registro. Similar al objetivo de Commons Logging, pero más intuitivo desde mi experiencia.
James McMahon
37

Encuentro que iniciar sesión en Java es confuso, inconsistente, mal documentado y, especialmente, desordenado. Además, existe una gran similitud entre estos marcos de registro, lo que resulta en la duplicación de esfuerzos y la confusión en cuanto al entorno de registro en el que se encuentra. En particular, si está trabajando en una pila de aplicaciones web Java seria, a menudo se encuentra en múltipleentornos de registro a la vez; (por ejemplo, hibernate puede usar log4j y tomcat java.util.logging). Apache commons está destinado a unir diferentes marcos de registro, pero en realidad solo agrega más complejidad. Si no sabe esto de antemano, es completamente desconcertante. ¿Por qué mis mensajes de registro no se imprimen en la consola, etc.? Ohh, porque estoy mirando los registros de Tomcat y no log4j. Añadiendo otra capa de complejidad, el servidor de aplicaciones puede tener configuraciones de registro global que pueden no reconocer las configuraciones locales para una aplicación web en particular. Por último, todos estos marcos de registro son DEMASIADO COMPLICADOS. Iniciar sesión en Java ha sido un desastre desorganizado que ha dejado a los desarrolladores como yo frustrados y confundidos.

Las primeras versiones de Java no tenían un marco de registro integrado que condujera a este escenario.

Julien Chastang
fuente
19
¿Es esta una respuesta? Parece más una perorata.
Michael Myers
15
Lo siento. Que es un poco de una queja. Pero también es una respuesta convincente a "¿Qué pasa con el registro en Java?". La respuesta, en resumen, es que está profundamente rota.
Julien Chastang
1
bueno, no vale un voto de -1; P Pero algo sobre lo que reflexionar.
guyumu
21
Los problemas comenzaron cuando Sun realmente agregó java.util.logging a Java 1.4. Antes de eso, LOG4J estaba bien establecido y se usaba ampliamente. Después de eso, surgió la necesidad de contenedores para admitir LOG4J y java.util.logging. Además, dado que jul está contenido en el paquete java. *, No se puede reemplazar intercambiando un JAR, que es la forma en que SLF4J une los otros marcos. Esta fue probablemente la peor idea de Sun jamás ... y finalmente llevó a la suposición errónea de que un "buen ciudadano de Java" debería usar jul.
Huxi
4
@Huxi, mantengo que la API de Calendario fue peor. En defensa de Sun no era su código, sino que procedía de Taglient.
Thorbjørn Ravn Andersen
22

Hay un punto importante que no se mencionó antes:

SLF4J (y tanto Logback como LOG4J como backend de registro) tienen soporte para un contexto de diagnóstico mapeado (MDC, consulte javadoc y documentación ).

Esto es esencialmente un mapa <String, String> local de subproceso que puede usar para agregar información de contexto adicional a su evento de registro. El estado actual del MDC se adjunta a cada evento.

Esto puede ser increíblemente útil si pones cosas como el nombre de usuario y la URL de la solicitud (en el caso de una aplicación web). Esto se puede hacer automáticamente usando un filtro, por ejemplo.

Huxi
fuente
2
Técnicamente, es un mapa <String, String> local de subprocesos.
pdxleif
17

Consulte también las respuestas a la pregunta ¿Cuáles son las mejores prácticas para registrar un error? , especialmente:

  • Hay algunos problemas potenciales de carga de clases con Commons Logging.

  • Log4J y SLF4J fueron desarrollados por la misma persona, aprendiendo de los problemas encontrados en la práctica con Log4J.

Ken Gentle
fuente
4

En el proyecto de nuestra empresa usamos LOG4j y es muy fácil de usar como lo mostró Stephen en su ejemplo. También hemos escrito nuestras propias clases de patrones para LOG4j para que pueda crear sus propios esquemas de archivos de salida. Puede describir cómo debería verse su archivo de registro. Es posible mejorar las clases log4j originales.

Puede cambiar todas las propiedades de LOG4j en un archivo log4j.properties, por lo que puede usar diferentes archivos para diferentes proyectos.

El registro de Java no es mi favorito, pero esto podría deberse a que uso log4j desde el principio.

Markus Lausberg
fuente
4

La descripción general de Commons Logging da la razón de su existencia: registro desde el código de la biblioteca, cuando no tiene control sobre el marco de registro subyacente. Muy importante para los diversos proyectos de Apache, que estarán vinculados a aplicaciones externas. Quizás no sea tan importante para los proyectos de TI internos, donde tiene el control total.

Dicho esto, escribo a Commons Logging, al igual que muchos de los otros desarrolladores que conozco. La razón es minimizar el bagaje mental: puede cambiar de proyecto o trabajo, y no tener que aprender un nuevo marco (siempre que el nuevo trabajo / proyecto también use CL, y / o pueda convencerlos de que se muden a él).

Además, es valioso crear sus propios contenedores en torno a cualquier marco que utilice. Como se describe aquí , me gusta usar un objeto LogWrapper para proporcionar una cadena personalizada (importante) y minimizar el desorden visual de las declaraciones de registro (menos importante).

kdgregory
fuente
1
También hay un puente commons.logging => SLF4J que se puede utilizar para enrutar todos los registros de CL sobre SLF4J. SLF4J admite el puenteo de commons.logging, LOG4J y (un poco engorroso, pero lo mejor posible) java.util.logging, por lo que todos los registros terminarán en cualquier backend SLF4J que utilice. Ver slf4j.org/legacy.html Yo usaría Logback, por cierto, pero se podría argumentar que soy parcial.
Huxi
2

Generalmente, usaría Log4J por defecto.

Usaría Java Logging si no me importara una dependencia en Java 1.4, pero aún usaría Log4J de preferencia.

Usaría Commons Logging si estuviera mejorando algo que ya lo usaba.

Michael Rutherfurd
fuente
¿No le importaba una dependencia de 1.4? Incluso 1.4 ha llegado al final de su vida útil.
Tom Hawtin - tackline
2
@Tom Él quiere decir jdk1.4 + no seas tonto.
mP.
En realidad, recientemente hice algunos trabajos en un sistema que todavía se ejecutaba bajo jdk 1.3 :-(, y hace menos de dos años estuve manteniendo un sistema jdk 1.2 por última vez . Demasiados lugares no se actualizan a menos que sea absolutamente necesario a, simplemente se niegan a instalar las actualizaciones.
Michael Rutherfurd
0

Sugeriría crear una fachada de registro delgada que pueda escribir en cualquiera de los marcos de registro, momento en el que la elección del motor de respaldo se convierte en un punto discutible.

tsimon
fuente
2
Eso es lo que hace la tala de bienes comunes, entonces, ¿por qué reinventar la rueda? También hay algunos problemas que su fachada tendría que manejar y que el registro común ya lo hace.
James AN Stauffer
+1 Para contrarrestar el argumento de registro de bienes comunes, algunas aplicaciones empresariales utilizan un registrador personalizado. Siempre es una buena idea ocultar la implementación subyacente. La envoltura 'delgada' elimina la necesidad de empaquetar otro frasco y no es tanto como reinventarse.
Questzen
1
Esto me salvó recientemente cuando trasladamos nuestro marco a Compact Framework (en .Net). Si tuviéramos dependencias codificadas en nLog, estaríamos jodidos. Debido a que usamos este enfoque, pudimos colocar un registrador nulo y ser felices. Alguien me vote de nuevo hasta 0 Por favor :-)
tsimon
3
Ya existe uno: eche un vistazo a slf4j. Es un contenedor delgado aceptado que le permite cambiar los marcos de registro en el inicio de la aplicación cambiando los archivos jar en la ruta de clases en tiempo de ejecución.
Determinado el
1
clogging tiene su propia forma de descubrir qué marco utilizará; no es agradable y es bastante complicado. Cuántos marcos de registro ha creado Ceki. Uno siempre debe esforzarse por ubicar un nivel de interdirección y ocultar una implementación incluso si está obstruida con su propio registro. Detrás de escena, puede agregar cualquier f / w que desee, como lo menciona Travis.
mP.