logger - ¿Encuentra suficiente java.util.logging?
java util logging level (17)
Dependencias de registro con bibliotecas de terceros
El registro Java JDK en la mayoría de los casos no es suficiente por sí mismo. Sin embargo, si tiene un proyecto grande que utiliza múltiples bibliotecas de terceros de código abierto, descubrirá rápidamente que muchas de ellas tienen dependencias de registro dispares.
Es en estos casos donde la necesidad de abstraer su API de registro de su implementación de registro se vuelve importante. Recomiendo usar slf4j o logback (usa la API slf4j) como su API y si desea continuar con el registro de Java JDK, ¡todavía puede! Slf4j puede enviar a muchas implementaciones de registradores diferentes sin problemas.
Un ejemplo concreto de su utilidad sucedió durante un proyecto reciente: necesitábamos usar libs de terceros que necesitaban log4j, pero no queríamos ejecutar dos marcos de registro uno al lado del otro, así que usamos las librerías slf4j log4j api wrapper y el problema fue resuelto.
En resumen, el registro Java JDK está bien, pero una API estandarizada que se utiliza en las bibliotecas de terceros le ahorrará tiempo a largo plazo. ¡Solo intenta imaginar refactorizar cada declaración de registro!
Según el título, ¿considera que el marco de registro de Java predeterminado es suficiente para sus necesidades?
¿Utiliza servicios de registro alternativos como log4j u otros? Si es así, ¿por qué? Me gustaría escuchar cualquier consejo que tenga con respecto a los requisitos de registro en diferentes tipos de proyectos, y cuando la integración de marcos es realmente necesaria y / o útil.
A menos que haya una razón convincente para usar algo que no pertenezca al JDK, prefiero usar lo que Sun proporciona.
Muchos de los proyectos que usan el registro Log4J lo estaban usando antes de que existiera la API de registro "estándar".
En los proyectos en los que trabajo, tendemos a usar el registro de bienes comunes de Yakarta. Eso no es un sistema de registro en sí mismo, sino que puede envolver algunos de los registradores más comunes: log4j, java.util.logging u otros.
Con eso, es relativamente fácil cambiar el registro en función del entorno en el que se implementa la aplicación (un desarrollador puede querer usar simplelog o java.util.logging en su máquina debido a la facilidad de mantenimiento, mientras que en un sistema SIT, log4j con una configuración común para todas las aplicaciones se pueden implementar, etc.)
Es bastante fácil escribir una clase LogManager
jul
que aplazará todos los registros a una implementación personalizada que utiliza Log4J. Esto significa que puede usar log4j pero aún tiene la buena característica de que las bibliotecas que se registran usando jul pueden controlarse como si hubieran usado Log4J.
Después de haber usado ambos (y el registro de áreas comunes), debo decir que lo que realmente, realmente , realmente me molesta es este:
log4j.error("An Exception", e);
jul.severe("An Exception", e); // GRRR! no such method
jul.log(Level.SEVERE, "An Exception", e); //Must use this method
¿Por qué hicieron esta elección de diseño? ¿Por qué? La otra cosa es que no hay PatternFormatter
que se envía con jul
; tienes que hacer tu propio.
Dicho esto, me equivoco al utilizar jul
partir de ahora ya que reduce las dependencias externas y no es más complicado de usar.
Las instalaciones de registro de JDK siempre han hecho lo que necesito que hagan, nunca tuve un problema con eso.
Para mí, las herramientas de registro de terceros no son necesarias ni deseables.
No pude averiguar cómo controlar el nivel de registro de clases individuales en el marco java.util.logging, algo que es posible en log4j. Si tengo problemas para diagnosticar un error o hay una clase de alto tráfico que registra información importante, puedo cambiar el nivel de una sola clase para registrar más y dejar el resto de mis clases relativamente tranquilo.
NB: podría ser que no supiera cómo hacerlo, o java.util.logging podría haber cambiado desde que lo intenté.
Pensé que usaría log4j, como lo menciona @ ScArcher2, solo porque todos lo hacen. Pero después de lidiar con ambas opciones, descubrí que java.util.logging es lo suficientemente amplio como para la mayoría de mis necesidades, y estoy hablando de un gran sistema con muchos componentes dispersos trabajando juntos.
Entonces, en mi opinión, no hay necesidad de usar servicios alternativos. Java.util.logging es lo suficientemente potente para la mayoría de los casos.
Personalmente utilizo Simple Logger , pero en el trabajo utilizo nuestro envoltorio corporativo para el registrador JDK. Uso Simple Logger, debido a la facilidad de configurarlo y al hecho de que admite el registro de 7 niveles entre Fatal y Ludicrous.
Si necesita iniciar sesión en su aplicación, es probable que haya hecho realmente mal. Yo argumentaría que reportar el problema ocasional está bien, pero tener declaraciones de depuración, información, etc. en muchas clases con lógica es completamente erróneo. Cualquier aplicación grande con declaraciones de registro en la mayoría de sus clases llenas de lógica va a equivaler a una sobrecarga de información, incluso si se seleccionan solo los registradores correctos. La mayoría de las veces la información estará incompleta, ruidosa o la información real que necesita es simple.
Básicamente, digo que solo debe escribir declaraciones de depuración para informar al usuario sobre las reacciones del programa a factores externos
- problema de formato en un archivo de configuración basado en texto.
- Problemas para abrir o ubicar un archivo requerido.
Todo depende de cuáles sean sus requisitos de registro. No es solo la API que usan los desarrolladores de la aplicación lo que ven, y francamente, eso es lo de menos, ya que la mayoría de las API de registro son fáciles de adaptar, sin importar qué elección haga.
La parte importante es qué tipo de configuración de registro necesita para las operaciones y deberían decirle lo que requieren.
- Puede ser tan simple como los archivos de texto que se transfieren.
- Puede ser más complicado, como iniciar sesión en un JMS o una base de datos.
- Puede requerir registros separados para rendimiento, auditoría, etc.
- Puede requerir detalles de correo electrónico cuando ocurre un evento de registro.
Log4J en su paquete varia ha tenido soporte para estos y más y probado con sus API. Ahora con java.util.logging deberías poder descargarlos, pero no son tan conocidos como Log4J y puede ser más difícil encontrar información para ti.
Otra cosa a considerar es la API del proveedor que está utilizando. La mayoría de los proveedores "fuerzan" una API de registro para usted. Spring es uno de ellos que requiere el registro de los bienes comunes.
Como desarrollador, trataría de usar java.util.logging si puedo para mis propias cosas, pero en los escenarios del mundo real tienes que sacudir lo que necesitarían en las operaciones y dejar que eso te guíe porque son ellos quienes tienen para usar estos registros cuando la aplicación se active. Ni el arquitecto de la aplicación ni los desarrolladores deben hacer esa elección, aunque deberían hacer sugerencias.
Una cosa que nadie mencionó en este hilo: java.util.logging no es compatible con syslog desde el primer momento. Eso es un factor decisivo para mí, (y me ha causado un poco de consternación tener que refactorizar las cosas java.util.logging en lugar de algo con un poco más de jugo.
Esto es lo que encontré hoy:
http://logging.apache.org/log4j/1.2/ - el único, aunque parece envejecer un poco ...
SLF4J - Está intentando tomar la corona de log4j, parece tener algún comportamiento de puenteo / redirección ... podría ser adecuado para un reemplazo directo, pero no pude encontrar ningún ejemplo claro. Debería pasar más tiempo en esto.
http://syslog4j.org/ - Registra syslogs, pero no tiene un reemplazo directo (nada parece, ¿los java no syslog mucho o algo así?)
http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/apidocs/org/apache/logging/julbridge/JULLog4jBridge.html - jul-log4j-bridge anuncia que es un soltar el reemplazo, parecía prometedor y tenía una huella pequeña.
Uno de los problemas que tengo con TODOS los marcos de trabajo de registro es que, a menos que todos los integrantes de su equipo dediquen tiempo a dominar exactamente cómo configurarlo y controlarlo, nunca se sabe si se imprimirá o no una determinada declaración de depuración.
Puede tener un nivel (depuración) desactivado, o puede tener un paquete apagado.
Perdí demasiado tiempo suponiendo que se imprimiera una declaración de depuración y no es así. Ahora dependo principalmente de System.out.println () y simplemente los examino y los elimino cuando los termino de depurar.
Sé que esto no responde a su pregunta. Solo digo que tal vez desee considerar cuánta justificación tiene antes de agregar complejidad.
La tala no es tan complicada y ciertamente está justificada en la mayoría de los proyectos más grandes.
Usamos log4j con el registro de commons . Creo que solo los usamos porque todos los demás lo hacen. Eso y estábamos usando log4j antes del registro compatible con jdk.
Editar: El hecho de que todo el mundo lo haga fue una broma, pero probablemente por eso comencé con el log4j y el registro de commons.
Usamos java.util.logging en todas partes. También para proyectos grandes. Hay algunas cosas que debe modificar (por ejemplo, el formato predeterminado), pero eso está fuera del punto real. Encuentro que el número de frameworks de registro en Java y la función de creep que implementaron son bastante molestos y un poco embarazosos para la comunidad Java. El nivel de debate sobre la tala es una señal segura de que algo salió mal.
Lo que JUL le brinda es una API simple pero suficiente y un lugar único para configurar qué salida de registro desea ver (logging.properties o JMX ...). Y siempre está ahí y estable.
Todo el código que desea iniciar sesión debe ajustarse a las convenciones estándar (el nivel predeterminado es INFO) y, de lo contrario, no hará más, pero usará registradores de un nombre significativo (por ejemplo, nombre de paquete o clase) y estará bien.
java.util.logging (jul) fue innecesario desde el principio. Simplemente ignóralo.
jul en sí tiene las siguientes desventajas:
- En el momento en que jul se introdujo en Java 1.4, ya existía un marco de registro bien establecido de amplio uso: LOG4J
- los niveles de registro predefinidos son: SEVERO, ADVERTENCIA, INFO, CONFIG, FINE, FINER, FINEST. No le diré lo que personalmente pienso acerca de esos niveles predefinidos para mantener esta respuesta semi-objetivo.
- Se pueden definir niveles adicionales. jul admite hasta 4G diferentes niveles de registro que es un poco exagerado, en mi humilde opinión. Menos es a veces más.
El punto más importante: si te atreves a definir tu propio nivel de registro, es probable que te topes con un problema de pérdida de memoria.
Siéntase libre de leer acerca de este efecto aquí:- Fugas de Classloader: la temida excepción "java.lang.OutOfMemoryError: PermGen space"
- Cómo solucionar la temida excepción "java.lang.OutOfMemoryError: PermGen space" (fugas del cargador de clases)
Es una lectura bastante interesante, incluso si no está planeando usar niveles personalizados, por cierto, ya que el problema es muy extendido y no solo se aplica a jul.
- reside en el espacio de nombres java. * por lo que la implementación no se puede intercambiar en tiempo de ejecución. Esto efectivamente evita que se vincule a SLF4J de la misma manera que es posible en caso de commons.logging y LOG4J. La forma en que se realiza el puente para jul tiene un impacto en el rendimiento. Esto hace que jul sea el marco de registro más inflexible que existe.
- Al introducir jul, Sun implícitamente lo definió como el "marco de registro Java estándar". Esto llevó a la idea errónea común de que un "buen ciudadano de Java" debería usar jul en sus bibliotecas o aplicaciones.
Ocurre justo lo contrario.
Si usa Commons.logging o LOG4j, podrá intercambiar el marco de registro realmente utilizado, si alguna vez lo necesita, mediante un puente a SLF4J. Esto significa que las bibliotecas que utilizan commons.logging, LOG4J o SLF4J pueden iniciar sesión en el mismo destino de registro, por ejemplo, archivo.
Yo personalmente sugiero usar el combo SLF4J + logback para todos los propósitos de registro. Ambos proyectos están coordinados por Ceki Gülcü, el responsable de LOG4J.
SLF4J es un sucesor digno (pero no oficial ya que no es del mismo grupo) de commons.logging. Es menos problemático que CL porque resuelve estáticamente el backend de inicio de sesión realmente utilizado. Además, tiene una API más rica que CL.
Logback, por otro lado, es el sucesor (no) oficial de LOG4J. Implementa SLF4J de forma nativa, por lo que no hay sobrecarga causada por ningún contenedor.
Ahora puedes rechazarme si sigues creyendo que me lo merezco. ;)
java.util.logging es bueno, pero no tiene una configuración que se recoja por defecto de la ruta de clases. Ese es un punto doloroso para nosotros, ya que tenemos muchas implementaciones que no comparten configuraciones de registro y es bastante complicado hacer esto en jul.
Actualmente, Log4j no se está desarrollando mucho, por lo que si hay una necesidad de desarrollo en la parte backend, logback es en este momento la opción más dinámica en mi opinión.
(advertencia: involucrado en algún desarrollo oscuro de slf4j y logback pero eso se debe y no está causando las declaraciones que hago arriba :))
slf4j es el nuevo niño. He trabajado un poco con eso y es bastante agradable. Su principal ventaja es el registro parametrizado , lo que significa que debe hacer esto:
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
En vez de esto:
logger.debug("The new entry is " + entry + ". It replaces " + oldEntry + ".");
Y toda esa manipulación de cadenas se hace solo si la declaración está realmente registrada. Se ve más limpio también.
Se debe tener en cuenta que SLF4J es un contenedor como el registro de recursos comunes, aunque afirma ser menos propenso a los problemas de cargador de clases de registro común.