1. 程式人生 > >java Logger 的使用與配置2

java Logger 的使用與配置2

Java Logging API是sun公司於2002年5月正式釋出的。它是自J2SE 1.4版本開始提供的一個新的應用程式介面。它能夠很方便地控制和輸出日誌資訊到檔案,控制檯或其它使用者定義的地方,如資料庫,電子郵件等。所以它是為終端使用者,系統管理員,軟體服務工程師和開發人員提供的一種捕捉安全漏洞,檢查配置正確性,跟蹤調查系統執行瓶頸和調查系統執行錯誤的工具。

Java Logging API的設計目標是要:
1. 能夠在執行時開啟或關閉日誌功能;
  2. 能夠非常精密地控制日誌,即能夠開啟或關閉日誌的某個個別功能;
  3. 能夠在執行時註冊日誌服務,當然也可以註冊新的第三方日誌服務;
  4. 能夠提供連線服務,使Java Logging API能與現存的日誌系統(如作業系統的日誌功能)連線;
  5. 能夠支援顯示高優先度的資訊給終端使用者。

輸出日誌

由於Java Logging API提供了非常方便的介面,你可以在下面的例子裡看到它的使用有多方便。
例1:
  import java.util.logging.Logger;     // <= (1)
  public class HelloLogWorld {
    private static String name = HelloLogWorld.class.getName();    // <= (2)
    private static Logger log = Logger.getLogger(name);
    public void sub() {
      log.info("Hello Logging World");    // <= (3)
    }
    public static void main(String[] args) {
      HelloLogWorld logWorld = new HelloLogWorld();
      logWorld.sub();
    }
  }


說明:
  (1) Logger是Java Logging API中的一個類。在此之前,你必須確認你所使用的J2SE是1.4或更高版本。
  (2) Logger.getLogger方法建立了一個Logger例項。每一個Logger例項都必須有個名稱,通常的做法是使用類名稱定義Logger例項。後面還會講到這樣做的原因。
  (3) log.info方法用來輸出日誌資訊。
執行例1你可以看到控制檯上輸出了日期時間,類名,方法名和Hello Logging World的資訊。

輸出的種類
Java Logging API提供了七個等級用來控制輸出。這七個等級分別是:
SEVERE (最高等級) 
WARNING 
INFO 
CONFIG 
FINE 
FINER 
FINEST (最低等級)
與之對應,在Logger類中也為你預備好了這七個等級的輸出方法。下面是使用這幾種方法輸出日誌資訊的例子。
例2:
import java.util.logging.Logger;
public class LevelTest {
    private static String name = HelloLogWorld.class.getName();
    private static Logger log = Logger.getLogger(name);
    public void sub() {
        log.severe("severe level");        // <= (1)
        log.warning("warning level");    // <= (2)
        log.info("info level");            // <= (3)
        log.config("config level");        // <= (4)
        log.fine("fine level");            // <= (5)
        log.finer("finer level");            // <= (6)
        log.finest("finest level");        // <= (7)
    }
    public static void main(String[] args) {
        LevelTest test = new LevelTest();
        test.sub();
    }
}



執行例2你可能看到控制檯上只輸出了(1)-(3)的資訊,(4)-(7)的資訊並沒有如想象的那樣被輸出。這不要緊,繼續看下面的內容你就知道原因了。

控制輸出
上面例2中info以下的等級資訊沒有被輸出是因為預設日誌輸出等級的設定是info,也就是說只有info或它以上的等級被輸出,它以下的等級不被輸出。通過變更設定可以使輸出等級改變。變更輸出等級的方法有兩種,一是使用外部配置檔案,二是使用程式編碼。通常都是使用第一種方法。預設的外部配置檔案是JRE中lib/logging.properties檔案。你可以開啟這個檔案,修改以下兩行為:
.level= ALL
java.util.logging.ConsoleHandler.level = ALL
修改完後,再執行一次例2,這次(1)-(7)的內容就都輸出出來了。你可以修改輸出級別為以下任何值,試一試輸出有什麼變化。
OFF
SEVERE 
WARNING 
INFO 
CONFIG 
FINE 
FINER 
FINEST 
ALL

自定義的配置檔案
如果你不想使用系統提供的預設配置檔案lib/logging.properties,那麼也可以使用自己定義的配置檔案。使用自定義配置檔案的方法有很多種,比較方便的方法是通過定義系統屬性值java.util.logging.config.file來設定自定義配置檔案。例如在執行例2時,使用下面的命令:
java -Djava.util.logging.config.file=mylogging.properties LevelTest
其中mylogging.properties是你自定義的配置檔案。如果需要,你還可以加上檔案的路徑名。

更多的輸出控制
除了前面講到的七個輸出等級外,Logger類中還提供了以下三個便於程式設計師除錯時使用的輸出資訊方法:
entering
exiting
throwing
它們是與FINER相同等級的輸出,分別用於程式入口,出口和例外時的輸出。除此之外Logger類中還準備了一些輸出資訊的方法,這些留待以後詳細介紹。

輸出內容的本地化
Java Logging API已經考慮到了國際化對應問題。在輸出資訊上你可以使用ResourceBundle提供本地化的輸出資訊。下面舉個例子說明。
例3:
import java.util.logging.Logger;

public class LocalTest {
    private static String name = HelloLogWorld.class.getName();
    private static Logger log = Logger.getLogger (name, "local");        <= (1)
    public void sub() {
        log.severe("level.severe");        <= (2)
        log.warning("level.warning");    <= (3)
        log.info("level.info");            <= (4)
        log.config("level.config");        <= (5)
        log.fine("level.fine");            <= (6)
        log.finer("level.finer");            <= (7)
        log.finest("level.finest");        <= (8)
    }
    public static void main(String[] args) {
        LocalTest test = new LocalTest();
        test.sub();
    }
}


你可以比較一下例2和例3。可以看到例3的Logger.getLogger 方法呼叫中增加了一個傳參,並且(2)-(8)中的輸出內容也改變了。(1)中增加的字串傳參就是使用ResourceBundle配置時的屬性檔名。下面就需要建立這個屬性檔案local.properties如下:
level.severe=severe level
level.warning=warning level
level.info=info level
level.config=config level
level.fine=fine level
level.finer=finer level
level.finest=finest level
現在執行例3可以看到輸出結果並不是(2)-(8)中定義的內容。或許你已經想到了,(2)-(8)中定義的實際上是local.properties檔案中的屬性鍵名,而輸出是這些屬性鍵名所對應的鍵值。那麼或許你要問如果屬性鍵名在屬性檔案中不存在怎麼辦,答案很簡單,如果它不是屬性鍵名就一定是要輸出的內容,所以就照原樣輸出了事。