這個(gè)描述文件一般放在可以放在兩個(gè)地方:(1)WEB-INF/classes目錄下,或者放在在/project_root/,也就是你的web_app的根目錄下。利用這個(gè)控制日志紀(jì)錄的配置,當(dāng)然也可以通過xml文件配置,這里我們暫且說說properties的配置。
建立文件名log4j.properties文件。放在%tomca_home%/web_app/fcxtest/目錄下。
文件內(nèi)容如下:(fcxtest為自己建立的web app目錄)
#--------------------------------
# 設(shè)定logger的root level為DEBUG,指定的輸出目的地(appender)為A1
log4j.rootLogger=DEBUG, A1
# 設(shè)定調(diào)試信息的輸出位置,此處設(shè)定輸出為控制臺(tái)
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# 設(shè)定調(diào)試信息的輸出位置,此處設(shè)定輸出為fcxtest.log文件
# log4j.appender.A1=org.apache.log4j.RollingFileAppender
# log4j.appender.A1.File=fcxtest.log
# log4j.appender.A1.MaxFileSize=1000KB
# 設(shè)定制定的A1使用的PatternLayout.
# 有關(guān)ConversionPattern中的轉(zhuǎn)意字符的含義參考說明
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d %-5p [%t] %C{2} (%F:%L) - %m%n
#--------------------------------
1.2建立測試用的Servlet類
這個(gè)測試的com.fcxlog.LogShow類主要是顯示如何使用log4j。
package com.fcxlog;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;
public class LogShow extends javax.servlet.http.HttpServlet{
protected String configfile = "log4j.properties";
public void init() throws ServletException{
ServletContext sct = getServletContext();
System.out.println("[Log4j]: The Root Path: " + sct.getRealPath("/"));
//指定自己的properties文件
//以前使用的是BasicConfigurator.configure(),現(xiàn)在使用PropertyConfigurator替代
org.apache.log4j.PropertyConfigurator.configure(sct.getRealPath("/") + configfile);
}
public void service(javax.servlet.http.HttpServletRequest req,javax.servlet.http.HttpServletResponse res){
//初始化Logger,以前使用Category,現(xiàn)在改用Logger替代
//org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(LogShow.class);
org.apache.log4j.Logger log = ora.apache.log4j.Logger.getLogger(LogShow.class);
log.info("調(diào)試信息");
}
}
1.3 測試了
至于如何測試,發(fā)布,就不說了。
在此說明:
(1)本篇可能錯(cuò)誤不少,一方面是參考《Short introduction to log4j》著翻譯了一點(diǎn),有諸多言辭不妥之處,還望指正。一方面,憑借自己的理解,所以難免有不全的地方,還望各位補(bǔ)充。
(2)因?yàn)闀r(shí)間有限,每天只能寫一點(diǎn),本文主要是介紹有關(guān)Logger及Logger level相關(guān)概念的
(3)有關(guān)Log4j介紹(一),請參閱:http://www.javaren.com/bbs/cgi-bin/topic.cgi?forum=1&topic=12766&show=0#lastviewpost
概述:
本文主要是簡要的介紹了Log4j的api,以及其一些特征和設(shè)計(jì)原理。它本身是一個(gè)開源的軟件,允許開發(fā)者任意的操縱應(yīng)用系統(tǒng)日志信息。Log4j的使用通過外部配置文件進(jìn)行配置。
任何大型應(yīng)用系統(tǒng)都有其自己的系統(tǒng)日志管理或跟蹤的API,所以在1996年的時(shí)候,E.U. SEMPER項(xiàng)目組(http://www.semper.org/)也開發(fā)其自己的日志管理API,后來經(jīng)過無數(shù)次的修改和補(bǔ)充,發(fā)展成了現(xiàn)在的log4j,一個(gè)給予java的日志管理工具包。有關(guān)最新的版本信息和源碼,請?jiān)L問http://jakarta.apache.org/log4j/docs/index.html
把紀(jì)錄語句放在代碼之中,是一種低端的調(diào)試方法,不過有時(shí)卻不得不說是很有效,也是必需的。畢竟很多時(shí)候,調(diào)試器并不見得很適用。特別是在多線程應(yīng)用程序(multithread application)或分布式應(yīng)用程序(distributed application)
經(jīng)驗(yàn)告訴我們,在軟件開發(fā)生命周期中,日志系統(tǒng)是一個(gè)非常重要的組件。當(dāng)然,日志系統(tǒng)也有其自身的問題,過多的日志紀(jì)錄會(huì)降低系統(tǒng)運(yùn)行的速度。
(一)Log4j的三個(gè)重要組件?? Loggers, Appenders, Layouts
這三個(gè)組件協(xié)同的工作,使得開發(fā)者能夠依據(jù)信息類別和級別去紀(jì)錄信息,并能夠運(yùn)行期間,控制信息記錄的方式已經(jīng)日志存放地點(diǎn)。
(二)記錄器層次(Logger hierarchy)
幾乎任何紀(jì)錄日志的API得功能都超越了簡單的System.out.print語句。允許有選擇控制的輸出日志信息,也就是說,某的時(shí)候,一些日志信息允許輸出,而另一些則不允許輸出。這就假設(shè)日志紀(jì)錄信息之間是有分別的,根據(jù)開發(fā)者自己定義的選擇標(biāo)準(zhǔn),可以對日志信息加以分類。
紀(jì)錄器的命名是依據(jù)實(shí)體的。下面有一段有點(diǎn)繞口的解釋,我就直抄了,各位可以看看:(Name Hierarchy)A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.
(形象的解釋,比如存在記錄器 a.b.c,記錄器a.b,記錄器a。那么a就是a.b的ancestor,而a.b就是a.b.c的parent,而a.b.c就是a.b的child)
根紀(jì)錄器(root logger)是記錄器層次的頂端。它有兩個(gè)獨(dú)特點(diǎn):(1)總是存在的(2)能夠被重新找回??梢酝ㄟ^訪問類的靜態(tài)方法 Logger.getRootLogger 重新得到。其他的紀(jì)錄器通過訪問靜態(tài)方法 Logger.getLogger 被實(shí)例話或被得到,這個(gè)方法將希望獲得的記錄器的名稱作為參數(shù)。一些Logger類的方法描述如下:
public class Logger {
// Creation & retrieval methods:
public static Logger getRootLogger();
public static Logger getLogger(String name);
// printing methods:
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);
}
記錄器被賦予級別,這里有一套預(yù)定的級別標(biāo)準(zhǔn):DEBUG, INFO, WARN, ERROR and FATAL ,這些是在 org.apache.log4j.Level 定義的。你可以通過繼承Level類定義自己的級別標(biāo)準(zhǔn),雖然并不鼓勵(lì)這么做。
如果給定的記錄器沒有被賦予級別,則其會(huì)從離其最近的擁有級別的ancestor處繼承得到。如果ancestor也沒有被賦予級別,那么就從根記錄器繼承。所以通常情況下,為了讓所有的記錄器最終都能夠被賦予級別,跟記錄器都會(huì)被預(yù)先設(shè)定級別的。比如我們在操作properties文件中,會(huì)寫這么一句:log4j.rootLogger=DEBUG, A1 。實(shí)際上就這就指定了root Logger和root Logger level。
Appenders
Log4j允許記錄信息被打印到多個(gè)輸出目的地,一個(gè)輸出目的地叫做Appender。目前的Log4j存在的輸出目的地包括:控制臺(tái)(Console),文件(File),GUI Componennt,Remote Socket Server,JMS,NT Event Logger,and Remote Unix Syslog daemons。
多個(gè)Appender可以綁定到一個(gè)記錄器上(Logger)。
通過方法 addAppender(Logger.addAppender) 可以將一個(gè)Appender附加到一個(gè)記錄器上。每一個(gè)有效的發(fā)送到特定的記錄器的記錄請求都被轉(zhuǎn)送到那個(gè)與當(dāng)前記錄器所綁定的Appender上。(Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy),換句話說,Appender的繼承層次是附加在記錄器繼承層次上的。舉個(gè)例子:如果一個(gè)Console Appender被綁定到根記錄器(root Logger),那么所有的記錄請求都可以至少被打印到Console。另外,把一個(gè)file Appender綁定到記錄器C,那么針對記錄器C(或C的子孫)的記錄請求都可以至少發(fā)送到Console Appender和file Appender。當(dāng)然這種默認(rèn)的行為方式可以跟改,通過設(shè)定記錄器的additivity flag(Logger.setAdditivity)為false,從而可以使得Appender的不再具有可加性(Additivity)。
下面簡要介紹一下Appender Additivity。
Appender Additivity:記錄器C所記錄的日志信息將被發(fā)送到與記錄器C以及其祖先(ancestor)所綁定的所有Appender。
但是,如果記錄器C的祖先,叫做P,它的additivity flag被設(shè)定為false。那么,記錄信息仍然被發(fā)送到與記錄器C及其祖先,但只到達(dá)P這一層次,包括P在內(nèi)的記錄器的所有Appender。但不包括P祖先的。
通常,記錄器的additivity flag的被設(shè)置為true。
Layouts
這一塊主要是介紹輸出格式的。PatternLayout,Log4j標(biāo)準(zhǔn)的分配器,可以讓開發(fā)者依照conversion patterns去定義輸出格式。Conversion patterns有點(diǎn)像c語言的打印函數(shù)。
參看配置文件的java properties,如下面的兩行:
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d %-5p [%t] %C{2} (%F:%L) - %m%n
第一行就指定了分配器,第二行則指定了輸出的格式。
有關(guān)輸出格式的定義可以參考/org/apache/log4j/PatternLayout.html
更基礎(chǔ)的知識(shí),可以到田貫升門診室,另有一篇偏重基礎(chǔ)的介紹~?