JDK日志框架之自定義日志Handler淺析
自定義日志 Handler
所有的 Handler 類都是繼承自 java.util.logging.Handler 抽象類,該類結(jié)構(gòu)圖 如圖 所示。
圖- Handler 類圖
由該類圖可見,Handler 抽象類提供了抽象接口:publish, flush 和 close .這些接口提供了日志輸出的基本功能。同時(shí) Handler 類保存了 Formatter,F(xiàn)ilter 和 Level 對(duì)象用來(lái)控制日志輸出。因此,編寫自定義的Handler 類需要如下步驟:
1、繼承 Handler 抽象類
2、實(shí)現(xiàn) publish,flush 和 close 方法。其中publish 方法是用于發(fā)布一條日志記錄。 flush 方法是清空內(nèi)存緩沖區(qū)。 close 方法是當(dāng)應(yīng)用程序關(guān)閉的時(shí)候,釋放該 Handler 類所申請(qǐng)的資源(如文件,socket 等)
3、設(shè)置默認(rèn)的 Formatter,F(xiàn)ilter 和 Level 對(duì)象。必要的時(shí)候,可以在類的初始化時(shí)候讀取配置文件來(lái)設(shè)置這些參數(shù)。
一個(gè)典型的自定義 Handler 類實(shí)現(xiàn)如清單 1 所示。
清單 1 自定義 Handler 類
- public class MyHandler extends Handler {
- private bOOlean doneHeader = false;
- public MyHandler() {
- setLevel(Level.INFO);
- setFilter(null);
- setFormatter(new SimpleFormatter());
- }
- _cnnew1@Override
- public void close() throws SecurityException {
- if (!doneHeader) {
- output(getFormatter().getHead(this));
- doneHeader = true;
- }
- output(getFormatter().getTail(this));
- flush();
- }
- @Override
- public void flush() {
- // 清空緩沖區(qū)
- }
- @Override
- public void publish(LogRecord record) {
- if (!isLoggable(record)) {
- return;
- }
- String msg = getFormatter().format(record);
- try {
- if (!doneHeader ) {
- output(getFormatter().getHead(this));
- doneHeader = true;
- }
- output(msg);
- } catch (Exception ex) {
- reportError(null, ex, ErrorManager.WRITE_FAILURE);
- }
- }
- private void output(String message) {
- // 實(shí)現(xiàn)日志輸出
- }
- }
這里 reportError 方法是將日志類中的錯(cuò)誤信息輸出到外界,這個(gè)是由 ErrorManager 類實(shí)現(xiàn)的,ErrorManager 類負(fù)責(zé)記錄日志框架中Handler 的錯(cuò)誤,一般情況下是將該錯(cuò)誤打印到控制臺(tái)中。具體的每條日志消息被JDK日志框架封裝成 LogRecord 對(duì)象,該類部分定義如 清單 2 所示。
清單 2 LogRecord 類定義
- public class LogRecord implements java.io.Serializable {
- public String getLoggerName();
- public void setLoggerName(String name);
- public ResourceBundle getResourceBundle();
- public void setResourceBundle(ResourceBundle bundle);
- public Level getLevel();
- public void setLevel(Level level);
- public String getMessage();
- public void setMessage(String message);
- public Object[] getParameters();
- public void setParameters(Object parameters[]);
- public int getThreadID();
- public void setThreadID(int threadID);
- public long getMillis();
- public void setMillis(long millis);
- public Throwable getThrown();
- public void setThrown(Throwable thrown);
- ...
- }
由清單 2 可見,LogRecord 類包含了一個(gè)日志消息的級(jí)別、消息文本、時(shí)間、參數(shù)、線程等等所有的信息,這些都交給 Handler,F(xiàn)ormatter 和 Filter 這些對(duì)象來(lái)處理。同時(shí)該類也是可序列化的,可以序列化到網(wǎng)絡(luò)和文件中。該類還可以和一個(gè) ResourceBundle 對(duì)象綁定,實(shí)現(xiàn)消息字符串的本地化處理。
本文描述了一個(gè)典型的自定義的Handler 類的實(shí)現(xiàn)。那么現(xiàn)在你對(duì)JDK日志框架之自定義日志Handler是不是更加有感覺了呢?
【編輯推薦】