Jag hoppas att Log4j inte behöver någon introduktion och jag antar att du redan har grundläggande kunskaper om Log4j. Om inte, rekommenderar jag dig att först läsa denna Log4j Tutorial, för att komma igång.
Detta sagt, nu ska jag börja med MDC eller Mapped Diagnostic Context. Bli inte skrämd av det här namnet! MDC är inte så svårt. Det är ett enkelt men användbart koncept. Innan jag förklarar vad MDC är, låt oss anta att vi ska utveckla en enkel webbapplikation med en servlet MyServlet
som betjänar förfrågningar från flera klienter. Denna servlet använder log4j-ramverket för loggning. En file appender har definierats för den här servleten, så alla loggmeddelanden kommer att loggas i en textfil.
Med ovanstående konfiguration kommer alla loggmeddelanden från MyServlet
att hamna i en enda loggfil. När den här servleten betjänar fler än en klient samtidigt kommer loggmeddelandena att blandas och det finns inget sätt att särskilja vilket loggmeddelande som tillhör vilken klients behandling. Detta gör det svårt att spåra och felsöka om något bearbetningsfel uppstår i MyServlet
livscykeln.
Hur kan man skilja logguttalanden med respektive klient?
För att undvika att logguttalanden blandas ihop kan vi lägga till ett användarnamn (eller andra uppgifter som är unika för varje klient) till våra logguttalanden. För att göra detta måste vi se till att vi skickar dessa uppgifter om användarnamn explicit till varje enskilt loggmeddelande, vilket är ett tråkigt och repetitivt arbete. Men du behöver inte oroa dig! Log4j har ett utmärkt sätt att lösa detta. Det kallas MDC eller Mapped Diagnostic Context.
Så, vad är Log4j MDC (Mapped Diagnostic Context)
För att uttrycka det enkelt är MDC en karta som lagrar kontextdata för den speciella tråd där kontexten körs. För att förklara det, gå tillbaka till vår enkla applikation – varje klientförfrågan kommer att betjänas av olika trådar i MyServlet
. Om du använder log4j för loggning kan varje tråd ha en egen MDC som är global för hela tråden. Alla koder som är en del av den tråden kan enkelt få tillgång till de värden som finns i trådens MDC.
Så, hur gör vi MDC för att differentiera loggningsmeddelanden från flera klienter? Enkelt: Innan du startar någon affärsprocess i din kod, hämtar du användarnamnet (för vår Servlet kan vi hämta det från request
-objektet) och lägger in det i MDC. Nu kommer användarnamnet att vara tillgängligt för den fortsatta bearbetningen. När du definierar conversionPattern
i log4j.properties lägger du till ett mönster %X{key}
för att hämta de värden som finns i MDC. Nyckeln kommer att vara userName i vårt exempel. Det är som att hämta ett värde från ett Session-objekt.