Java中的日誌——Java.util.logging、log4j、commons-logging
Java中給項目程序添加log主要有三種方式,一使用JDK中的java.util.logging包,一種是log4j,一種是commons-logging。其中log4j和commons-logging都是apache軟件基金會的開源項目。這三種方式的區別如下:
Java.util.logging,JDK標準庫中的類,是JDK 1.4 版本之後添加的日誌記錄的功能包。
log4j,最強大的記錄日誌的方式。可以通過配置 .properties 或是 .xml 的文件, 配置日誌的目的地,格式等等。
commons-logging,最綜合和常見的日誌記錄方式,是Java中的一個日誌接口,一般會與log4j一起使用。自帶SimpleLog可用於日誌記錄。
1.Java.util.logging
【例1.1】:日誌的簡單使用
[java] view plaincopy
- package lwf.log.test;
- import java.util.logging.Logger;
- public class LogTest {
- static String strClassName = LogTest.class.getName();
- static Logger logger = Logger.getLogger(strClassName);
- public static double division(int value1, int value2) {
- double result = 0;
- try {
- result = value1 / value2;
- } catch(ArithmeticException e) {
- logger.warning("除數不能為0.");
- e.printStackTrace();
- }
- return result;
- }
- public static void main(String[] args) {
- System.out.println(division(5, 0));
- }
- }
結果:
從這個例子中你會看到控制臺上輸出了日期時間,類名,方法名和“[warning]除數不能為0.”的信息。
Logger是Java Logging API中的一個類,Logger.getLogger方法創建了一個Logger實例。每一個Logger實例都必須有個名稱,通常的做法是使用類名稱定義Logger實例。
logger.warning方法用來輸出日誌信息,除了warning處,還有severe、info等。我們可以把【例1】再改一下,讓其輸出各種日誌信息。
【例1.2】:日誌的級別
[java] view plaincopy
- public static double division(int value1, int value2) {
- double result = 0;
- try {
- result = value1 / value2;
- } catch(ArithmeticException e) {
- logger.severe("[severe]除數不能為0.");
- logger.warning("[warning]除數不能為0.");
- logger.info("[info]除數不能為0.");
- logger.config("[config]除數不能為0.");
- logger.fine("[fine]除數不能為0.");
- logger.finer("[finer]除數不能為0.");
- logger.finest("[finest]除數不能為0.");
- e.printStackTrace();
- }
- return result;
- }
結果:
Java Logging API提供了七個日誌級別用來控制輸出。這七個級別分別是:
級別 |
SEVERE |
WARNING |
INFO |
CONFIG |
FINE |
FINER |
FINEST |
調用方法 |
severe() |
warning() |
info() |
config() |
fine() |
finer() |
finest() |
含意 |
嚴重 |
警告 |
信息 |
配置 |
良好 |
較好 |
最好 |
但在上面的例子中我們可以看到只輸出了SEVERE、WARNING、INFO三個等級的日誌,並沒有如我們相像中的好樣輸出各個級別的日誌信息。這是因為默認日誌輸出級別的設置是info,也就是說只有info或它以上的級別被輸出,它以下的級別不被輸出。那如何修改這個設置呢?
日誌(Log)的配制:
1.代碼設置
使用setLevel();但這種方式不能改變console的級別,只能改變輸出到文件的日誌的級別。
2.修改logging.properties
默認的外部配置文件 是JRE中lib/logging.properties文件。你可以打開這個文件,修改以下兩行為:
.level=ALL //... |
這種方式會影響jre下所有用戶。
為了不影響到所有的用戶,我們還可以通過LogManager的readConfiguration(InputStream ins)讀取指定的配制文件。
【例1.3】:LogManager管理日誌
[java] view plaincopy
- package lwf.log.test;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.logging.FileHandler;
- import java.util.logging.Handler;
- import java.util.logging.Level;
- import java.util.logging.LogManager;
- import java.util.logging.LogRecord;
- import java.util.logging.Logger;
- import java.util.logging.SimpleFormatter;
- public class LogTest {
- static String strClassName = LogTest.class.getName();
- static Logger logger = Logger.getLogger(strClassName);
- static LogManager logManager = LogManager.getLogManager();
- static {
- InputStream inputStream = null;
- try {
- //讀取配制文件
- inputStream = LogTest.class.getClassLoader().getResourceAsStream("log.properties");
- logManager.readConfiguration(inputStream);
- //添加Logger
- logManager.addLogger(logger);
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static double division(int value1, int value2) {
- double result = 0;
- try {
- result = value1 / value2;
- } catch(ArithmeticException e) {
- logger.severe("[severe]除數不能為0.");
- logger.warning("[warning]除數不能為0.");
- logger.info("[info]除數不能為0.");
- logger.config("[config]除數不能為0.");
- logger.fine("[fine]除數不能為0.");
- logger.finer("[finer]除數不能為0.");
- logger.finest("[finest]除數不能為0.");
- e.printStackTrace();
- }
- return result;
- }
- public static void main(String[] args) {
- System.out.println(division(5, 0));
- }
- }
log.properties:
# "handlers" specifies a comma separated list of log Handler #handlers= java.util.logging.ConsoleHandler handlers= java.util.logging.FileHandler
# Default logging level. .level= CONFIG
# default file output is in "E:\Test" directory. java.util.logging.FileHandler.pattern = E:/Test/Log%u.log java.util.logging.FileHandler.limit = 50000 java.util.logging.FileHandler.count = 1 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# Limit the message that are printed on the console to CONFIG and above. java.util.logging.ConsoleHandler.level = CONFIG java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# Facility specific properties.Provides extra control for each logger. # For example, set the com.xyz.foo logger to only log SEVERE messages: com.xyz.foo.level = SEVERE |
這樣,用戶就可以自己定義配制文件了。在E:\Test下可以看到輸出的日誌文件Log0.log
java.util.logging包中類的關系圖如下:
參考文章:
http://blog.csdn.net/dl88250/article/details/1843813
2.log4j
1.項目串導入log4j的jar包
如Eclipse下項目名右鍵,Build Path\Add Libraries,添加一組用戶自己的jar包。項目結構如下:
2.修改log4j的配制文件,設置日誌輸出的級別、格式等
log4j的log有5個級別:FATAL(嚴重的 )、ERROR(錯誤 )、WARN(警告)、INFO(信息)、DEBUG(調試 )。
3.在項目代碼中適當添加日誌。
【例2.1】
log4j.properties:
#set log level: show debug, info, error log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender which outputs to System.out. #log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1=org.apache.log4j.FileAppender
# A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout #out log4j.appender.A1.File=E:/test/log4j.log
# set log output format‘s style log4j.appender.A1.layout=org.apache.log4j.TTCCLayout |
代碼:
[java] view plaincopy
- package lwf.log.test;
- import org.apache.log4j.Logger;
- public class Log4jTest {
- private static Logger logger = Logger.getLogger(Log4jTest.class);
- public static void main(String[] args) {
- System.out.println("This is log4j test.");
- // 記錄debug級別的信息
- logger.debug("This is debug message.");
- // 記錄info級別的信息
- logger.info("This is info message.");
- // 記錄error級別的信息
- logger.error("This is error message.");
- }
- }
log4j的使用和配制另參見:http://blog.csdn.net/luoweifu/article/details/43638495
3.commons-logging
commons-logging提供的是一個日誌(Log)接口(interface),是為那些需要建立在不同環境下使用不同日誌架構的組件或庫的開發者創建的,其中包括Apache Log4j以及Java log的日誌架構。把日誌信息抽象成commons-logging的Log接口,並由commons-logging在運行時決定使用哪種日誌架構。因為Log4j的強大功能,commons-logging一般會和Log4j一起使用,這幾乎成為了Java日誌的標準工具。
commons-logging有兩個基本的抽象類:Log(基本記錄器)和LogFactory(負責創建Log實例)。當commons-logging.jar被加入到CLASSPATH(通常將commons-logging.jar放在web project下的WebContent\WEB-INF\lib目錄中)之後,它會合理地猜測你想用的日誌工具,然後進行自我設置,用戶根本不需要做任何設置。默認的LogFactory是按照下列的步驟去發現並決定那個日誌工具將被使用的(按照順序,尋找過程會在找到第一個工具時中止,這個順序非常重要):
00001. 尋找當前factory中名叫org.apache.commons.logging.Log配置屬性的值
00002. 尋找系統中屬性中名叫org.apache.commons.logging.Log的值
00003. 如果應用程序的classpath中有log4j,則使用相關的包裝(wrapper)類(Log4JLogger)
00004. 如果應用程序運行在jdk1.4的系統中,使用相關的包裝類(Jdk14Logger)
00005. 使用簡易日誌包裝類(SimpleLog)
commons-logging與log4j的配合使用:
項目目錄結構:
common-logging.properties:
#use commons-logging default SimpleLog # org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
#use log4j org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JCategoryLog
#JDK1.4 Logger #org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger |
代碼:
[cpp] view plaincopy
- package lwf.log.test;
- import org.apache.log4j.Logger;
- public class Log4jTest {
- private static Logger logger = Logger.getLogger(Log4jTest.class);
- public static void main(String[] args) {
- System.out.println("This is log4j test.");
- // 記錄debug級別的信息
- logger.debug("This is debug message.");
- // 記錄info級別的信息
- logger.info("This is info message.");
- // 記錄error級別的信息
- logger.error("This is error message.");
- }
- }
參考:
http://www.cnblogs.com/xwdreamer/archive/2011/12/28/2304598.html
http://shift8.iteye.com/blog/1316802
Java中的日誌——Java.util.logging、log4j、commons-logging