在
多用戶并發(fā)的環(huán)境下,通常是由不同的線程分別處理不同的客戶端請求。此時要在日志信息中區(qū)分出不同的客戶端,你可以為每一個線程生成一個Logger,從
而從一堆日志信息中區(qū)分出哪些信息是屬于哪個線程的,但這種方式并不高效。Log4J巧妙地使用了Neil
Harrison提出的“NDC(嵌套診斷環(huán)境)”機(jī)制來解決這個問題。Log4J為同一類別的線程生成一個Logger,多個線程共享使用,而它僅在日
志信息中添加能夠區(qū)分不同線程的信息。NDC是什么?舉例來說,如果一個Servlet接到并發(fā)請求時,為每一個客戶端創(chuàng)建一個新的線程,然后分配一個用
于保存該請求上下文的NDC堆棧。該上下文可能是發(fā)出請求的主機(jī)名、IP地址或其它任何可以用于標(biāo)識該請求的信息。這樣,由于不同的客戶端處理線程具有不
同的NDC堆棧,即使這個Servlet同時生成多個線程處理不同的請求,這些日志信息仍然可以區(qū)分出來,就好像Log4J為每一個線程都單獨(dú)生成了一個
Logger實(shí)例一樣。在Log4J中是通過org.apache.log4j.NDC實(shí)現(xiàn)這種機(jī)制的。使用NDC的方法也很簡單,步驟如下:
1. 在進(jìn)入一個環(huán)境時調(diào)用NDC.push(String),然后創(chuàng)建一個NDC;
2. 所做的日志操作輸出中包括了NDC的信息;
3. 離開該環(huán)境時調(diào)用NDC.pop方法;
4. 當(dāng)從一個線程中退出時調(diào)用NDC.remove方法,以便釋放資源。
下面是一個模擬記錄來自不同客戶端請求事件的例子,代碼如下:
1. 在進(jìn)入一個環(huán)境時調(diào)用NDC.push(String),然后創(chuàng)建一個NDC;
2. 所做的日志操作輸出中包括了NDC的信息;
3. 離開該環(huán)境時調(diào)用NDC.pop方法;
4. 當(dāng)從一個線程中退出時調(diào)用NDC.remove方法,以便釋放資源。
下面是一個模擬記錄來自不同客戶端請求事件的例子,代碼如下:
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
public class TestNDC {
static Logger log = Logger.getLogger(TestNDC.class.getName());
public static void main(String[] args) {
log.info("Make sure %x is in your layout pattern!");
// 從客戶端獲得IP地址的例子
String[] ips = {"192.168.0.10","192.168.0.27"};
for (int i = 0; i<ips.length ; i++) // 模擬一個運(yùn)行方法
{
// 將IP放進(jìn) NDC中
NDC.push(ips[i]);
log.info("A NEW client connected, who's ip should appear in this log message.");
NDC.pop();
}
NDC.remove();
log.info("Finished.");
}
}
注意配置文件中的布局格式中一定要加上%x。系統(tǒng)輸出如下:import org.apache.log4j.NDC;
public class TestNDC {
static Logger log = Logger.getLogger(TestNDC.class.getName());
public static void main(String[] args) {
log.info("Make sure %x is in your layout pattern!");
// 從客戶端獲得IP地址的例子
String[] ips = {"192.168.0.10","192.168.0.27"};
for (int i = 0; i<ips.length ; i++) // 模擬一個運(yùn)行方法
{
// 將IP放進(jìn) NDC中
NDC.push(ips[i]);
log.info("A NEW client connected, who's ip should appear in this log message.");
NDC.pop();
}
NDC.remove();
log.info("Finished.");
}
}
INFO - Make sure %x is in your layout pattern!
INFO 192.168.0.10 - A NEW client connected, who's ip should appear in this log message.
INFO 192.168.0.27 - A NEW client connected, who's ip should appear in this log message.
INFO - Finished.
INFO 192.168.0.10 - A NEW client connected, who's ip should appear in this log message.
INFO 192.168.0.27 - A NEW client connected, who's ip should appear in this log message.
INFO - Finished.