Ich versuche, JUL Adapter zu verwenden, um Java Util Logging an Log4j2 zu delegieren. Genauer gesagt sollte jede Bibliothek von Drittanbietern, die JUL zum Generieren von Protokollen verwenden, an Log4j2 delegiert werden.
Als einfache Übung habe ich eine eigenständige Anwendung erstellt, die eine Bibliothek verwendet (ich habe diese Bibliothek zu Testzwecken erstellt, sie generiert JUL-Protokolle), um den JUL-Adapter zu testen. Wenn ich den Protokollmanager wie hier hier ändere, kann ich die Auswirkungen sehen. Und es funktioniert gut.
Ihr Code lautet:
%Vor%Abhängigkeiten erforderlich:
%Vor%Allerdings kann ich das in einer Java-Web-App, die Jersey verwendet, nicht bearbeiten. Jersey verwendet JUL, und ich versuche, es mit Log4j2 zu überbrücken.
Hier ist die Datei build.gradle
:
Ich habe diese Optionen versucht:
Ändern Sie den Protokollmanager in einer Klasse, die Application
erweitert.
Ändern Sie den Protokollmanager in einer Klasse, die ServletContextListener
Abgesehen von zwei oben genannten Optionen habe ich auch versucht, den Protokollmanager in static block
(für beide Optionen 1. und 2.) zu setzen.
Leider hat keine dieser Optionen für mich funktioniert. Ich frage mich, wo das gemacht werden sollte. Gibt es etwas, das ich vermisse?
java.util.logging.LogManager
class wird initialisiert, wenn der Webanwendungscontainer wie tomcat
, gretty
gestartet wird. Zum Zeitpunkt des Ladens (in static block
) überprüft diese Klasse den Wert von java.util.logging.manager
system property und erstellt den Logger
entsprechend. Einmal initialisiert, wird diese Klasse nie wieder initialisiert.
Für eine Webanwendung wäre es also zu spät, diese Systemeigenschaft über den Webanwendungscode festzulegen.
Eine mögliche Lösung besteht darin, diesen Systemeigenschaftswert über VM arguments
an den Anwendungscontainer zu übergeben -
In diesem Fall müssen Sie log4j
jars und die Konfigurationsdatei zum Zeitpunkt des Startcontainers angeben, damit org.apache.logging.log4j.jul.LogManager
durch System ClassLoader
geladen werden kann.
Für tomcat müssen Sie nach 3 Gläsern zusammen mit bootstrap.jar
(tomcat startup), tomcat-juli.jar
(logging) laden, damit es funktioniert -
Ein ähnlicher Ansatz muss auch für andere Container verwendet werden.
Wenn Sie die Konfiguration des Containers nicht ändern können oder möchten, hier ist eine alternative Lösung, die für mich funktioniert hat.
Wenn der Kontext initialisiert ist, entfernen Sie alle Handler, die ein JUL-Logger hat, und fügen Sie dann Ihren eigenen benutzerdefinierten Handler hinzu, in dem Sie Ihr bevorzugtes Logging-Framework verwenden können.
Hier ist ein Beispiel:
%Vor%Ich glaube, dass die Klasseninitialisierung "java.util.logging.LogManager" vor dem Zeitpunkt erfolgt, an dem die Systemeigenschaften aktualisiert werden.
Sie können also dem Container-Classloader Logging-Bibliotheken zur Verfügung stellen und diese Systemeigenschaft für den gesamten Container mit Umgebungsvariablen oder Konfigurationsdateien konfigurieren.