¿Cómo enviar java.util.logging a log4j?

84

Tengo una aplicación existente que hace todo su registro contra log4j. Usamos una serie de otras bibliotecas que también usan log4j, o registran contra Commons Logging, que termina usando log4j bajo las cubiertas de nuestro entorno. Una de nuestras dependencias incluso se registra en slf4j, que también funciona bien ya que eventualmente también delega en log4j.

Ahora, me gustaría agregar ehcache a esta aplicación para algunas necesidades de almacenamiento en caché. Las versiones anteriores de ehcache usaban commons-logging, que habría funcionado perfectamente en este escenario, pero a partir de la versión 1.6-beta1 eliminaron la dependencia de commons-logging y la reemplazaron con java.util.logging en su lugar.

Al no estar realmente familiarizado con el registro JDK integrado disponible con java.util.logging, ¿existe una manera fácil de que los mensajes de registro enviados a JUL se registren en log4j, para que pueda usar mi configuración existente y configurar para cualquier registro que venga? de ehcache?

Mirando los javadocs para JUL, parece que podría configurar un montón de variables de entorno para cambiar qué LogManagerimplementación se usa, y tal vez usar eso para ajustar log4j Loggers en la Loggerclase JUL . ¿Es este el enfoque correcto?

Es un poco irónico que el uso de un registro JDK integrado en una biblioteca cause un dolor de cabeza cuando (la mayoría) el resto del mundo está usando bibliotecas de terceros.

mate b
fuente

Respuestas:

37

Un enfoque que he utilizado con éxito es utilizar slf4j como mi API de registro principal. Luego tengo slf4j enlazado a log4j. Las dependencias de terceros que utilizan otros marcos (como JUL) se pueden puentear a slf4j.

