java.util.logging.Logger 使用詳解


 

概述:

第1部分 創建Logger對象

第2部分 日志級別

第3部分 Handler

第4部分 Formatter

第5部分 自定義

第6部分 Logger的層次關系

參考 

 

第1部分 創建Logger對象

要使用J2SE的日志功能,首先要取得java.util.logging.Logger實例,這可以通過Logger類的兩個靜態getLogger()方法來取得:

static Logger getLogger(String name) 
         查找或創建一個logger。
static Logger getLogger(String name, String resourceBundleName) 
         為指定子系統查找或創建一個logger。

注意:name是Logger的名稱,當名稱相同時候,同一個名稱的Logger只創建一個。

下面是簡單范例:

 1 public class LoggingDemo {
 2     public static void main(String[] args){
 3         Logger logger = Logger.getLogger("LoggingDemo");
 4         
 5         try{
 6             System.out.println(args[0]);
 7         }catch(ArrayIndexOutOfBoundsException e){
 8             logger.warning("沒有提供執行時的自變量!");
 9         }        
10     }    
11 }

執行結果:

 

第2部分 日志級別

在進行信息的記錄時,依信息程序的不同,會設定不同等級的信息輸出。Java log比log4j的級別詳細,全部定義在java.util.logging.Level里面。

各級別按降序排列如下:

  • SEVERE(最高值)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST(最低值)

此外,還有一個級別OFF,可用來關閉日志記錄,使用級別ALL啟用所有消息的日志記錄。

logger默認的級別是INFO,比INFO更低的日志將不顯示。

Logger的默認級別定義是在jre安裝目錄的lib下面。

# Limit the message that are printed on the console to INFO and above. 
java.util.logging.ConsoleHandler.level = INFO

可以通過操作Logger上的幾個方法來得到不同等級的信息輸出。如下列范例:

 1 public class LoggingDemo {
 2     public static void main(String[] args){
 3         Logger logger = Logger.getLogger("LoggingDemo");
 4         
 5         logger.severe("嚴重信息");
 6 
 7         logger.warning("警示信息");
 8 
 9         logger.info("一般信息");
10 
11         logger.config("設定方面的信息");
12 
13         logger.fine("細微的信息");
14 
15         logger.finer("更細微的信息");
16 
17         logger.finest("最細微的信息");
18     }
19     
20 }

執行結果:

 

此示例中config()方法及以下的信息並沒有顯示出來,這是因為Logger的默認等級是INFO,比這個等級更低的信息,Logger並不會將信息輸出。

Logger的默認等級是定義在執行環境的屬性文件logging.properties中,這個文件位於JRE安裝目錄的lib目錄下。部分內容如下:

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

 

Logger默認的輸出媒介控制器(Handler)是java.util.logging.ConsolerHandler,也就是將信息輸出至控制台。一個Logger可以擁有多個handler,每個handler可以有自己的日志級別,在通過Logger的級別限制后,實際上還要再經過handler的級別限制。所以在上面的范例中如果想要看到所有的信息,則必須同時設定Logger與!ConsoleHandler的級別。下面的范例示范了如何設定:

 1 public class LoggingDemo {
 2     public static void main(String[] args){
 3         Logger logger = Logger.getLogger("LoggingDemo");
 4         
 5         //顯示所有等級的信息
 6         logger.setLevel(Level.ALL);
 7         ConsoleHandler consoleHandler = new ConsoleHandler();
 8         //顯示所有等級的信息
 9         consoleHandler.setLevel(Level.ALL);
10         //設定Handler為!ConsoleHandler
11         logger.addHandler(consoleHandler);        
12         logger.severe("嚴重信息");
13         logger.warning("警示信息");
14         logger.info("一般信息");
15         logger.config("設定方面的信息");
16         logger.fine("細微的信息");
17         logger.finer("更細微的信息");
18         logger.finest("最細微的信息");
19     }
20     
21 }

 

執行結果:

Level.ALL表示顯示所有的信息,所有這一次的執行結果可顯示所有等級的信息。如果要關閉所有的信息,可以設定為Level.OFF。

Logger的Severe(),warning(),info()等方法,實際上是個便捷的方法。也可以直接使用log()方法並指定等級來執行相同的作用,如:

public class LoggingDemo {
    public static void main(String[] args){
        Logger logger = Logger.getLogger("LoggingDemo");
        logger.log(Level.SEVERE, "嚴重信息test");        
    }    
}

結果:

第3部分 Handler

Handler對象從Logger中獲取日志信息,並將這些信息導出。例如,它可將這些信息寫入控制台或文件中,也可以將這些信息發送到網絡日志服務中,或將其轉發到操作系統日志中。

Logger默認的輸出處理者是ConsoleHandler。!ConsoleHandler的輸出是使用System.err對象,而信息的默認等級是INFO,這可以在JRE安裝目錄下lib目錄的logging.properties中看到:

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO

Java SE實現了5個Handler:

(1) java.util.logging.ConsoleHandler 以System.err輸出日志。

(2) java.util.logging.FileHandler 將信息輸出到文件。

(3) java.util.logging.!StreamHandler以指定的!OutputStream實例輸出日志。

(4) java.util.logging.!SocketHandler將信息通過Socket傳送至遠程主機。

(5) java.util.logging.!MemoryHandler將信息暫存在內存中。

以下代碼將信息輸出至文件中:

 1 public class LoggingDemo {
 2     public static void main(String[] args){
 3         Logger logger = Logger.getLogger("LoggingDemo");
 4 
 5         try {
 6             FileHandler fileHandler = new FileHandler("D:\\test/3.txt");
 7             logger.addHandler(fileHandler);
 8             logger.info("測試信息");
 9         } catch (SecurityException e) {
10             e.printStackTrace();
11         } catch (IOException e) {
12             e.printStackTrace();
13         }
14     }
15     
16 }

