Log4j – 如何配置多個logger?
內容簡介:
本文主要介紹 在一個系統中如何通過log4j的配置檔案配置出多個logger,使得該系統可以在不同路徑下輸出多個內容不同的log 檔案。並通過該例項的實現過程進一步講解log4j的一些特性。
具體內容:
1. 如何在專案中配置log4j使得該系統可以輸出web test的日誌檔案(自定義格式)到工程dist目錄下的junitLog/WebTestLog.log目錄下,輸出508 check日誌(html格式)到c:/508log.html路徑下?
第一步:加入log4j-1.2.8.jar到lib下。
第二步:在CLASSPATH下建立log4j.properties(即將log4j的配置檔案放在src的根目錄下)。
第三步:根據需要修改log4j配置檔案中的相應屬性,修改之前就必須知道這些都是幹什麼的,在後面的部分具體講解。
該例項中 根據需要 配好的log4j.properties如下:
[plain] view plain copy print?- log4j.rootLogger=ERROR
- log4j.logger.com.testframework.web=ERROR,A3
- log4j.logger.com.testframework.util= ERROR,A1,A2
- log4j.appender.A1=org.apache.log4j.ConsoleAppender
- log4j.appender.A1.layout=org.apache.log4j.PatternLayout
- log4j.appender.A1.layout.ConversionPattern=%m%n
- log4j.appender.A2=org.apache.log4j.RollingFileAppender
- log4j.appender.A2.File=c:/508log.html
- log4j.appender.A2.MaxFileSize=50000KB
- log4j.appender.A2.MaxBackupIndex=1
- log4j.appender.A2.layout=org.apache.log4j.HTMLLayout
- log4j.appender.A3=org.apache.log4j.RollingFileAppender
- log4j.appender.A3.File=junitLog/WebTestLog.log
- log4j.appender.A3.MaxFileSize=50000KB
- log4j.appender.A3.MaxBackupIndex=1
- log4j.appender.A3.layout=org.apache.log4j.PatternLayout
- log4j.appender.A3.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss}%5p[%t](%F:%L)-%m%n
log4j.rootLogger=ERROR
log4j.logger.com.testframework.web=ERROR,A3
log4j.logger.com.testframework.util= ERROR,A1,A2
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%m%n
log4j.appender.A2=org.apache.log4j.RollingFileAppender
log4j.appender.A2.File=c:/508log.html
log4j.appender.A2.MaxFileSize=50000KB
log4j.appender.A2.MaxBackupIndex=1
log4j.appender.A2.layout=org.apache.log4j.HTMLLayout
log4j.appender.A3=org.apache.log4j.RollingFileAppender
log4j.appender.A3.File=junitLog/WebTestLog.log
log4j.appender.A3.MaxFileSize=50000KB
log4j.appender.A3.MaxBackupIndex=1
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss}%5p[%t](%F:%L)-%m%n
第四步:在要輸出日誌的類中加入相關語句。
[java] view plain copy print?- package com. testframework.web
- Public class PersonTest{
- //載入logger的語句- 加粗部分為log4j配置檔案中配置的logger的名字
- static Logger logger = Logger.getLogger(PersonTest .class);
- publicvoid testGetPersonNameById(int personId){
- ........
- String personName = "";
- try {
- personName= dataPool. getPersonNameById (int personId);
- } catch (Exception e){
- String errorMsg = " Get Person Name Failed!";
- //利用logger輸出資訊到日誌中
- logger.error(errorMsg,e);
- fail(errorMsg);
- }
- ........
- }
- }
package com. testframework.web
Public class PersonTest{
//載入logger的語句- 加粗部分為log4j配置檔案中配置的logger的名字
static Logger logger = Logger.getLogger(PersonTest .class);
public void testGetPersonNameById(int personId){
........
String personName = "";
try {
personName= dataPool. getPersonNameById (int personId);
} catch (Exception e){
String errorMsg = " Get Person Name Failed!";
//利用logger輸出資訊到日誌中
logger.error(errorMsg,e);
fail(errorMsg);
}
........
}
}
Note:由於Log4j中Logger具有Java的繼承特性,所以在這個例項中,為了實現‘com. testframework.web’包下的所有類都可以使用Appender A3將Error級別以上的資訊輸出到工程dist目錄下的junitLog/WebTestLog.log日誌檔案中。所以在properties檔案中用包名定義了一個logger
log4j.logger.com.testframework.web=ERROR,A3
且在java程式碼中用該包中的類名來載入logger
staticLogger logger = Logger.getLogger(PersonTest.class);
此時,在java程式碼中所載入的這個logger的名字是com.testframework.web.PersonTest, 根據繼承原理,由於在log4j配置檔案中沒有定義這個logger的level和appender,所以這個logger將自動繼承其父logger‘com.testframework.web’的level和appender設定。
對於log4j的java繼承原理,後面的部分會詳細介紹。
2. Log4j配置檔案講解
Log4j支援兩種配置檔案格式,一種是XML格式的檔案,一種是Java特性檔案log4j.properties(鍵=值)。下面將介紹使用log4j.properties檔案作為配置檔案的方法。
2.1 配置根Logger
Logger 負責處理日誌記錄的大部分操作。
其語法為:
log4j.rootLogger = [ level ] , appenderName, appenderName, …
其中,level 是日誌記錄的優先順序,分為OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定義的級別。Log4j建議只使用四個級別,優先順序從高到低分別是ERROR、WARN、INFO、DEBUG。通過在這裡定義的級別,您可以控制到應用程式中相應級別的日誌資訊的開關。比如在這裡定義了INFO級別,只有等於及高於這個級別的才進行處理,則應用程式中所有DEBUG級別的日誌資訊將不被打印出來。ALL: 列印所有的日誌,OFF:關閉所有的日誌輸出。 appenderName就是指定日誌資訊輸出到哪個地方,可同時指定多個輸出目的地。
2.2 配置日誌資訊輸出目的地 Appender
Appender 負責控制日誌記錄操作的輸出。
其語法為:
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.optionN = valueN
這裡的appenderName為在①裡定義的,可任意起名。
其中,Log4j提供的appender有以下幾種:
org.apache.log4j.ConsoleAppender(控制檯),
org.apache.log4j.FileAppender(檔案),
org.apache.log4j.DailyRollingFileAppender(每天產生一個日誌檔案),
org.apache.log4j.RollingFileAppender(檔案大小到達指定尺寸的時候產生一個新的檔案),可通過log4j.appender.R.MaxFileSize=100KB設定檔案大小,還可通過log4j.appender.R.MaxBackupIndex=1設定為儲存一個備份檔案。
org.apache.log4j.WriterAppender(將日誌資訊以流格式傳送到任意指定的地方)
例如:log4j.appender.stdout=org.apache.log4j.ConsoleAppender
就是定義一個名為stdout的輸出目的地,ConsoleAppender為控制檯。
2.3 配置日誌資訊的格式(佈局)Layout
Layout 負責格式化Appender的輸出。
其語法為:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.optionN = valueN
其中,Log4j提供的layout有以下幾種:
org.apache.log4j.HTMLLayout(以HTML表格形式佈局),
org.apache.log4j.PatternLayout(可以靈活地指定佈局模式),
org.apache.log4j.SimpleLayout(包含日誌資訊的級別和資訊字串),
org.apache.log4j.TTCCLayout(包含日誌產生的時間、執行緒、類別等等資訊)
2.3.1格式化日誌資訊
Log4J採用類似C語言中的printf函式的列印格式格式化日誌資訊,列印引數如下:
%m 輸出程式碼中指定的訊息
%p 輸出優先順序,即DEBUG,INFO,WARN,ERROR,FATAL
%r 輸出自應用啟動到輸出該log資訊耗費的毫秒數
%c 輸出所屬的類目,通常就是所在類的全名
%t 輸出產生該日誌事件的執行緒名
%n 輸出一個回車換行符,Windows平臺為“rn”,Unix平臺為“n”
%d 輸出日誌時間點的日期或時間,預設格式為ISO8601,也可以在其後指定格式,比如:%d{yyyy MMM ddHH:mm:ss,SSS},輸出類似:2002年10月18日 22:10:28,921
%l 輸出日誌事件的發生位置,包括類目名、發生的執行緒,以及在程式碼中的行數。
3. Log4j的java特性簡介
Log4j簡單的來說由3部分組成: logger,appender,layout。
Logger之間是具有java的繼承特性的。Log4j有一個rootLogger,所有普通logger都預設繼承rootLogger。而普通logger之間的繼承關係是通過logger name來實現的。
例如,叫"com.foo.Bar"名字的logger就繼承於叫"com.foo"名字的logger。就好像java中"java.util" 和"java.util.Vector"的關係一樣。
而這些繼承關係決定了logger的Level和Appender這兩個屬性的確定。
請看下面的例子(繼承關係對確定logger的Level的影響):
Logger |
Assigned |
Inherited |
root |
Proot |
Proot |
X |
Px |
Px |
X.Y |
none |
Px |
X.Y.Z |
Pxyz |
Pxyz |
在上面例子中我們可以瞭解到如果一個普通logger定義了Level,則其level就使用它定義的(例如:logger X),如果沒有定義,就使用其父logger的(例如:logger X.Y)。
請看下面的例子(繼承關係對確定logger的Appender的影響):
Logger |
Added |
Additivity |
Output Targets |
Comment |
root |
A1 |
not applicable |
A1 |
The root logger is anonymous but can be accessed with the Logger.getRootLogger() method. There is no default appender attached to root. |
x |
A-x1, A-x2 |
true |
A1, A-x1, A-x2 |
Appenders of "x" and root. |
x.y |
none |
true |
A1, A-x1, A-x2 |
Appenders of "x" and root. |
x.y.z |
A-xyz1 |
true |
A1, A-x1, A-x2, A-xyz1 |
Appenders in "x.y.z", "x" and root. |
security |
A-sec |
false |
A-sec |
No appender accumulation since the additivity flag is set to false. |
security.access |
none |
true |
A-sec |
Only appenders of "security" because the additivity flag in "security" is set to false. |
在上面的例子中我們可以看出:
a. 如果一個普通logger定義Appender且其AdditivityFlag是true,則該logger的Appender包括其定義的Appender及其父logger定義的Appender。例如:logger‘x’。
b. 如果一個普通logger沒有定義Appender,但其AdditivityFlag是true,則該logger的Appender為其父logger定義的Appender。例如:logger‘x.y’。
c. 如果一個普通logger定義了Appender,但其AdditivityFlag是false,則該logger的Appender只為其定義的Appender。例如:logger‘security’。