pensar demasiado
fuente
2
Buen enlace, pero creo que te refieres a # jul-to-slf4j
araqnid
Esto suena como un buen enfoque, excepto que parece que no puedo hacerlo funcionar :(
matt b
2
Además, no puedo creer que una biblioteca tan popular como ehcache haga un cambio a algo como java.util.logging - parece muy tonto
matt b
1
@matt b, JUL siempre está presente en el tiempo de ejecución de Java, por lo que requiere la menor cantidad de dependencias externas. Sin embargo, en mi opinión, es un verdadero ejemplo de código escrito por personas que no tienen experiencia con los usos de ese código. El sistema de configuración es bastante inconveniente.
Thorbjørn Ravn Andersen
1
El problema que tiene es que si une SLF4J a JUL, el rendimiento de registro es terrible. Específicamente, cada línea de registro que crea da como resultado una excepción lanzada para determinar qué contexto de registrador usar. Eso crea mucha sobrecarga y ralentiza los procesos
Egwor
19

Usamos SLF4J en nuestro proyecto actual y nos ha funcionado muy bien. SLF4J está escrito por Ceki Gülcü, el creador de Log4J, y ha hecho un gran trabajo. En nuestro código usamos las API de registro SLF4J directamente, y configuramos SLF4J para que las llamadas desde las API de Jakarta Commons Logging (JCL), java.util.logging (JUL) y Log4J se conecten con las API de SLF4J. Necesitamos hacer eso porque, al igual que usted, usamos bibliotecas de terceros (código abierto) que han elegido diferentes API de registro.

En la parte inferior de SLF4J, lo configura para usar una implementación de registrador particular. Viene con un registrador interno o "simple", y puede anularlo con Log4J, JUL o Logback . La configuración se realiza simplemente colocando diferentes archivos jar en su classpath.

Originalmente, usamos la implementación Logback, también escrita por Ceki Gülcü. Esto es muy poderoso. Sin embargo, luego decidimos implementar nuestra aplicación en el servidor de aplicaciones Glassfish Java EE, cuyo visor de registros espera mensajes con formato JUL. Así que hoy cambié de Logback a JUL, y en solo unos minutos reemplacé dos frascos de Logback con un frasco SLF4J que lo conecta a la implementación de JUL.

Así que como @overthink, recomiendo encarecidamente usar SLF4J en su configuración.

Jim Ferrans
fuente
8
¿Cuántas veces Ceki necesita reinventar un marco de registro / fascade?
mP.
@mP: El registro puede no ser glamoroso, pero es una necesidad crucial para un software comercial a gran escala. Y SLF4J resuelve el problema de la integración de código que utiliza marcos de registro dispares (hecho más urgente cuando Sun eligió desarrollar java.utils.logging en lugar de adoptar Log4J).
Jim Ferrans
3
@mP, slf4j era necesario porque el mal trabajo que hizo Sun con JUL. Logback es una bifurcación de log4j, no un proyecto nuevo.
Thorbjørn Ravn Andersen
3
Encontré que el logback es necesario, al menos, no es Apache, y en realidad está documentado.
Spencer Kormos
13

Existe una alternativa más simple que SLF4J para unir JUL con log4j, consulte http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/examples.html

Solo tiene que poner jul-log4j-bridge en la ruta de clase y agregar una propiedad del sistema:

-Djava.util.logging.manager=org.apache.logging.julbridge.JULBridgeLogManager

jul-log4j-bridge no está en Maven Central y se puede obtener de este repositorio:

<repository>
  <id>psmith</id>
  <url>http://people.apache.org/~psmith/logging.apache.org/repo</url>
  <releases>
    <enabled>false</enabled>
  </releases>
</repository>

y luego se usa con:

<dependency>
  <groupId>org.apache.logging</groupId>
  <artifactId>apache-jul-log4j-bridge</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>log4j</groupId>
      <artifactId>apache-log4j-component</artifactId>
    </exclusion>
  </exclusions>
</dependency>

También es posible reconstruirlo a partir de fuentes con los siguientes pasos:

  1. svn co http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge/
  2. edite pom.xml, reemplace la dependencia en log4j: log4j: 1.2.15 con log4j: apache-log4j-extras: 1.2.17 y elimine la dependencia en apache-log4j-component
  3. paquete mvn
Emmanuel Bourg
fuente
4
Creo que es más simple porque se puede hacer sin cambiar su código, solo tiene que agregar una propiedad del sistema. SLF4J no propone un mecanismo similar todavía, o cambia el código o el logging.propertiesarchivo.
Emmanuel Bourg
1
Esto no existe en log4j2, desafortunadamente :(
BeepDog
JulLog4jBridge.assimilate();o_0
Bastian Voigt
2
¡ADVERTENCIA! jul-log4j-bridgeusa el apache-log4j-companionspaquete nunca lanzado (un backport del abandonado log4j 1.3). Te resultará difícil construirlo. Naturalmente, el puente en sí también se abandonó antes del lanzamiento.
ivan_pozdeev
@ivan_pozdeev Buen punto, gracias. Agregué instrucciones para construirlo.
Emmanuel Bourg
9

Octubre de 2014

Desde la versión 2.1 de log4j existe el componente log4j-jul, que permite exactamente esto. Aún así, en caso de que esté utilizando log4j 1, debe ser posible actualizar a log4j2 para poder utilizar este enfoque.

Adaptador de registro JDK

Class LogManager

Migrar de log4j 1.xa log4j 2

AdrianRM
fuente
2
A partir de ahora (mediados de 2018), esta debería ser la respuesta aceptada
rmuller
Para futuros lectores: confirmo que esto está funcionando. Entonces, básicamente (1) agregue esto a su pom mvnrepository.com/artifact/org.apache.logging.log4j/log4j-jul y (2) agregue la propiedad del sistema en el primer enlace (por ejemplo, en los parámetros de JVM agregue -Djava. util.logging.manager = org.apache.logging.log4j.jul.LogManager)
Hossam El-Deen
3

Creo que el sitio slf4j tiene un puente para pasar eventos java.util.logging a través de slf4j (y por lo tanto a log4j).

Sí, la descarga de SLF4J contiene jul-to-slf4j que creo que hace precisamente eso. Contiene un controlador JUL para pasar registros a SLF4J.

arácnido
fuente
2

@Yishai - Gracias por publicar el enlace a mi wiki. El ejemplo allí redirige a JUL a Log4J y lo he tenido funcionando en un sistema de producción durante algunos años. JBoss 5.x ya redirige JUL a Log4J, así que lo eliminé cuando actualizamos. Tengo uno más nuevo que redirige a SLF4J, que ahora uso en algunas cosas. Publicaré eso cuando tenga la oportunidad.

Sin embargo, SLF4J ya lo tiene:

http://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j

Joshua Davis
fuente