2014-11-26 10 views
6

Ich versuche die asynchrone Protokollierung (aus Leistungsgründen) in REST-Webmethoden einzurichten, die derzeit auf einem Liberty-Profilserver ausgeführt werden.log4j2: Speicherort für die Log4jContextSelector-Systemeigenschaft für die asynchrone Protokollierung

Um dies zu tun, ich habe die folgende Eigenschaft ein:

System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"); 

Mein Problem ist, dass, egal wo ich dies tun, manchmal funktioniert es und Protokollierung ist sehr schnell, und manchmal es doesn‘ t.

I versucht haben, (a) in den Konstruktor für die Klasse alle Webmethoden REST enthaltenden (b) in dem Filter doFilter Methode, die (c) in dem Filter init Verfahren vor dem REST-Methode aufgerufen wird (d) in der REST-Methode selbst

keiner dieser Orte funktioniert konsistent.

Kann jemand eine Erklärung für dieses Verhalten und wenn möglich eine vorgeschlagene Möglichkeit zur Behebung des Problems bieten.

EDIT: Es scheint, dass log4j vor dem Aufruf von setProperty initialisiert wird. Also, was ich tun muss, ist die Einrichtung der Eigenschaft über Liberty-Profil statt.

+0

@fnt Nein, ich habe keine Beweise, habe keine Vergleiche gemacht, also werde ich meinen Kommentar ändern. Ich habe nur einen Vergleich mit Standard-Logging hier [Binäre Logging-Leistung - Folie 23] (http://www.slideshare.net/cnbailey/websphere-technical-university-top-websphere-problem-determination-features). – Gas

+1

Sie können [binary logging] (http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/twlp_confHPEL.html?cp) auswerten = SSAW57_8.5.5% 2F3-0-2-9-1 & lang = en) Option in Liberty, da es eine bessere Leistung als die Standardprotokollierung bietet. Vielleicht wird es dir gut genug sein. – Gas

+0

Gut gelesen. https://springframework.guru/asynchronous-logging-with-log4j-2/ –

Antwort

0

So anscheinend brauchte ich eine Linie zu den jvm.options hinzufügen

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector 

Die jvm.options Datei befindet Datei hier:

${server.config.dir}/jvm.options 

Und das Verzeichnis kann durch die Verwendung der gefunden werden Link:

http://www-01.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/rwlp_dirs.html?cp=SSEQTP_8.5.5%2F1-3-11-0-2-0

In meinem Fall ist es unter: C: \ ECLI pse \ runtime \ usr \ servername \ serverName

+0

Funktioniert es, wenn es VM-Argumenten der Serverkonfiguration für Tomcat hinzugefügt wird? –

9

Es gibt eine nicht dokumentierte Methode zum Festlegen dieses Werts für Ihr Projekt, ohne den Systemeigenschaftswert beim Start manuell eingeben zu müssen.

Fügen Sie Ihrem Klassenpfad eine Datei mit dem Namen log4j2.component.properties hinzu. Dies kann in den meisten Maven- oder Gradle-Projekten durch Speichern in src/main/resources erfolgen.

Dies ist Datei ist einfach java.util.Properties Datei. Legen Sie den Wert für den Kontextwähler fest, indem Sie der Datei die folgende Zeile hinzufügen.

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector 

Log4j versucht zuerst, die Systemeigenschaft zu lesen. Wenn die Systemeigenschaft null ist, wird sie standardmäßig auf die in dieser Datei gespeicherten Werte zurückgesetzt.

Der Code, der diese Konfiguration durchführt, befindet sich unter Log4jContextFactory.java:91.

File Location

1

Mein Problem ist, dass, egal wo ich dies tun, manchmal funktioniert es und Protokollierung ist sehr schnell, und es tut manchmal nicht.

Fügen Sie diesen Code in einem statischen Initialisiererblock in der Klasse hinzu, die Ihren Haupteinstiegspunkt definiert.

public class MainClass { 
    // NOTE: Nothing can appear before this initializer 
    // NOTE: This initializer must be in the class that contains your entry point 
    static { 
     System.setProperty("Log4jContextSelector", 
      "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"); 
    } 

    public static void main(final String[] args) { 
     // Do anything you want to here 
    } 
} 

Gemäß der Java-Spezifikation erfolgt die statische Initialisierung in der Reihenfolge, in der sie deklariert ist. Daher wird der Aufruf System.setProperty garantiert vor der Log4j-Initialisierung stattfinden.

0

Log4j wurde vor dem Aufruf der Hauptmethode initialisiert. Es ist also nicht möglich, Ihre Eigenschaft Log4jContextSelector vom System auszuwählen und standardmäßig arbeitet es synchron.

So überprüfen Sie das: Entfernen Disruptor-Abhängigkeit, Wenn Ihr Projekt noch läuft, wird es nicht async.

Wenn Sie eine Eigenschaft über -DLog4jContextSelector = org.apache.logging.log4j.core.async.AsyncLoggerContextSelector hinzufügen, wird nach dem Entfernen des Disruptor-Projekts nicht nach oben gegangen.

Wenn Sie Tomcat verwenden, fügen Sie Systemeigenschaften in catalina.properties hinzu. Und vergiss nicht, sofortFlush = "false" zu verwenden.