log4j 1.x基礎教程

前言

Log4j 1.x已經不再維護,1.x最新版本是Log4j  1.2,請儘快升級到Apache Log4j 2。不過目前依然有不少舊項目使用1.x版本。Log4j有三個主要組件:logger, appender和layout。這三類組件一起工作使得開發者可以按消息的類別和等級來輸出消息,並且在運行時控制這些消息怎麼格式化和在哪裏輸出這些信息。


logger

自從 Log4j 的1.2版本,Logger類已經取代了Category類,對那些熟悉Log4j 早期版本的人來說,Logger類可以被認爲僅僅是Category類的別名。logger是被命名的實體,logger名是大小寫敏感的,並且它們遵循如下層次規則:一個logger可以說是另一個logger的祖先,假如logger的名稱加上圓點是後代logger的前綴,如果它們之間沒有其他的祖先,則logger是後代logger的父logger。例如:名稱爲“com.foo”的logger是名稱爲“com.foo.bar”的父logger。相似的是,“java”是“java.util”的父logger,是“java.util.vector”的祖先。這個命名規則對大多數的開發人員來說應該是很熟悉的。
root logger處於層次的頂端,它總是存在的,並且無法通過名稱獲得。
Logger.getRootLogger獲得root logger,其他的使用Logger.getLogger獲得。logger可以被設置級別,可能的級別包括TRACE、DEBUG,、INFO、 WARN、 ERROR、FATAL,這些級別被定義在org.apache.log4j.Level類中。一些常用方法如下:
package org.apache.log4j;

  public class Logger {

    // Creation & retrieval methods:
    public static Logger getRootLogger();
    public static Logger getLogger(String name);

    // printing methods:
    public void trace(Object message);
    public void debug(Object message);
    public void info(Object message);
    public void warn(Object message);
    public void error(Object message);
    public void fatal(Object message);

    // generic printing method:
    public void log(Level l, Object message);
}
假如一個logger沒有指定級別,它將從它最近的祖先繼承,如果祖先級別爲空,則繼續往上查詢,直到第一個級別非空的logger。root logger必須指定一個級別。
記錄請求是通過調用一個日誌實例的打印方法,如trace、debug等方法來實現的。假如記錄請求的等級大於等於logger的級別,那麼這個記錄請求就是有效的,反之無效。
這個規則是Log4j的核心,級別排序DEBUG < INFO < WARN < ERROR < FATAL.。

appender

基於logger的選擇性的啓用或禁用記錄請求的能力僅僅是描述的一部分,Log4j允許記錄請求輸出到多個目標,一個輸出目標就被稱爲appender。目前,appender包括console, files, GUI components, remote socket servers, JMS, NT Event Loggers, remote UNIX Syslog daemons,它也可以異步地記錄日誌。一個logger可以添加多個appender。appender也是可以被繼承的,logger的additivity屬性就是用於設置是否輸出到父appender,默認是true。例如:有一個logger叫做p,p是c的父logger,如果p的additivity是false,那麼c的日誌就會輸出到c的所有appender和p的所有appender,不會再輸出到p的父logger的appender上。
threshold屬性和logger的level差不多,它的作用是在level的基礎上再次過濾,可以達到每個appender輸出的日誌級別不一樣的效果,threshold大於等於level。

org.apache.log4j.ConsoleAppender

Threshold=DEBUG:指定日誌消息的輸出最低層次。
ImmediateFlush=true:默認值是true,意謂着所有的消息都會被立即輸出。

org.apache.log4j.RollingFileAppender

Encoding:輸出文件的編碼。
Threshold=DEBUG:指定日誌消息的輸出最低層次。
ImmediateFlush=true:默認值是true,意謂着所有的消息都會被立即輸出。
File=mylog.txt:指定消息輸出到mylog.txt文件,可以調用System.setProperty方法配置某個路徑,在這裏用${xxxx}引用系統變量。
Append=false:默認值是true,即將消息增加到指定文件中,false指將消息覆蓋指定的文件內容。
MaxFileSize=100KB:後綴可以是KB,、MB 或者是 GB。 在日誌文件到達該大小時,將會自動滾動,即將原來的內容移到mylog.log.1文件。
MaxBackupIndex=2:指定可以產生的滾動文件的最大數。

