Ich hoffe, dass Log4j keine Einführung benötigt und ich gehe davon aus, dass Sie bereits ein Grundverständnis von Log4j haben. Wenn nicht, empfehle ich Ihnen, zuerst dieses Log4j-Tutorial zu lesen, um loszulegen.
Damit beginne ich nun mit MDC oder Mapped Diagnostic Context. Lassen Sie sich von diesem Namen nicht erschrecken! MDC ist gar nicht so schwer. Es ist ein einfaches, aber nützliches Konzept. Bevor ich erkläre, was MDC ist, gehen wir davon aus, dass wir eine einfache Webanwendung mit einem Servlet MyServlet
entwickeln, das Anfragen von mehreren Clients bedient. Und dieses Servlet verwendet das log4j-Framework für die Protokollierung. Für dieses Servlet wurde ein Datei-Appender definiert, so dass alle Protokollnachrichten in einer Textdatei protokolliert werden.
Mit der oben genannten Konfiguration werden alle Protokollnachrichten von MyServlet
in einer einzigen Protokolldatei gespeichert. Und wenn dieses Servlet mehrere Clients gleichzeitig bedient, werden die Log-Statements vermischt und es gibt keine Möglichkeit zu unterscheiden, welches Log-Statement zu welcher Client-Verarbeitung gehört. Das macht es schwierig zu verfolgen und zu debuggen, wenn ein Verarbeitungsfehler im MyServlet
Lebenszyklus auftritt.
Wie kann man die Log-Statements mit den jeweiligen Clients unterscheiden?
Um die Vermischung der Log-Statements zu vermeiden, können wir einen Benutzernamen (oder andere Daten, die für jeden Client eindeutig sind) zu unseren Log-Statements hinzufügen. Um dies zu tun, müssen wir sicherstellen, dass wir diesen Benutzernamen explizit an jede einzelne Protokollanweisung übergeben, was eine mühsame und sich wiederholende Arbeit ist. Aber kein Grund zur Sorge! Log4j bietet eine hervorragende Möglichkeit, dies zu umgehen. Sie wird MDC oder Mapped Diagnostic Context genannt.
Was ist Log4j MDC (Mapped Diagnostic Context)
Einfach ausgedrückt ist der MDC eine Map, die die Kontextdaten des jeweiligen Threads speichert, in dem der Kontext läuft. Um dies zu erklären, kehren wir zu unserer einfachen Anwendung zurück – jede Client-Anfrage wird von einem anderen Thread des MyServlet
bedient. Wenn Sie also log4j für die Protokollierung verwenden, kann jeder Thread seinen eigenen MDC haben, der für den gesamten Thread global ist. Jeder Code, der Teil dieses Threads ist, kann leicht auf die Werte zugreifen, die im MDC des Threads vorhanden sind.
Wie können wir also einen MDC erstellen, um Protokollierungsanweisungen von mehreren Clients zu unterscheiden? Ganz einfach: Bevor Sie einen Geschäftsprozess in Ihrem Code starten, holen Sie sich den Benutzernamen (für unser Servlet können wir ihn aus dem request
-Objekt holen) und tragen ihn in den MDC ein. Nun steht der Benutzername für die weitere Verarbeitung zur Verfügung. Fügen Sie in Ihrer log4j.properties bei der Definition des conversionPattern
ein Muster %X{key}
hinzu, um die Werte abzurufen, die im MDC vorhanden sind. Der Schlüssel wird in unserem Beispiel userName sein. Es ist so, als würde man einen Wert aus einem Session-Objekt abrufen.