Mein Team arbeitet an einem Plugin für NetBeans, das die Protokollierung in eine bestimmte Datei verwendet. Das Protokollierungssystem verwendet SLF4J + Log4J2; Die einzige Konfigurationsinformation, die mir bekannt ist, ist eine Datei log4j2.xml
mit Protokollierungseigenschaften für das Plugin und die folgenden:
(Die Tatsache, dass ich SLF4J und NetBeans verwende, ist hier nicht wirklich relevant.)
Die Frage, die ich habe, ist, was ist der richtige Weg, um die Protokollierung zu starten, wenn das Plugin startet und die Protokollierung zu beenden, wenn das Plugin beendet wird? (Die JVM fährt mit NetBeans fort, damit die Protokolldateien nicht automatisch geschlossen werden.)
Ich habe nachgeschlagen LoggerContext
und ich sehe stop()
und terminate()
Methoden, aber ich kann keine Dokumentation dafür finden, wie Anwendungen LoggerContext
verwenden sollen, also weiß ich nicht, ob dieser LifeCycle
stuff ein internes Detail ist oder etwas, das eine Anwendung verwenden soll.
Einige genauere Details:
Der Lebenszyklus unseres Plugins sieht ungefähr so aus wie in der folgenden Abbildung (nur eine Instanz darf gleichzeitig ausgeführt werden). Die "A" und "B" beziehen sich auf Protokollkonfigurationen, die wir gerne hätten.
%Vor%Die Konfiguration A ist der JVM zugeordnet und ist die Standardkonfiguration, die von log4j erstellt wird, wenn sie das erste Mal von der JVM geladen wird.
Konfiguration B wird programmgesteuert vom Plugin verwaltet und sollte unabhängig von Konfiguration A explizit gestartet / heruntergefahren werden (und Konfiguration A sollte nicht betroffen sein).
Gibt es eine Möglichkeit, dies mit Log4j 2.0 zu erreichen?
Sie können sicher separate LoggerContext
s für verschiedene Komponenten Ihrer Anwendung verwenden.
terminate()
und stop()
sind absolut identisch. Eigentlich nennt der erstere Letzteres und tut nichts mehr. terminate()
ist ein Teil der LoggerContext
eigene API, während stop()
ein Teil der weiteren LifeCycle
Schnittstelle ist.
Wenn Sie die Trennung Ihrer Logging-Kontexte richtig implementieren möchten, verwenden Sie den Mechanismus der Kontext-Selektoren. Lo4j2 stellt die Schnittstelle ContextSelector
für Klassen zur Verfügung, die für die Auswahl des Kontexts verantwortlich sind, der von LogManager.getContext()
zurückgegeben wird. Es gibt mehrere Implementierungen aus der Box:
BasicContextSelector
wählt einen Kontext basierend auf dem aktuellen Thread. BundleContextSelector
für die Verwendung in einer OSGI-Umgebung. JndiContextSelector
für mehrere Webanwendungen in einem einzelnen Servlet-Container. ClassLoaderContextSelector
wählt einen Kontext basierend auf dem Klassenlader des Aufrufers. Um festzulegen, welchen Selektor Sie verwenden möchten, legen Sie die Option Log4jContextSelector
Java fest.
Wenn Ihre Plugins beispielsweise in separaten Threads ausgeführt werden, können Sie BasicContextSelector
:
und verwenden Sie separate LoggerContext
s für Ihre Plugins auf diese Weise (dieser Code muss im Thread des Plugins ausgeführt werden):
Abhängig von der Architektur Ihrer Plugins können Sie eine dieser Implementierungen verwenden oder Ihre eigenen implementieren, es ist ziemlich einfach, Sie müssen nur die folgenden Methoden implementieren:
getContext()
zum Erstellen neuer Kontexte (oder zum Zurückgeben vorhandener Kontexte) basierend auf den für LogManager.getContext(...)
bereitgestellten Parametern. getLoggerContexts()
, um die Sammlung der verfügbaren Kontexte (die zuvor erstellten Kontexte) zurückzugeben. removeContext()
, um die Kontexte aus dem Speicher zu entfernen, wenn sie gestoppt (beendet) werden.