org.apache.log4j.DailyRollingFileAppender

Encoding:輸出文件的編碼。
Threshold=DEBUG:指定日誌消息的輸出最低層次。
ImmediateFlush=true:默認值是true,意謂着所有的消息都會被立即輸出。
File=mylog.txt:指定消息輸出到mylog.txt文件,可以調用System.setProperty方法配置某個路徑,在這裏用${xxxx}引用系統變量。
Append=false:默認值是true,即將消息增加到指定文件中,false指將消息覆蓋指定的文件內容。
DatePattern:文件命名規則和更新時間。
'.'yyyy-MM 在每個月剛開始的時候更新一次
'.'yyyy-MM-dd 每天半夜24點的時候更新
'.'yyyy-MM-dd-a 每天12點和24點更新
'.'yyyy-MM-dd-HH 每個小時更新一次
'.'yyyy-MM-dd-HH-mm 每分鐘更新一次
'.'yyyy-ww 每週的第一天更新

org.apache.log4j.AsyncAppender

AsyncAppender允許異步地記錄日誌,它可以附加幾個appender,工作原理是蒐集記錄事件然後派送到附屬於它的appender上,必須使用xml方式配置纔可以。
BufferSize:蒐集的事件數,默認128。
<appender name="ASYNC_FILE_LOG" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="256"/>
        <param name="LocationInfo" value="true"/>
        <appender-ref ref=appenderName/>
</appender>

layout

通常,用戶不僅需要自定義輸出目標,也需要自定義輸出格式,這是通過給appender設置一個layout來達到目的。PatternLayout是Log4j標準發行包的一部分,允許我們通過conversion屬性來定義格式,語法類似於C的printf。例如:設置爲"%r [%t] %-5p %c - %m%n",那麼會輸出:176 [main] INFO  org.foo.Bar - Located nearest gas station。
(1)org.apache.log4j.HTMLLayout(以HTML表格形式佈局)
(2)org.apache.log4j.PatternLayout(可以靈活地指定佈局模式)
(3)org.apache.log4j.SimpleLayout(包含日誌信息的級別和信息字符串)
(4)org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等等信息)
HTMLLayout選項:
LocationInfo=true:輸出java文件名稱和行號,默認值是false。
Title=My Logging: 默認值是Log4J Log Messages。
PatternLayout選項:
ConversionPattern=%m%n:設定以怎樣的格式顯示消息。
%p:輸出日誌信息的優先級,即DEBUG,INFO,WARN,ERROR,FATAL。
%d:輸出日誌時間點的日期或時間,默認格式爲ISO8601,也可以在其後指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
%r:輸出自應用程序啓動到輸出該log信息耗費的毫秒數。
%t:輸出產生該日誌事件的線程名。
%l:輸出日誌事件的發生位置,相當於%c.%M(%F:%L)的組合,包括類全名、方法、文件名以及在代碼中的行數。例如:test.TestLog4j.main(TestLog4j.java:10)。
%c:輸出日誌信息所屬的類目,通常就是所在類的全名。
%M:輸出產生日誌信息的方法名。
%F:輸出日誌消息產生時所在的文件名稱。
%L::輸出代碼中的行號。
%m::輸出代碼中指定的具體日誌信息。
%n:輸出一個回車換行符,Windows平臺爲"rn",Unix平臺爲"n"。
%x:輸出和當前線程相關聯的NDC(嵌套診斷環境),尤其用到像java servlets這樣的多客戶多線程的應用中。
%%:輸出一個"%"字符。
另外,還可以在%與格式字符之間加上修飾符來控制其最小長度、最大長度、和文本的對齊方式。如:
c:指定輸出日誌所屬類的名稱,最小的長度是20,如果日誌所屬類的名稱長度小於20的話,默認的情況下右對齊。
2)%-20c:"-"號表示左對齊。
3)%.30c:指定輸出日誌所屬類的名稱,最大的長度是30,如果日誌所屬類的名稱長度大於30的話,就會將左邊多出的字符截掉,但小於30的話也不會補空格。

解析配置文件

