2009-06-13

log4j基本觀念

根據官方網站和網路上資料整理的一些心得,雖然一些簡介是來自網路上的,但是其中也加了很多我的使用心得,要引用記得附註連結。

log4j 學過java的人應該都知道這個好用的API,java學了那麼久竟然還不會用,真是太冏了,決定來學一下,順便整理一下,有需要的話網友看看吧!!
##CONTINUE##

log4j簡介

Log4j 是一套開放源碼的工具,方便編程人員在程式中加入 log 機制,並輸出到各種目標上。Log4j 能夠透過外部的設定檔(properites 或 XML)進行設定。Log4j 能夠將 log message 寫到 console、 檔案、串流、TCP 協定的伺服器或Unix Syslog daemon 等等,相當的多得應用。Log4j 具有 5 種 log 等級(DEBUG、INFO、 WARN、ERROR、FATAL),可用於不同的系統狀態下所產生的訊息。

Log4j的三大元件

  • Logger - 由編程人員在程式中使用,進行 logging 的元件
  • Appender - 負責將 log message 輸出到各種裝置上
  • Layout - 決定 log message 的格式


Log4j的階層架構


一個程式可擁有多個logger,每個logger以名稱做區分,並且每個logger有階層的概念。
Example:假如你定義了 "com.util"此logger的一些設定(輸出格式、log等級或是輸出裝置),如果你沒有定義"com.util.cnn"此logger的設定,則他將會延續"com.util"logger的設定。
預設最高的logger是root logger且他一定存在,他可隨時從在程式中以 Logger.getRootLogger(),其它 logger 則以 Logger.getLogger(String loggerName) 取得。

Logger


Logger可以被指派等級。能夠指派給 Logger 的等級有 : DEBUG、INFO、WARN、ERROR、FATAL 5 種,定義在 org.apache.log4j.Level 類別中。這 5 種等級的高低順序為 FATAL > ERROR > WARN > INFO > DEBUG。
Logger等級決定可印出的message數量,Logger只印自身等級或是高於自身等級的message。
Exmaple: 定義一個Logger的等級為WARN,則他只會印出FATAL、ERROR及WARN的message。
Logger之間以名稱區分,所以在程式中任何地方,呼叫 Logger.getLogger(),並傳入同一個 Logger名稱,則會得到同一個Logger的reference。

Appender


一個Looger將會透過Appender將message輸出到定的裝置上,一個Logger可擁有多個Appender,因此可輸出到多個裝置上。

Layout


Logger可透過Layout來配置輸出到裝置上message的格式。
PatternLayout 的 格式字元列表如下:

  • %c 輸出日誌訊息所屬的類別的全名
  • %d 輸出日誌時間點的日期或時間,指定格式的方式:%d{yyy-MM-dd HH:mm:ss }。
  • %l 輸出日誌事件的發生位置,即輸出日誌訊息的語句處於它所在的類別的第幾行。
  • %m 輸出代碼中指定的訊息,如log(message)中的message。
  • %n 輸出一個列尾符號。
  • %p 輸出優先階層,即DEBUG,INFO,WARN,ERROR,FATAL。如果是調用debug()輸出的,則為DEBUG,依此類推。-5p 代表將此字串填滿至 5 個字元,以空白補不足處。
  • %r 輸出自應用啟動到輸出該日誌訊息所耗費的毫秒數。
  • %t 輸出產生該日誌事件的線程名。
  • %f 輸出日誌訊息所屬的類別的類別名。


設定log4j


有2種方式可以設定log4j,一個是在撰寫java code時設定,另一個是外部設定(*.properties),外部設定比較有彈性且易於修改,不像前者還要重新編譯code。
1.在撰寫java code時設定:

package codinghunter.log4j;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
public class Log4jTest {
private static Logger logger = Logger.getLogger(Log4jTest.class);
public static void main(String[] args) {
BasicConfigurator.configure();
logger.info("This is an info message.");
logger.debug("This is a debug message.");
}
}

BasicConfigurator.configure(); 就是以預設值去設定log4j
2.外部設定(*.properties)
首先在classpath下建立一個log4j.properties的檔案,設定如下:

//定義 Root Logger 的等級為 INFO,且為其指定一個 appender 名為 rootAppender.
log4j.rootLogger=info, rootAppender

//指定 rootAppender 的類型為ConsoleAppender(輸出再主控台下)
log4j.appender.rootAppender=org.apache.log4j.ConsoleAppender

//指定 rootAppender 的 Layout.
log4j.appender.rootAppender.layout=org.apache.log4j.PatternLayout

//指定 rootAppender Layout 的輸出格式.
log4j.appender.rootAppender.layout.ConversionPattern=%d- %-p -%c - %m%n

//自訂自己的logger,可定義到單一一個class也可以是一個package
log4j.logger.codinghunter.log4j.Log4jTest=INFO, log4jAppender
log4j.appender.log4jAppender=org.apache.log4j.RollingFileAppender
log4j.appender.log4jAppender.File=c:/tmp/codinghunter/Log4jTest/log4j.log
//log4j.appender.log4jAppender.File 為輸出的路徑,如果設定的路徑中有資料夾不存在,它會自動幫你建立
log4j.appender.log4jAppender.MaxFileSize=100KB
log4j.appender.log4jAppender.MaxBackupIndex=10
log4j.appender.log4jAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.log4jAppender.layout.ConversionPattern=%c - %m%n



番外篇:


以下是自動碰到的一個問題,那就是想要一個Logger擁有2個不同等級的Appender,看似好像很一般,但是仔細看一下,指定一個logger的Appender時可以一次指定多個,但設定的等級皆為同一個
Ex:log4j.logger.codinghunter.log4j.Log4jTest=INFO, log4jAppender,log4jAppender2
2個Appender設定的等級皆為INFO,但是我想要一個INFO另一個DEBUG怎麼做呢??
最後加上這個即可:
log4j.appender.log4jAppender.Threshold=DEBUG

其他資料


Log4j提供的appender有以下幾種:
org.apache.log4j.ConsoleAppender(輸出在控制台)
org.apache.log4j.FileAppender(輸出到文件檔案)
org.apache.log4j.DailyRollingFileAppender(每天產生一個文件檔案)
org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的时候產生一個新的文件)
org.apache.log4j.WriterAppender(將log信息以串流格式發送到任意指定的地方)

Log4j提供的layout有以下幾種:
org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以任意地指定布局模式)
org.apache.log4j.SimpleLayout(包含log信息的級別和信息字符串)
org.apache.log4j.TTCCLayout(包含log產生的时間、線程、類别等等信息)

上面有提到對單一個logger的Appender等級的設定,其實還有可以指定package或是class的等級
log4j.logger.codinghunter.log4j.Log4jTest = DEBUG
log4j.logger.codinghunter.log4j = INFO

沒有留言:

張貼留言

有問題就留下吧,盡力而為回答。不要留垃圾訊息就好!