執行結果:

D:\test\3.text內容如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
  <date>2014-11-25T10:53:49</date>
  <millis>1416884029723</millis>
  <sequence>0</sequence>
  <logger>LoggingDemo</logger>
  <level>INFO</level>
  <class>com.ConcurrentContainer.LoggingDemo</class>
  <method>main</method>
  <thread>1</thread>
  <message>測試信息</message>
</record>
</log>

fileHandler默認的輸出格式是XML格式。輸出格式由java.util.logging.Formatter來控制,下一節詳細介紹Formatter。

第4部分 Formatter

Formatter為格式化LogRecords提供支持。
一般來說,每個Handler都有關聯的Formatter。Formatter接受LogRecord,並將它轉換為一個字符串。

默認提供了兩種Formatter:
1.java.util.logging.SimpleFormatter:標准日志格式,就是我們通常在啟動一些諸如 Tomcat JBoss之類的服務器的時候經常能在控制台下看到的那種形式,就像這樣:

2004-12-20 23:08:52 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8080

2.java.util.logging.XMLFormatter:XML形式的日志格式,如果為Logger添加了一個new XMLFormatter(),那么就會以XML形式輸出,不過更常用的是使用上面介紹的FileHandler輸出到XML文件中。

從上一節的例子可知,FileHandler的默認格式是java.util.logging.XMLFormatter,而ConsolerHandler的默認格式是java.util.logging.SimpleFormatter,可以使用Handler實例的setFormatter()方法來設定信息的輸出格式。例如:

fileHandler.setFormatter(new SimpleFormatter());

FileHandler的Formatter設定為SimpleFormatter,則輸出的日志文件內容就是簡單的文字信息,打開文件后會發現與命令行模式下看到的信息內容相同。

第5部分 自定義

1、Handler

用戶可以定制自己輸出媒介控制器,繼承Handler即可,通常只需要實現Handler中三個未定義的抽象方法:

 publish:主要方法,把日志記錄寫入你需要的媒介。

 flush:清除緩沖區並保存數據。

 close:關閉控制器。

通過重寫以上三個方法可以很容易實現一個新的輸出媒介控制器。

2、Formatter

除了XMLFormatter與!SimpleFormatter之外,也可以自定義日志的輸出格式,只要繼承抽象類Formatter,並重新定義其format()方法即可。format()方法會傳入一個java.util.logging.LogRecord對象作為參數,可以使用它來取得一些與程序執行有關的信息。'

3、日志級別

Java的一個日志級別對應一個整數值,Level有9個內置的級別,分別是:

類型          對應的整數
 OFF         最大整數( Integer. MAX_VALUE
 SEVERE     1000
 WARNING   900
 INFO         800
 CONFIG      700
 FINE          500
 FINER        400
 FINEST      300
 ALL           最小整數(Integer. MIN_VALUE

你也可以定義自己的日志級別,通過繼承Level的方式,譬如:

 1 /**
 2  * 自定義日志級別
 3  * @ClassName: AlertLevel
 4  * TODO
 5  * @author xingle
 6  * @date 2014-11-25 上午9:54:23
 7  */
 8 public class AlertLevel extends Level{
 9 
10     /**
11      * @param name
12      * @param value
13      */
14     protected AlertLevel(String name, int value) {
15         super(name,value);
16     }
17     
18     public static void main(String[] args){
19         Logger logger = Logger.getAnonymousLogger();
20         //低於INFO(800),顯示不出來,因為默認的配置 java.util.logging.ConsoleHandler.level = INFO
21         logger.log(new AlertLevel("ALERT",950), "自定義 lever!");
22     }
23 }

執行結果:

第6部分 Logger的層次關系

 在使用Logger的靜態getLogger()方法取得Logger實例時,給getLogger()方法的名稱是有意義的。如果給定a,實際上將從根(Root)logger繼承一些特性,像日志級別(Level)以及根logger的輸出媒介控制器。如果再取得一個Logger實例,並給定名稱a.b,則這次取得的Logger將繼承pku這個Logger上的特性。從以下范例可以看出Logger在名稱上的繼承關系:

 1 /**
 2  * Logger的層次關系
 3  * @ClassName: LoggerHierarchyDemo
 4  * TODO
 5  * @author xingle
 6  * @date 2014-11-25 上午10:04:54
 7  */
 8 public class LoggerHierarchyDemo {
 9     public static void main(String[] args){
10         Logger onlyfunLogger = Logger.getLogger("a");
11         Logger caterpillarLogger = Logger.getLogger("a.b");
12         System.out.println("root logger:"+onlyfunLogger.getParent());
13         System.out.println("onlyfun logger:" + caterpillarLogger.getParent().getName());
14         System.out.println("caterpillar Logger:" + caterpillarLogger.getName() + "\n");
15         onlyfunLogger.setLevel(Level.WARNING);
16         caterpillarLogger.info("caterpillar ' info");
17         caterpillarLogger.setLevel(Level.INFO);
18         caterpillarLogger.info("caterpillar ' info");
19     }
20 }

執行結果:

getParent()方法可以取得Logger上的上層父Logger,根Logger並沒有名稱,所以直接調用它的toString()以取得字符串描述。當Logger沒有設定等級時,則使用父Logger的等級設定,所以在上面的范例中,onlyfunLogger設定等級為WARNING時,caterpillarLogger調用info()方法時並不會有信息顯示(因為WARNING等級比INFO高)。


 

參考 :

 1.主題:log4j詳解與實戰


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM