我這兒有兩個程式,一個是普通的java程式,實現了一個“九九表”;另一個是servlet。我這兒用的tomcat是4.1.12,J2SE是1.3.1,log4j的版本是1.2.8.
一、九九表。
環境設定:需要將log4j-1.2.8.jar放入CLASSPATH變數中。
Hello.java檔案的內容如下:
import org.apache.log4j.*;
public class Hello{
static Logger logger = Logger.getLogger(Hello.class);
public static void main(String[] args) {
int i,j;
// BasicConfigurator.configure();
PropertyConfigurator.configure(args[0]);
logger.info("Entering application.");
for(i=1;i<10;i++){
logger.debug(""+i);
for (j=1;j<=i;j++){
logger.warn(""+j);
System.out.print(i*j);
System.out.print("\t");
}
System.out.println("");
}
logger.info("Exiting application.");
}
log4j的設定檔log4j.inf的內容如下:
log4j.rootLogger=WARN, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
#log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
# Print the date in ISO 8601 format
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.foo=WARN
運行:
javac Hello.java
java Hello log4j.inf
結果會在螢幕上顯示,並在example.log檔案中記錄。
二、servlet
環境設定:將log4j-1.2.8.jar及servlet.jar放入環境變數CLASSPATH中,並且要將log4j-1.2.8複製到$TOMCAT_HOME/common/lib目錄下。
假定,有一個布署到tomcat的應用叫myweb。
servlet程式Log4jInit.java的位置在$TOMCAT_HOME/webapps/myweb/WEB-INF/classes/com/hedong/learning/log4j/目錄下,內容如下:
package com.hedong.learning.log4j;
import org.apache.log4j.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Log4jInit extends HttpServlet {
public void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j");
// if the log4j-init-file is not set, then no point in trying
System.out.println("................log4j start");
if(file != null) {
PropertyConfigurator.configure(prefix+file);
}
}
public void doGet(HttpServletRequest req, HttpServletResponse res) {
}
}
在Log4jInit.java所在目錄下編譯它:
javac Log4jInit.java
myweb的設定檔案web.xml在$TOMCAT_HOME/webapps/myweb/WEB-INF/目錄下,增加如下紅色部分。
</web-app>
...........
<servlet>
<servlet-name>log4j-init</servlet-name>
<servlet-class>com.hedong.learning.log4j.Log4jInit</servlet-class>
<init-param>
<param-name>log4j</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
同時,在這個目錄下建一個檔案名稱叫log4j.properties,內容如下:
log4j.rootLogger=INFO, A1 , R
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=$TOMCAT_HOME/webapps/dbweb/logs/log4j.log<----將$TOMCAT_HOME換成tomcat的安裝目錄
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
記住,別忘了建立目錄$TOMCAT_HOME/webapps/dbweb/logs/,如果它不存在的話。
建立目錄$TOMCAT_HOME/webapps/dbweb/test/,然後在這個目錄下建立一個檔案test.jsp,內容如下:
<%@ page contentType="text/html; charset=GB2312" %>
<%@ page import="org.apache.log4j.*" %>
<%
Logger logger = Logger.getLogger("test.jsp");
logger.info("befor say hi");
%>
<h1> Hi</h1>
<%
logger.info("after say hi");
%>
然後,重新啟動tomcat,通過瀏覽器訪問這個jsp頁面,如http://yourdomain.com:8080/myweb/test/test.jsp,如果一切正常,會看到一個大大的HI。然後,在伺服器上的$TOMCAT_HOME/webapps/dbweb/logs/log4j.log檔案中看到如下的資訊:
INFO HttpProcessor[8080][4] test.jsp - befor say hi
INFO HttpProcessor[8080][4] test.jsp - after say hi
。在預設的情況下,tomcat的螢幕輸出被重新導向到$TOMCAT_HOME/logs/catalina.out檔案中,在檔案的最後也應看到上述的輸出。
前面主要記了一些原理,今天是實務。
1、研究發現,一個系統中4%的代碼是用來作logging的。
2、Log4J的設定檔(Configuration File)就是用來設定記錄器的層級、存放器和布局的,它可接key=value格式的設定或xml格式的設定資訊。通過配置,可以建立出Log4J的運行環境。
Log4J運行時,不對環境做任何假定,尤其是沒有預設的存放器。
3、有幾種方式可以配置Log4J
1)在程式中調用BasicConfigurator.configure()方法;
2)配置放在檔案裡,通過命令列參數傳遞檔案名稱字,通過PropertyConfigurator.configure(args[x])解析並配置;
3)配置放在檔案裡,通過環境變數傳遞檔案名稱等資訊,利用log4j預設的初始化過程解析並配置;
4)配置放在檔案裡,通過應用伺服器配置傳遞檔案名稱等資訊,利用一個特殊的servlet來完成配置。
看下面的例子:
import com.foo.Bar;
// Import log4j classes.
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
public class MyApp {
// Define a static logger variable so that it references the
// Logger instance named "MyApp".
static Logger logger = Logger.getLogger(MyApp.class);
public static void main(String[] args) {
// Set up a simple configuration that logs on the console.
BasicConfigurator.configure();
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
logger.info("Exiting application.");
}
}
package com.foo;
import org.apache.log4j.Logger;
public class Bar {
static Logger logger = Logger.getLogger(Bar.class);
public void doIt() {
logger.debug("Did it again!");
}
}
BasicConfigurator.configure給根記錄器增加一個ConsoleAppender,輸出格式通過PatternLayout設為"%-4r [%t] %-5p %c %x - %m%n",還有根記錄器的預設層級是Level.DEBUG.
記錄器之間的關係如:
輸出結果如下:
0 [main] INFO MyApp - Entering application.
36 [main] DEBUG com.foo.Bar - Did it again!
51 [main] INFO MyApp - Exiting application.
下面的代碼結合配置資訊,會得到與上述程式一樣的結果。
import com.foo.Bar;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class MyApp {
static Logger logger = Logger.getLogger(MyApp.class.getName());
public static void main(String[] args) {
// BasicConfigurator replaced with PropertyConfigurator.
PropertyConfigurator.configure(args[0]);
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
logger.info("Exiting application.");
}
}
設定檔的內容如下:
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
利用設定檔,可以很方便地修改配置。如下例
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
#log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
# Print the date in ISO 8601 format
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.foo=WARN
對於tomcat4,利用環境變數傳遞參數的,可參見以下幾個例子
unix設定
export CATALINA_OPTS ="-Dlog4j.configuration=foobar.txt"<===用PropertyConfigurator解析
export CATALINA_OPTS ="-Dlog4j.debug -Dlog4j.configuration=foobar.xml"<===用DOMConfigurator解析
以下是windows設定
set CATALINA_OPTS =-Dlog4j.configuration=foobar.lcf -Dlog4j.configuratorClass=com.foo.BarConfigurator<===用com.foo.BarConfigurator解析
set CATALINA_OPTS =-Dlog4j.configuration=file:/c:/foobar.lcf
設定檔位置如果沒有明確指明,則要放在WEB-INF/classes目錄下。
4、用servlet配置log4j
以下都是參考冰之火的文章,抄來放在這兒,並做了一些必要的修改。需要說明的是,下面的代碼需要自己寫並發布,下的jar中沒有這個類。待我以後寫一個,也放上來。我也寫了兩個,在筆記(三)中。
在Application目錄下的web.xml檔案加入以後代碼
<servlet>
<servlet-name>log4jlog4j-init</servlet-name>
<servlet-class>com.apache.jakarta.log4j.Log4jInit</servlet-class>
<init-param>
<param-name>log4j</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
這段代碼的意思是說,在Tomcat啟動時載入com.apache.jakarta.log4j.Log4jInit這個名叫Log4jInit.class這個類檔案。
其中Log4jInit.class的原始碼如下
package com.apache.jakarta.log4j;
import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Log4jInit extends HttpServlet {
public void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j");
// if the log4j-init-file is not set, then no point in trying
System.out.println("................log4j start");
if(file != null) {
PropertyConfigurator.configure(prefix+file);
}
}
public void doGet(HttpServletRequest req, HttpServletResponse res) {
}
}
在載入的過程中,程式會讀取/WEB-INF/log4j.properties這個檔案。
設定檔講解如下:
# Set root logger level to DEBUG and its only appender to A1
#log4j中有五級logger
#FATAL 0
#ERROR 3
#WARN 4
#INFO 6
#DEBUG 7
#配置根Logger,其文法為:
#log4j.rootLogger = [ level ] , appenderName, appenderName, …
log4j.rootLogger=INFO, A1 ,R
#這一句設定以為著所有的log都輸出
#如果為log4j.rootLogger=WARN, 則意味著只有WARN,ERROR,FATAL
#被輸出,DEBUG,INFO將被屏蔽掉.
# A1 is set to be a ConsoleAppender.
#log4j中Appender有幾層如控制台、檔案、GUI組件、甚至是套介面伺服器、NT的事件記錄器、UNIX Syslog守護進程等
#ConsoleAppender輸出到控制台
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 使用的輸出布局,其中log4j提供4種布局. org.apache.log4j.HTMLLayout(以HTML表格形式布局)
#org.apache.log4j.PatternLayout(可以靈活地指定配置模式),
#org.apache.log4j.SimpleLayout(包含日誌資訊的層級和資訊字串),
#org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等等資訊)
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
#靈活定義輸出格式 具體查看log4j javadoc org.apache.log4j.PatternLayout
#d 時間 ....
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
#R 輸出到檔案 RollingFileAppender的擴充,可以提供一種日誌的備份功能。
log4j.appender.R=org.apache.log4j.RollingFileAppender
#記錄檔的名稱
log4j.appender.R.File=log4j.log
#記錄檔的大小
log4j.appender.R.MaxFileSize=100KB
# 儲存一個備份檔案
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.TTCCLayout
#log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
配置根Logger,其文法為:log4j.rootLogger = [ level ] , appenderName, appenderName, ...
level 是日誌記錄的優先順序
appenderName就是指定日誌資訊輸出到哪個地方。您可以同時指定多個輸出目的地。
配置日誌資訊輸出目的地Appender,其文法為
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
...
log4j.appender.appenderName.option = valueN
Log4j提供的appender有以下幾種:
org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(檔案),
org.apache.log4j.DailyRollingFileAppender(每天產生一個記錄檔),
org.apache.log4j.RollingFileAppender(檔案大小到達指定尺寸的時候產生一個新的檔案),
org.apache.log4j.WriterAppender(將日誌資訊以流格式發送到任意指定的地方)
配置日誌資訊的格式(布局),其文法為:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
....
log4j.appender.appenderName.layout.option = valueN
Log4j提供的layout有以下幾種:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以靈活地指定配置模式),
org.apache.log4j.SimpleLayout(包含日誌資訊的層級和資訊字串),
org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等等資訊)
相關資料:
http://www-128.ibm.com/developerworks/cn/java/l-log4j/index.html