天天看點

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】:日志的簡單使用

​​

  1. package lwf.log.test;  
  2. import java.util.logging.Logger;  
  3. public class LogTest {  
  4.     static String strClassName = LogTest.class.getName();  
  5.     static Logger logger = Logger.getLogger(strClassName);  
  6.     public static double division(int value1, int value2) {  
  7.         double result = 0;  
  8.         try {  
  9.             result = value1 / value2;  
  10.         } catch(ArithmeticException e) {  
  11.             logger.warning("除數不能為0.");  
  12.             e.printStackTrace();  
  13.         }  
  14.         return result;  
  15.     }  
  16.     public static void main(String[] args) {  
  17.         System.out.println(division(5, 0));  
  18. }  

結果:

Java中的日志——Java.util.logging、log4j、commons-logging

從這個例子中你會看到控制台上輸出了日期時間,類名,方法名和“[warning]除數不能為0.”的資訊。

Logger是Java Logging API中的一個類,Logger.getLogger方法建立了一個Logger執行個體。每一個Logger執行個體都必須有個名稱,通常的做法是使用類名稱定義Logger執行個體。

logger.warning方法用來輸出日志資訊,除了warning處,還有severe、info等。我們可以把【例1】再改一下,讓其輸出各種日志資訊。

【例1.2】:日志的級别

[java] ​​view plain​​​​copy​​​​​​​​​​

  1. public static double division(int value1, int value2) {  
  2.     double result = 0;  
  3.     try {  
  4.         result = value1 / value2;  
  5.     } catch(ArithmeticException e) {  
  6.         logger.severe("[severe]除數不能為0.");  
  7.         logger.warning("[warning]除數不能為0.");  
  8.         logger.info("[info]除數不能為0.");  
  9.         logger.config("[config]除數不能為0.");  
  10.         logger.fine("[fine]除數不能為0.");  
  11.         logger.finer("[finer]除數不能為0.");  
  12.         logger.finest("[finest]除數不能為0.");  
  13.         e.printStackTrace();  
  14.     return result;  
Java中的日志——Java.util.logging、log4j、commons-logging

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 

//...

java.util.logging.ConsoleHandler.level = ALL 

這種方式會影響jre下所有使用者。

為了不影響到所有的使用者,我們還可以通過LogManager的readConfiguration(InputStream ins)讀取指定的配制檔案。

【例1.3】:LogManager管理日志

  1. import java.io.IOException;  
  2. import java.io.InputStream;  
  3. import java.util.logging.FileHandler;  
  4. import java.util.logging.Handler;  
  5. import java.util.logging.Level;  
  6. import java.util.logging.LogManager;  
  7. import java.util.logging.LogRecord;  
  8. import java.util.logging.SimpleFormatter;  
  9.     static LogManager logManager = LogManager.getLogManager();  
  10.     static {  
  11.         InputStream inputStream = null;  
  12.             //讀取配制檔案  
  13.             inputStream = LogTest.class.getClassLoader().getResourceAsStream("log.properties");  
  14.             logManager.readConfiguration(inputStream);  
  15.             //添加Logger  
  16.             logManager.addLogger(logger);  
  17.         } catch (SecurityException e) {  
  18.         } catch (IOException e) {  
  19.             logger.severe("[severe]除數不能為0.");  
  20.             logger.warning("[warning]除數不能為0.");  
  21.             logger.info("[info]除數不能為0.");  
  22.             logger.config("[config]除數不能為0.");  
  23.             logger.fine("[fine]除數不能為0.");  
  24.             logger.finer("[finer]除數不能為0.");  
  25.             logger.finest("[finest]除數不能為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包中類的關系圖如下:

Java中的日志——Java.util.logging、log4j、commons-logging

2.log4j 

1.項目串導入log4j的jar包

如Eclipse下項目名右鍵,Build Path\Add Libraries,添加一組使用者自己的jar包。項目結構如下:

Java中的日志——Java.util.logging、log4j、commons-logging

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  

代碼:

  1. import org.apache.log4j.Logger;  
  2. public class Log4jTest {  
  3.     private static Logger logger = Logger.getLogger(Log4jTest.class);    
  4.     public static void main(String[] args) {    
  5.         System.out.println("This is log4j test.");  
  6.         // 記錄debug級别的資訊    
  7.         logger.debug("This is debug message.");    
  8.         // 記錄info級别的資訊    
  9.         logger.info("This is info message.");    
  10.         // 記錄error級别的資訊    
  11.         logger.error("This is error message.");    
  12.     }    

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的配合使用:

項目目錄結構:

Java中的日志——Java.util.logging、log4j、commons-logging

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