log4j中的MDC和NDC


NDC和MDC

NDC(Nested Diagnostic Context)和MDC(Mapped Diagnostic Context)是log4j種非常有用的兩個類,它們用於存儲應用程序的上下文信息(context infomation),從而便於在log中使用這些上下文信息。

 

NDC采用了一個類似棧的機制來push和pop上下文信息,每一個線程都獨立地儲存上下文信息。比如說一個servlet就可以針對每一個request創建對應的NDC,儲存客戶端地址等等信息。

當使用的時候,我們要盡可能確保在進入一個context的時候,把相關的信息使用NDC.push(message);在離開這個context的時候使用NDC.pop()將信息刪除。另外由於設計上的一些問題,還需要保證在當前thread結束的時候使用NDC.remove()清除內存,否則會產生內存泄漏的問題。

存儲了上下文信息之后,我們就可以在log的時候將信息輸出。在相應的PatternLayout中使用”%x”來輸出存儲的上下文信息,下面是一個PatternLayout的例子:

%r [%t] %-5p %c{2} %x - %m%n

使用NDC最重要的好處就是,當我們想輸出一些上下文的信息的時候,不需要讓logger去尋找這些信息,而只需要在適當的位置進行存儲,然后再配置文件中修改PatternLayout。在最新的log4j 1.3版本中增加了一個org.apache.log4j.filters.NDCMatchFilter,用來

根據NDC中存儲的信息接受或拒絕一條log信息。

 

MDC和NDC非常相似,所不同的是MDC內部使用了類似map的機制來存儲信息,上下文信息也是每個線程獨立地儲存,所不同的是信息都是以它們的key值存儲在”map”中。相對應的方法,MDC.put(key, value); MDC.remove(key); MDC.get(key); 在配置PatternLayout的時候使用:%x{key}來輸出對應的value。同樣地,MDC也有一個org.apache.log4j.filters.MDCMatchFilter。這里需要注意的一點,MDC是線程獨立的,但是一個子線程會自動獲得一個父線程MDC的copy。

至於選擇NDC還是MDC要看需要存儲的上下文信息是堆棧式的還是key/value形式的。

 

動態修改日志配置

在開發過程中,我們經常會遇到修改log4j配置的情況,在這種情況下,頻繁重啟應用顯然是不可接受的。幸好log4j提供了自動重新加載配置文件的能力,在配置文件修改后,便會自己重新加載配置。在1.2及以前的版本中DOMConfigurator和PropertyConfigurator都提供了configureAndWatch方法,對指定的配置文件進行監控,並且可以設置檢查的間隔時間。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM