茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1671888 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_2372155.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2017/2/18 3:37:08
[JAVA] Log4J

資料來源:http://jameslin1203memo.blogspot.com/2006_03_01_jameslin1203memo_archive.html#114256516645009463

這篇筆記是參考 Log4j 官方網站的文件,以及網路上所找到的文章所寫成的。

簡介 :
Log4j 是一套開放源碼的工具,方便編程人員在程式中加入 log 機制,並輸出到各種目標上。Log4j 能夠透過外部的設定檔(properites 或 XML)進行設定。Log4j 能夠將 log message 寫到 console, 檔案,串流,TCP 協定的伺服器, Unix Syslog daemon 等。Log4j 具有 5 種 log 層級(DEBUG, INFO, WARN, ERROR, FATAL),可用於不同的系統狀態下所產生的訊息。

組成 Log4j 的三大元件 :
Logger - 由編程人員在程式中使用,進行 logging 的元件
Appender - 負責將 log message 輸出到各種裝置上
Layout - 決定 log message 的格式

Log4j 的階層架構 :
一個程式中可以擁有多個 Logger,這些 Logger之間以名稱區分,並以此區分出階層。例如有一個 Logger 的名稱為 "com.foo",那麼另一個名為 "com.foo.bar" 的 Logger 就隸屬於 "com.foo" logger,如果 "com.foo.bar" 未定義自己的 log 等級,則以 "com.foo" 的 log 等級為預設值。
階層的最高為 root logger。Root logger 一定在存,不具有名稱屬性,可以隨時在程式中以 Logger.getRootLogger() 取得,其它 logger 則以 Logger.getLogger(String loggerName) 取得。

Logger :
Logger 可以被指派等級。能夠指派給 Logger 的等級有 : DEBUG, INFO, WARN, ERROR, FATAL 5 種,定義在 org.apache.log4j.Level 類別中。這 5 種等級的高低順序為 FATAL > ERROR > WARN > INFO > DEBUG。
Logger 的等級決定它產生 log message 的數量 : Logger 只寫"出高於或等於本身等級"的 log message。例如某個 Logger 的等級被設定為 WARN,那麼它只會寫出等級為 WARN, ERROR, FATAL 的 log message,對於 DEBUG, INFO 的 log message 則不予理會。
若是 Logger 的等級未被設定,則會自動使用 parent(上一層) 的等級。如果程式中所有的 Logger 都未設定等級,則由 root logger 決定。
Logger 之間以名稱區分,所以在程式中任何地方,呼叫 Logger.getLogger(),並傳入同一個 Logger 名稱,則會得到同一個 Logger 的 reference。
Logger 之間以名稱區分出階層。即使父階層在程式中出現的時機比子階層晚,例如 "com.foo" logger 比 "com.foo.bar" 被取得的時間來得晚,"com.foo" 仍然是 "com.foo.bar" 的父階層(會影響到子階層 logger 未被定義的屬性, log 等級, appender, layout )。

Appender:
透過 Appender, Logger 能夠將 log message 輸出到指定的裝置上。一個 Logger 能夠擁有多個 Appender,所以 Logger 能夠同時將 log message 輸出到多個個裝置上。
Appender 的設定亦會反映在 Logger 的階層中。當 Logger 輸出一筆 log message 時,父階層的 Appender 和自己的 Appender(如果有的話)都會記錄到這筆 log message;例如 "com.foo" Logger 有一個 Appender 將 log message 輸出到 console,而 "com.foo.bar" 有一個 Appender 將 log message 輸出到 檔案;當 "com.foo.bar" Logger 輸出一筆 log message 時, console 和檔案都會出現這筆 log message。而最簡單的例子,就是當 root logger 擁有一個輸出到 console 的 Appender 時,則程式中所有的 logger 所產生的 log message 都會輸出到 console。唯一個例外的情況,就是當某個 logger 將自己的 additivity 屬性設為 false(Logger.setAdditivity(false)),則此 logger 與隸屬於它的子 logger 都不會將 log message 寫到 console。

Layout:
編程人員透過 Layout 的配置,能夠自由改變 Logger 寫出 log message 的格式。例如,為 Logger 加入一個 conversion pattern 為 "%r [%t] %-5p %c - %m%n" 的 PatternLayout,則輸出的 log message 就可能會像下列這樣:
176 [main] INFO  org.foo.Bar - Located nearest gas station.

PatternLayout 的 格式字元列表如下:
    %c 輸出日誌訊息所屬的類別的全名
    %d 輸出日誌時間點的日期或時間,指定格式的方式:%d{yyy-MM-dd HH:mm:ss }。
    %l 輸出日誌事件的發生位置,即輸出日誌訊息的語句處於它所在的類別的第幾行。
    %m 輸出代碼中指定的訊息,如log(message)中的message。
    %n 輸出一個列尾符號。
    %p 輸出優先階層,即DEBUG,INFO,WARN,ERROR,FATAL。如果是調用debug()輸出的,則為DEBUG,依此類推。-5p 代表將此字串填滿至 5 個字元,以空白補不足處。
    %r 輸出自應用啟動到輸出該日誌訊息所耗費的毫秒數。
    %t 輸出產生該日誌事件的線程名。
    %f 輸出日誌訊息所屬的類別的類別名。

Layout 亦會反映在 Logger 的階層上。

設定 :
設定 Log4j 有 2 種方式 : 以 Java 程式碼配置組態,或是以外部設定檔進行設定。無論以哪種方式進行,不外下列幾個主要的步驟:

定義 Root Logger 的等級 - 此設定會成為 logger 的預設等級
定義 Root Logger 的 Appender - 如果有定義 Root Logger,則 Root Logger 的 Appender 一定要指定
定義 Root Logger Appender 的 Layout - 定義 Layout 的類別後,可以選擇是否要定義該 Layout 的 conversion pattern
定義個別的 Logger,其它步驟同 Root Logger

最簡單的使用方式 - 使用 BasicConfigurator 進行設定, Root Logger 將會被設定為 DEBUG 等級,並且將 log message 以 "%r [%t] %p %c %x - %m%n" 的格式輸出到 console :
package yc.usingLog4j;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

public class UsingLog4j {
     private static Logger logger = Logger.getLogger(UsingLog4j.class);

     public static void main(String[] args) {
     BasicConfigurator.configure();

     logger.info("This is an info message.");
     logger.debug("This is a debug message.");
 }
}

將 Log4j 的設定提到外部檔案(*.properties),讓程式較具有彈性。以下是一個設定檔的範例 :
#定義 Root Logger 的等級為 INFO,且為其指定一個 appender 名為 rootAppender.
log4j.rootLogger=info, rootAppender

#指定 rootAppender 的類型.
log4j.appender.rootAppender=org.apache.log4j.ConsoleAppender

#指定 rootAppender 的 Layout.
log4j.appender.rootAppender.layout=org.apache.log4j.PatternLayout

#指定 rootAppender Layout 的輸出格式.
log4j.appender.rootAppender.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

#設定特定名稱的 Logger.
log4j.logger.yc.usingLog4j.UsingLog4jA=INFO, log4jaAppender
log4j.appender.log4jaAppender=org.apache.log4j.RollingFileAppender
log4j.appender.log4jaAppender.File=d:/tmp/usinglog4j.log
log4j.appender.log4jaAppender.MaxFileSize=100KB
log4j.appender.log4jaAppender.MaxBackupIndex=10
log4j.appender.log4jaAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.log4jaAppender.layout.ConversionPattern=%c - %m%n

Log4j 會從 class path 中尋找 log4j.properties,並自動讀取其中的設定。

