Kann log4j anzeigen, mit welcher Datei es sich selbst konfiguriert hat?

78

Frage

Ist es möglich, dass Log4J den vollständigen Pfad der für die Konfiguration verwendeten Datei anzeigt?


Hintergrund

Ich habe eine Hassliebe zu log4j. In guten Zeiten ist es großartig, aber wenn es nicht funktioniert, kann es eines der schwierigsten Dinge sein, Fehler zu beheben. Ich verwalte die gesamte Protokollierung in unserer Anwendung. Daher bin ich mit der Protokollierung und dem im Handbuch definierten Standardinitialisierungsverfahren sehr vertraut . Trotzdem scheint es, dass alle paar Wochen die Protokollierungspausen und ich viel Zeit damit verbringen , das Problem zu lösen.

Dieses Mal ist es schwer gebrochen. Jede einzelne Protokollanweisung wird überall auf der Konsole gespeichert, und ich kann nicht herausfinden, warum. Die gleiche exakte Codebasis, die letzte Woche meine log4j.xml-Dateien verwendet hat, verwendet plötzlich eine andere Konfiguration. Nichts Offensichtliches hat sich geändert. Meine einzige Vermutung ist, dass sich einige Abhängigkeiten geändert haben und ich vermute, dass Maven eine böse JAR heruntergeladen hat, die alles kaputt macht.

Wenn ich nur herausfinden könnte, welche Konfigurationsdatei Log4J beim Start verwenden soll , könnte ich dieses und die meisten anderen Probleme leicht lösen.


Zusammenfassung

Gibt es eine Möglichkeit, Log4J anzuweisen, die für die Konfiguration verwendete Datei zu drucken? Gibt es alternativ eine Möglichkeit, eine laufende Anwendung zu brechen und den Debugger zu verwenden, um diese Frage zu beantworten (möglicherweise mit einem Ausdruck oder durch Überprüfen von Variablen)?

gMännlich
quelle
1
Der Hintergrund klingt nach einem Mehrfachbindungsproblem. Von slf4j.org/codes.html#multiple_bindings : Die von SLF4J ausgegebene Warnung ist genau das, eine Warnung. Selbst wenn mehrere Bindungen vorhanden sind, wählt SLF4J ein Protokollierungsframework / eine Protokollierungsimplementierung aus und bindet daran. Die Art und Weise, wie SLF4J eine Bindung auswählt, wird von der JVM bestimmt und sollte für alle praktischen Zwecke als zufällig angesehen werden.
Newur

Antworten:

80

Ja, fügen Sie einfach log4j.debugdie JVM-Systemvariablen hinzu. Zum Beispiel:

java -Dlog4j.debug -cp ... some.class.name

Log4j gibt dann Folgendes aus:

log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@1f7182c1.  
log4j: Using URL [file:/C:/Users/matt/workspace/projectname/target/test-classes/log4j.xml] for automatic log4j configuration.  
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator  
log4j: System property is :null  
log4j: Standard DocumentBuilderFactory search succeded.  
log4j: DocumentBuilderFactory is: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl  
log4j: debug attribute= "null".  
log4j: Ignoring debug attribute.  
log4j: reset attribute= "false".  
log4j: Threshold ="null".  
...

Referenz finden Sie im Handbuch und in den FAQ .

matt b
quelle
6
Aus irgendeinem Grund hat das Setzen dieses Flags in meinem Projekt keine Auswirkungen, möglicherweise weil SLF4J verwendet wird. Ich habe versucht herauszufinden, warum, aber ich habe schließlich manuell 21 Konfigurationsdateien überprüft, die dort sind;)
Zeile
2
Beachten Sie, dass in log4j2 die Eigenschaft in log4j2.debug geändert wurde und Sie möglicherweise auch -Dorg.apache.logging.log4j.simplelog.StatusLogger.level = TRACE festlegen müssen, wenn Sie versuchen, Probleme beim Auffinden der Konfigurationsdatei zu debuggen.
user2163960
6

Ich verwende Log4J2 und wenn Sie die Datei aus Ihrem Java-Programm heraus erhalten möchten, hat dies für mich funktioniert:

LoggerContext lContect = LogManager.getContext();
Field f = lContect.getClass().getDeclaredField("configuration");
f.setAccessible(true);
XmlConfiguration iWantThis = (XmlConfiguration) f.get(lContect);
System.out.println("Config File: " + iWantThis.getName());
Ben
quelle
1
Auf der einen Seite war dies genau das, wonach ich gesucht hatte, auf der anderen Seite hatte das Ändern der Konfigurationsdatei von der Ausgabe keine Auswirkung. Man muss also wirklich sehr sicher sein, dass Log4J2 tatsächlich verwendet wird. Ich hatte ein Problem mit mehreren Bindungen - wie hier beschrieben: slf4j.org/codes.html#multiple_bindings - also war der eigentliche Logger slf4j-einfach.
Newur
Ich habe auch den Debugger verwendet und einen Haltepunkt für den Konstruktor von org.apache.logging.log4j.util.PropertiesUtil festgelegt. Hier befinden sich die Dateien mit dem Namen log4j2.component.properties und werden geladen. Ich habe festgestellt, dass zwei Dateien geladen wurden, erstens von Ziel- / Testklassen und zweitens von Ziel / Klassen, und die Eigenschaft von letzterer überschrieb die Eigenschaft von der ersten.
Rychu
2

Das log4j 2-Äquivalent hierfür ist <Configuration status="trace">in der Konfigurationsdatei festzulegen. Dies zeigt den Speicherort an, von dem aus die log4j2-Konfigurationsdatei geladen wird, sowie andere interne Details des log4j2-Konfigurationsprozesses. Standardmäßig lautet die Statusprotokollierungsstufe WARN, sodass Sie nur dann Benachrichtigungen sehen, wenn ein Problem vorliegt.

Wenn die Konfigurationsdatei nicht korrekt gefunden wird, können Sie die interne Statusprotokollierung von log4j2 weiterhin aktivieren, indem Sie die Systemeigenschaft org.apache.logging.log4j.simplelog.StatusLogger.levelauf setzen TRACE.

Remko Popma
quelle
5
Wenn Sie jedoch herausfinden möchten, welcher Konfigurationswert verwendet wird, hilft es nichts, diesen zu einem Konfigurationswert hinzuzufügen, der möglicherweise nicht aktiv ist!
Omaha