Comment envoyer java.util.logging à log4j?

84

J'ai une application existante qui fait toute sa journalisation contre log4j. Nous utilisons un certain nombre d'autres bibliothèques qui utilisent également log4j ou qui se connectent à Commons Logging, qui finit par utiliser log4j sous les couvertures de notre environnement. Une de nos dépendances se connecte même à slf4j, ce qui fonctionne également très bien puisqu'elle délègue également à log4j.

Maintenant, j'aimerais ajouter ehcache à cette application pour certains besoins de mise en cache. Les versions précédentes d'ehcache utilisaient la journalisation commune, ce qui aurait parfaitement fonctionné dans ce scénario, mais à partir de la version 1.6-beta1, elles ont supprimé la dépendance à la journalisation commune et l'ont remplacée par java.util.logging à la place.

Ne connaissant pas vraiment la journalisation JDK intégrée disponible avec java.util.logging, existe-t-il un moyen simple d'envoyer les messages de journal à JUL journalisés par rapport à log4j, afin que je puisse utiliser ma configuration existante et configurer pour toute journalisation à venir de ehcache?

En regardant les javadocs pour JUL, il semble que je pourrais configurer un tas de variables d'environnement pour changer l' LogManagerimplémentation utilisée, et peut-être l'utiliser pour envelopper les log4j Loggerdans la Loggerclasse JUL . Est-ce la bonne approche?

Un peu ironique que l'utilisation par une bibliothèque de la journalisation JDK intégrée causerait un tel casse-tête lorsque (la plupart des) le reste du monde utilise à la place des bibliothèques tierces.

mat b
la source

Réponses:

37

Une approche que j'ai utilisée avec succès consiste à utiliser slf4j comme API de journalisation principale. J'ai alors slf4j lié à log4j. Les dépendances tierces utilisant d'autres frameworks (comme JUL) peuvent être reliées à slf4j.

réfléchir
la source
2
Bon lien, mais je pense que vous vouliez dire # jul-to-slf4j
araqnid
Cela semble être une bonne approche, sauf que je n'arrive pas à la faire fonctionner :(
matt b
2
De plus, je ne peux pas croire qu'une bibliothèque aussi populaire que ehcache passerait à quelque chose comme java.util.logging - semble très osé
matt b
1
@matt b, JUL est toujours présent dans le runtime Java donc il nécessite le moins de dépendances externes. C'est cependant à mes yeux un véritable exemple de code écrit par des personnes qui n'ont pas l'expérience des usages de ce code. Le système de configuration est plutôt gênant.
Thorbjørn Ravn Andersen
1
Le problème que vous rencontrez est que si vous reliez SLF4J à JUL, les performances de journalisation sont épouvantables. Plus précisément, chaque ligne de journal que vous créez entraîne une exception levée pour déterminer le contexte de journalisation à utiliser. Cela crée beaucoup de frais généraux et ralentit les processus
Egwor
19

Nous utilisons SLF4J sur notre projet actuel et cela a très bien fonctionné pour nous. SLF4J est écrit par Ceki Gülcü, le créateur de Log4J, et il a fait un très bon travail. Dans notre code, nous utilisons directement les API de journalisation SLF4J et nous configurons SLF4J de sorte que les appels de Jakarta Commons Logging (JCL), java.util.logging (JUL) et Log4J soient tous reliés aux API SLF4J. Nous devons le faire car, comme vous, nous utilisons des bibliothèques tierces (open source) qui ont choisi différentes API de journalisation.

Au bas de SLF4J, vous le configurez pour utiliser une implémentation de logger particulière. Il est livré avec un enregistreur interne ou "simple", et vous pouvez le remplacer avec Log4J, JUL ou Logback . La configuration se fait simplement en déposant différents fichiers jar dans votre chemin de classe.

À l'origine, nous avons utilisé l'implémentation Logback, également écrite par Ceki Gülcü. C'est très puissant. Cependant, nous avons ensuite décidé de déployer notre application sur le serveur d'applications Glassfish Java EE, dont la visionneuse de journaux attend des messages au format JUL. Donc aujourd'hui, je suis passé de Logback à JUL, et en quelques minutes, j'ai remplacé deux bocaux Logback par un bocal SLF4J qui le connecte à l'implémentation JUL.

Donc, comme @overthink, je recommande vivement d'utiliser SLF4J dans votre configuration.

Jim Ferrans
la source
8
Combien de fois Ceki a-t-il besoin de réinventer un cadre / une façade d'exploitation forestière?
mP.
@mP: La journalisation n'est peut-être pas glamour, mais c'est un besoin crucial de logiciels à grande échelle de qualité commerciale. Et SLF4J résout le problème de l'intégration de code qui utilise des cadres de journalisation disparates (rendu plus urgent par Sun choisissant de développer java.utils.logging au lieu d'adopter Log4J).
Jim Ferrans
3
@mP, slf4j était nécessaire car le mauvais travail de Sun avec JUL. Logback est un fork de log4j, pas un nouveau projet.
Thorbjørn Ravn Andersen
3
J'ai trouvé que la connexion était nécessaire, si pour rien d'autre, ce n'est pas Apache, et c'est en fait documenté.
Spencer Kormos
13

Il existe une alternative plus simple que SLF4J pour relier JUL avec log4j, voir http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/examples.html

Il vous suffit de mettre le jul-log4j-bridge sur le classpath et d'ajouter une propriété système:

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

jul-log4j-bridge n'est pas dans Maven Central et peut être récupéré à partir de ce référentiel:

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

puis utilisé avec:

<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>

Il est également possible de le reconstruire à partir des sources avec les étapes suivantes:

  1. svn co http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge/
  2. éditez pom.xml, remplacez la dépendance sur log4j: log4j: 1.2.15 par log4j: apache-log4j-extras: 1.2.17 et supprimez la dépendance sur apache-log4j-component
  3. package mvn
Emmanuel Bourg
la source
4
Je pense que c'est plus simple car cela peut être fait sans changer votre code, il vous suffit d'ajouter une propriété système. SLF4J ne propose pas encore de mécanisme similaire, vous modifiez soit le code, soit le logging.propertiesfichier.
Emmanuel Bourg
1
Cela n'existe pas dans log4j2, malheureusement :(
BeepDog
JulLog4jBridge.assimilate();o_0
Bastian Voigt
2
ATTENTION! jul-log4j-bridgeutilise le apache-log4j-companionsbundle jamais publié (un backport de l'abandonné log4j 1.3). Vous aurez du mal à le construire. Naturellement, le pont lui-même est également abandonné en pré-version.
ivan_pozdeev
@ivan_pozdeev Bon point, merci. J'ai ajouté des instructions pour le construire.
Emmanuel Bourg
9

OCTOBRE 2014

Depuis la version 2.1 de log4j existe le composant log4j-jul, qui permet exactement cela. Néanmoins, dans le cas où vous utilisez log4j 1, il doit être possible de mettre à niveau vers log4j2 afin d'utiliser cette approche.

Adaptateur de journalisation JDK

Classe LogManager

Migrer de log4j 1.x vers log4j 2

AdrianRM
la source
2
À partir de maintenant (mi-2018), cela devrait être la réponse acceptée
rmuller
Pour les futurs lecteurs: je confirme que cela fonctionne. Donc, en gros (1) ajoutez ceci à votre pom mvnrepository.com/artifact/org.apache.logging.log4j/log4j-jul et (2) ajoutez la propriété système dans le premier lien (par exemple, dans les paramètres JVM, ajoutez -Djava. util.logging.manager = org.apache.logging.log4j.jul.LogManager)
Hossam El-Deen
3

Je crois que le site slf4j a un pont pour transmettre les événements java.util.logging via slf4j (et donc vers log4j).

Oui, le téléchargement SLF4J contient jul-to-slf4j qui, je crois, fait exactement cela. Il contient un gestionnaire JUL pour passer des enregistrements à SLF4J.

araqnid
la source
2

@Yishai - Merci d'avoir publié le lien vers mon wiki. L'exemple là-bas redirige JUL vers Log4J et je l'ai fait tourner dans un système de production pendant quelques années. JBoss 5.x redirige déjà JUL vers Log4J, donc je l'ai retiré lors de la mise à niveau. J'en ai un plus récent qui redirige vers SLF4J, que j'utilise maintenant sur certaines choses. Je posterai ça quand j'en aurai l'occasion.

Cependant, SLF4J l'a déjà:

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

Joshua Davis
la source