2016-11-09 3 views
3

Ich erstelle child() Kontexte dynamisch in Spring Boot und ich möchte jeden Kontext in eine separate Datei protokollieren. Ist das möglich?Logback-Trennung von Spring Boot child() Kontexte

Der Grund dafür ist, dass ich eine dynamische Federintegrationskonfiguration für verschiedene Adapter habe. Dies ist sehr nützlich für die Arbeit mit verschiedenen Verbindungen mit der gleichen Adapterkonfiguration, aber es gibt viele Informationen für nur eine Protokolldatei.

Ich sah eine Thread-Trennung sogar eine JNDI Kontext Trennung, aber ich weiß nicht, was der beste Weg ist, dies zu tun. Ist es möglich, nur die logback.xml-Datei zu konfigurieren?

Update:

Vielleicht ist die Option MDC und ich verstehe nicht das Konzept. Zum Beispiel könnten Sie erklären, wie MDC für ein Feder @MessageEndpoint Elemente mit mehrere Feder Integration Elementen wie @Transformer, @ServiceActivator und @Router wie die folgenden anwenden: könnte

@MessageEndpoint 
public class TestComponents { 

private static final Logger LOGGER = LoggerFactory.getLogger(Test.class); 

@Router(inputChannel = "inputRouter") 
public MessageChannel router(Message<String> demo) { 
.. 
LOGGER.trace(“TEST”); 
… 
LOGGER.error(“TEST”); 
… 
} 

@ServiceActivator(inputChannel="inputService") 
public void service(Message<String> demo) { 
.. 
LOGGER.trace(“TEST”); 
.. 
} 

@Transformer(inputChannel="inputTransformer", outputChannel="outputTransformer") 
public byte[] transformerToByte(Message<String> demo) { 
.. 
LOGGER.debug(“TEST”); 
.. 
} 
} 

Das Beispiel auch mit anderen zu einem @Component anwendbar seinen Methoden.

Ich bin Sorge über die Leistung aufgrund der paragraph in der Dokumentation beschrieben:

Bitte beachten Sie, dass als MDC implementiert durch logback-classic geht davon aus, dass Werte in die MDC platziert werden mit mäßiger Frequenz

Antwort

0

Ich denke nicht, dass das leicht gemacht werden kann. Ich habe nicht viel Erfahrung mit Logback, aber ich bin vertraut mit Log4J, Spring, Tomcat und Classloading.

Logback verwendet wie log4J eine statische Factory-Methode, um einen Singleton-Logger zu erstellen. Dies bedeutet, dass der statische Status im Klassenlader gespeichert wird. Im Frühjahr können Sie angeben, welche Klasse geladen wird, um den Kontext zu laden, aber ein Klassenlader lädt nur eine Klasse/Ressource, die nicht vom übergeordneten Klassenlader geladen werden kann (Sie werden dies entdecken, wenn Sie URLClassLoader.getResource überschreiben) . Dies ist ein Problem, da beim Start von Spring Boot die Protokollierung initialisiert und vom Klassenlader 'root' geladen wird.

Die einzige Möglichkeit, dies zu verhindern, besteht darin, das Logback-Jar aus dem Klassenpfad zu entfernen und einen neuen URL-Klassenlader (mit nur Logback-Jar und Konfiguration) zum Laden des Spring-Stammkontexts und einer anderen Klassenlast zu erstellen Laden der untergeordneten Kontexte (gleiche jar unterschiedliche Konfiguration). Da das Logback-Jar nicht Teil des Systemklassenpfads ist, sollten Sie in der Lage sein, zwei separate Logbackkonfigurationen zu verwenden, da Static von Klassenladeprogrammen gesteuert wird.

EDIT