調用BasicConfigurator.configure方法,創建了一個相當簡單的Log4j設置。這個方法爲root logger添加了ConsoleAppender,PatternLayout被設置爲"%-4r [%t] %-5p %c %x - %m%n"。默認root logger級別是DEBUG。
調用PropertyConfigurator.configure方法,解析配置文件,配置文件可以是java的properties和xml文件。如果用spring,那麼配置監聽器org.springframework.web.util.Log4jConfigListener來解析配置文件,默認是classpath路徑,。建議使用xml文件,可讀性高。

Log4jConfigListener

1:動態的改變記錄級別和策略,不需要重啓Web應用。 
2:配置文件不需要寫絕對路徑。 
有幾個屬性需要注意:
webAppRootKey:默認是webapp.root,如果同一個jvm下有多個應用使用Log4jConfigListener,那麼需要修改這個屬性,讓每個應用不一樣,否則會導致後續應用啓動失敗。
log4jConfigLocation:配置文件路徑,相對web根目錄。
log4jRefreshInterval:單位毫秒,多長時間掃描配置文件,這樣就不用重啓web服務。
<context-param>
        <param-name>webAppRootKey </param-name>
        <param-value>some.web.root </param-value>
</context-param>
<context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>60000</param-value>
</context-param>
<listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

示例

# 控制檯
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 日誌文件
log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.Threshold=DEBUG
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/logs/log.log4j
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 滾動文件
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.Threshold=DEBUG
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.Append=true
log4j.appender.rollingFile.File=D:/logs/log.log4j
log4j.appender.rollingFile.MaxFileSize=200KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 定期滾動日誌文件
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.Threshold=DEBUG
log4j.appender.dailyFile.ImmediateFlush=true
log4j.appender.dailyFile.Append=true
log4j.appender.dailyFile.File=D:/logs/log.log4j
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 應用於socket
log4j.appender.socket=org.apache.log4j.RollingFileAppender
log4j.appender.socket.RemoteHost=localhost
log4j.appender.socket.Port=5001
log4j.appender.socket.LocationInfo=true
# Set up for Log Factor 5
log4j.appender.socket.layout=org.apache.log4j.PatternLayout
log4j.appender.socket.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

# 發送日誌到指定郵件
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=FATAL
log4j.appender.mail.BufferSize=10
log4j.appender.mail.From = [email protected]
log4j.appender.mail.SMTPHost=mail.com
log4j.appender.mail.Subject=Log4J Message
log4j.appender.mail.To= [email protected]
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 應用於數據庫
log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.database.URL=jdbc:mysql://localhost:3306/test
log4j.appender.database.driver=com.mysql.jdbc.Driver
log4j.appender.database.user=root
log4j.appender.database.password=
log4j.appender.database.sql=INSERT INTO LOG4J (Message) VALUES('=[%-5p] %d(%r) --> [%t] %l: %m %x %n')
log4j.appender.database.layout=org.apache.log4j.PatternLayout
log4j.appender.database.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

配置根Logger
log4j.rootLogger = [ level ] , appenderName1, appenderName2, …

配置Logger
log4j.logger.loggerName= [ level ] , appenderName1, appenderName2, …

配置appender
log4j.appender.appenderName = 完全限定類名

配置layout
log4j.appender.appenderName.layout = 完全限定類名
log4j.appender.appenderName.layout.ConversionPattern=格式

xml格式示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM
        "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<!--instruct log4j to also output internal debugging messages on the console-->
<log4j:configuration>
    <appender name="FILE_LOG" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="Encoding" value="UTF-8"/>
        <param name="Threshold" value="DEBUG"/>
        <param name="File" value=""/>
        <param name="Append" value="true"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d [%x] %t [%-5p] (%F,%L) - %m%n"/>
        </layout>
    </appender>

    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <param name="Threshold" value="DEBUG"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d [%x] %t [%-5p](%c %F,%L) - %m%n"/>
        </layout>
    </appender>

    <appender name="ASYNC_FILE_LOG" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="256"/>
        <param name="LocationInfo" value="true"/>
        <appender-ref ref="FILE_LOG"/>
    </appender>

    <appender name="ASYNC_CONSOLE" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="64"/>
        <param name="LocationInfo" value="true"/>
        <appender-ref ref="CONSOLE"/>
    </appender>

    <root>
        <level value="INFO"/>
        <appender-ref ref="ASYNC_CONSOLE"/>
        <appender-ref ref="ASYNC_FILE_LOG"/>
    </root>
</log4j:configuration> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章