一般的使用方法 : 為 Root logger 設定 DEBUG 等級, Appender 及格式。其它的 logger 不做其它設定;當程式要轉換為 debug 或 release 模式時,只需修改 Root Logger 的等級即可。
使用範例 :
package yc.usingLog4j;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class UsingLog4j {
  private static Logger logger = Logger.getLogger(UsingLog4j.class);

  public static void main(String[] args) {
      BasicConfigurator.configure();

      /* 改變 Root Logger 的等級為 INFO */
      //Logger.getRootLogger().setLevel(Level.INFO);

      /* 鴨子類別庫的 client 只做 INFO 等級的 log;類別庫裡才使用 DEBUG 等級的 log. */
      logger.info("Create a Redhead Duck.");
      RedheadDuck rhd = new RedheadDuck(new FlyWithWings(), new Quack());
      logger.info("Play with the duck.");
      rhd.display();
      rhd.performFly();
      rhd.performQuack();

      logger.info("Create a RubberDuck.");
      RubberDuck rbd = new RubberDuck(new FlyWithRocket(), new Squeak());
      logger.info("Play with the duck.");
      rbd.display();
      rbd.performFly();
      rbd.performQuack();
      }
  }

  interface FlyBehavior {
      public void fly();
  }

  class FlyWithWings implements FlyBehavior {
      private static Logger logger = Logger.getLogger(FlyWithWings.class);

      public void fly() {
      logger.debug("Fly with wings...");
  }
}

class FlyWithRocket implements FlyBehavior {
  private static Logger logger = Logger.getLogger(FlyWithRocket.class);

  public void fly() {
      logger.debug("Fly with a rocket...");
  }
}

interface QuackBehavior {
  public void quack();
}

class Quack implements QuackBehavior {
  private static Logger logger = Logger.getLogger(Quack.class);

  public void quack() {
      logger.debug("Quack...");
  }
}

class Squeak implements QuackBehavior {
  private static Logger logger = Logger.getLogger(Squeak.class);

  public void quack() {
      logger.debug("Squeak...");
  }
}

abstract class Duck {
  private FlyBehavior flyBehavior;

  private QuackBehavior quackBehavior;

  public Duck(FlyBehavior flyBehavior, QuackBehavior quackBehavior) {
      this.flyBehavior = flyBehavior;
      this.quackBehavior = quackBehavior;
  }

  public void performQuack() {
      this.quackBehavior.quack();
  }

  public void performFly() {
   this.flyBehavior.fly();
  }

  public abstract void display();
}

class RedheadDuck extends Duck {
  private static Logger logger = Logger.getLogger(RedheadDuck.class);

  public RedheadDuck(FlyBehavior flyBehavior, QuackBehavior quackBehavior) {
      super(flyBehavior, quackBehavior);
  }

  @Override
  public void display() {
      logger.debug("A RedheadDuck is showing up...");
  }
}

class RubberDuck extends Duck {
  private static Logger logger = Logger.getLogger(RubberDuck.class);

  public RubberDuck(FlyBehavior flyBehavior, QuackBehavior quackBehavior) {
      super(flyBehavior, quackBehavior);
  }

  @Override
  public void display() {
      logger.debug("A RubberDuck is showing up...");
  }
}

在一般情況下運行時所得到的 log message :
0 [main] INFO yc.usingLog4j.UsingLog4j  - Create a Redhead Duck.
16 [main] INFO yc.usingLog4j.UsingLog4j  - Play with the duck.
16 [main] INFO yc.usingLog4j.UsingLog4j  - Create a RubberDuck.
16 [main] INFO yc.usingLog4j.UsingLog4j  - Play with the duck.

而在除錯模式下則是 :
0 [main] INFO yc.usingLog4j.UsingLog4j  - Create a Redhead Duck.
109 [main] INFO yc.usingLog4j.UsingLog4j  - Play with the duck.
109 [main] DEBUG yc.usingLog4j.RedheadDuck  - A RedheadDuck is showing up...
109 [main] DEBUG yc.usingLog4j.FlyWithWings  - Fly with wings...
109 [main] DEBUG yc.usingLog4j.Quack  - Quack...
109 [main] INFO yc.usingLog4j.UsingLog4j  - Create a RubberDuck.
125 [main] INFO yc.usingLog4j.UsingLog4j  - Play with the duck.
125 [main] DEBUG yc.usingLog4j.RubberDuck  - A RubberDuck is showing up...
125 [main] DEBUG yc.usingLog4j.FlyWithRocket  - Fly with a rocket...
125 [main] DEBUG yc.usingLog4j.Squeak  - Squeak...


原文出處:[JAVA] Log4J @ 過太爽的日子 :: 隨意窩 Xuite日誌
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|