Tauchen ein wenig tiefer ich gemerkt, dass es nicht genug ist, einen Klassenlader zu haben, die logback-Kern und logback-klassische Gläser, aufgrund der Art und Weise der LoggingSystem Klasse (LogSystem Linie initialisiert lädt 126, Version 1.4.1), muss das gesamte Springboot (und möglicherweise auch alles andere) vom selben Klassenlader geladen werden. Dies bedeutet, dass Sie nicht in der Lage sein werden, die üblicherweise zum Ausführen von Spring-Boot-Anwendungen verwendete Glasbündelung zu verwenden.

+0

Danke Klaus. Ich kann diesen Ansatz nicht verwenden, da unsere benutzerdefinierte Konfiguration die Spring Boot-Konfiguration überschreibt, Spring Boot jedoch immer noch Logback verwendet, bevor und nachdem die child() - Kontexte erstellt werden. Ich arbeite mit Spring-Erweiterungen, Anpassen der Konfiguration programmgesteuert – crm86

0

Sie können MDC (Mapped Diagnostic Context) von logback in Kombination mit SiftingAppender verwenden.

Im Folgenden werde ich erklären, wie es funktionieren sollte:

  1. MDC ermöglicht es Ihnen, einen Diskriminator zu haben, die verwendet werden können, um Dateien zu trennen, basierend auf seinen Wert log. Zu diesem Zeitpunkt müssen Sie MDC.put('child-context-key', 'childContextId') ausführen, bevor eine Top-Stack-Methode aus dem untergeordneten Kontext ausgeführt wird, und MDC.remove('child-context-key') nach der Ausführung.
  2. Danach können Sie konfigurieren ch.qos.logback.classic.sift.SiftingAppender, die 'child-context-key' Wert als Diskriminator verwenden, um Ihre Protokolldateien zu trennen. Beispiel:

    <appender name="CHILD-CONTEXT-SIFT-APPENDER" class="ch.qos.logback.classic.sift.SiftingAppender"> 
    <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator"> 
        <key>child-context-key</key> 
        <defaultValue>defaultChildContextId</defaultValue> 
    </discriminator> 
    <sift> 
        <appender name="CHILD-CONTEXT-SIFT-FILE-APPENDER" 
         class="ch.qos.logback.core.rolling.RollingFileAppender"> 
         <file>/path/to/your/log/file/${child-context-key}.log 
         </file> 
    </sift> 
    </appender> 
    

Sie können auch this example Form logback folgen, die zeigen, wie separate Protokolldateien für Web-Anwendungsmodule auf JNDI Scheider Basis konfigurieren.

+0

Ich denke, er möchte, dass jedes Kind Kontext in seine eigene Datei anmelden, so dass dies funktionieren würde, müsste X Anzahl von ShiftAppenders, Kind-1, Kind-2, Kind definieren -3 ... Kind-X. Es sei denn, er kann den ShiftAppender hinzufügen, um programmatisch zu loggen. Sie müssen den MDC vor dem Laden des Spring-Kontexts festlegen. Wenn der Kontext jedoch Executors verwendet, müssen Sie den MDC (MDC.getCopyOfContextMap()) aus dem Spring-Lade-Thread speichern, damit Sie die Executor-Threads aktivieren können Dies bedeutet, dass Sie die ThreadFactory definieren oder MDC.setContextMap (saved-MDC) in jeder ausführbaren run-Methode aufrufen müssen. –

+0

@Klaus Groenbaek, tut mir leid, aber Sie irren sich über mehrere 'SiftAppenders'. –

+0

Danke Sergey. Ich habe die Dokumentation gelesen, aber MDC und JNDI sind keine gültigen Optionen, da ich keinen App-Server habe und MDC wirklich schlecht in der Leistung ist. Darüber hinaus ist die Lösung mit MDC nicht gültig, da ich nach etwas dynamisch konfigurierbar mit den dynamischen Kontexten suche. MDC ist gut, wenn Sie wenige Nachrichten oder Thread-Trennung haben, aber der Child-Kontext ist ziemlich groß mit Dutzenden von LOG-Traces. – crm86