Log4j使用總結

Log4j的類圖

Log4j類圖

日誌記錄器(Logger)只輸出那些級別高於或等於它的級別的信息。如果沒有設置日誌記錄器(Logger)的級別,那麼它將會繼承最近的祖先的級別。因此,如果在pack1.pack2包中創建一個日誌記錄器(Logger)並且沒有設置級別,那它將會繼承在包pack1中創建的日誌記錄器(Logger)的級別。如果在pack1中沒有創建日誌記錄器(Logger)的話,那麼在pack1中創建的日誌記錄器(Logger)將繼承root 日誌記錄器(Logger)的級別,root日誌記錄器(Logger)經常被實例化而可用,它的默認級別爲DEBUG

Logger的級別:

Level.ALL < Level.DEBUG < Level.INFO < Level.WARN < Level.ERROR < Level.FATAL < Level.OFF

 

Appender(日誌目的地)

每個Logger都可以擁有一個或者多個appender,每個appender表示一個日誌的輸出目的地,可以使用Logger.addAppender(Appender)Logger增加一個appender,可以使用Logger.removeAppender(Appender)來爲Logger移除一個appender

默認情況下loggeradditivity值爲true,表示子logger將繼承父Logger的所有appender,該選項可以被重置爲false,表示子logger將不再繼承父Loggerappender,如果一個categoryadditivityfalse,同時沒有appender-ref時將報錯。

<category name="CORE" additivity="false">

        <priority value="info"/>

        <appender-ref ref="fileAppender"/>

     </category>

在程序中Logger logger = Logger.getLogger(CORE);記錄日誌時將記錄info或者info級別以上的日誌信息到fileAppender

Appender 控制日誌怎樣輸出。下面列出一些可用的Appender(log4j API中所描述的 http://jakarta.apache.org/log4j/docs/api/index.html):

ConsoleAppender:使用用戶指定的佈局(layout) 輸出日誌事件到System.out或者 System.err。默認的目標是System.out ConsoleAppender appender = new ConsoleAppender(new PatternLayout());

可以使用ConsoleAppender對象把日誌輸出到控制檯。每個ConsoleAppender都有一個target,表示它的輸出目的地。它可以是System.out,標準輸出設備(緩衝顯示屏);或者是System.err,標準錯誤設備(不緩衝顯示屏)。

<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">

         <layout class="org.apache.log4j.SimpleLayout"/>

     </appender>

FileAppender 把日誌事件寫入一個文件 appender = new FileAppender(new PatternLayout(),"filename");  FileAppender(Layout layout, String filename, boolean append)

<appender name="fileAppender" class="org.apache.log4j.FileAppender">

         <param name="File" value="cyaniteCHLog.txt" />

         <param name="Append" value="true" />

         <layout class="org.apache.log4j.PatternLayout">

              <param name="ConversionPattern" value="%d [%t] %p - %m%n" />

         </layout>

     </appender>

RollingFileAppender 擴展FileAppender備份容量達到一定大小的日誌文件。不同的是該日誌文件的大小受到限制,當日志內容超出最大的尺寸時,該文件將向上滾動(最老的日誌被擦除)。還可以在該類對象中指定爲日誌文件做多少個備份

<appender name="rollingFileAppend"

         class="org.apache.log4j.RollingFileAppender">

         <param name="File" value="cyaniteCH.log" />

         <param name="Append" value="true" />

         <param name="MaxBackupIndex" value="2" />

         <param name="MaxFileSize" value="1024" />

         <layout class="org.apache.log4j.PatternLayout">

              <param name="ConversionPattern" value="%d [%t] %p - %m%n" />

         </layout>

     </appender>

 

DailyRollingFileAppender 擴展FileAppender,因此多個日誌文件可以以一個用戶選定的頻率進行循環日誌記錄。

WriterAppender根據用戶的選擇把日誌事件寫入到Writer或者OutputStream appender = new WriterAppender(new PatternLayout(),new FileOutputStream("filename"));

SMTPAppender 當特定的日誌事件發生時,一般是指發生錯誤或者重大錯誤時,發送一封郵件。

SocketAppender 給遠程日誌服務器(通常是網絡套接字節點)發送日誌事件(LoggingEvent)對象。

SocketHubAppender 給遠程日誌服務器羣組(通常是網絡套接字節點)發送日誌事件(LoggingEvent)對象。

SyslogAppender給遠程異步日誌記錄的後臺精靈程序(daemon)發送消息。

TelnetAppender 一個專用於向只讀網絡套接字發送消息的log4j appender

還可以實現 Appender 接口,創建以自己的方式進行日誌輸出的Appender

 

Layout

Appender必須使用一個與之相關聯的 Layout,這樣它才能知道怎樣格式化它的輸出。當前,log4j具有三種類型的Layout:

HTMLLayout 格式化日誌輸出爲HTML表格。 HTMLLayout layout = new HTMLLayout();

PatternLayout 根據指定的 轉換模式格式化日誌輸出,或者如果沒有指定任何轉換模式,就使用默認的轉換模式。 %n is newline

String pattern = "Milliseconds since program start: %r %n";

pattern += "Classname of caller: %C %n";

pattern += "Date in ISO8601 format: %d{ISO8601} %n";

pattern += "Location of log event: %l %n";

pattern += "Message: %m %n %n";

PatternLayout layout = new PatternLayout(pattern);

SimpleLayout 以一種非常簡單的方式格式化日誌輸出,它打印級別 Level,然後跟着一個破折號“-“ ,最後纔是日誌消息。SimpleLayout layout = new SimpleLayout();

 

Log4J採用類似C語言中的printf函數的打印格式格式化日誌信息,打印參數如下: %m 輸出代碼中指定的消息

  %p 輸出優先級,即DEBUGINFOWARNERRORFATAL
  %r 輸出自應用啓動到輸出該log信息耗費的毫秒數
  %c 輸出所屬的類目,通常就是所在類的全名
  %t 輸出產生該日誌事件的線程名
  %n 輸出一個回車換行符,Windows平臺爲“/r/n”Unix平臺爲“/n”
  %d 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也可以在其後指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},輸出類似:20021018 221028921
  %l 輸出日誌事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。

 

Logger的初始化

BasicConfigurator.configure();

BasicConfigurator.configure()方法使用最簡的方法配置log4j環境。注:所謂配置log4j環境,就是指配置root logger,因爲所有其它的logger都是root logger的後代,所以它們(默認情況下)都將繼承root logger的性質。

BasicConfigurator.configure()完成的任務是:

  • 用默認pattern創建PatternLayout對象p
    PatternLayout p = new PatternLayout("%-4r[%t]%-5p%c%x - %m%n");

  • p創建ConsoleAppender對象a,目標是system.out,標準輸出設備:
    ConsoleAppender a = new ConsoleAppender(p,ConsoleAppender.SYSTEM_OUT);

  • root logger增加一個ConsoleAppender p
    rootLogger.addAppender(p);

  • root loggerlog level設置爲DEBUG級別:
    rootLogger.setLevel(Level.DEBUG);

DOMConfigurator.configure()

xml格式的log4j配置文件需要使用org.apache.log4j.xml.DOMConfigurator.configure()方法來讀入。對xml文件的語法定義可以在log4j的發佈包中找到:org/apache/log4j/xml/log4j.dtd

PropertyConfigurator.configure()

讀取使用Java的特性文件編寫的配置文件。

 

Log4jxml配置文件的樹狀結構

log4jxml配置文件的樹狀結構如下所示,下圖只顯示了常用的部分。

xml declaration and DTD

 |

log4j:configuration

 |

 +-- appender (name, class)

 |     |

 |     +-- param (name, value)

 |     +-- layout (class)

 |           |

 |           +-- param (name, value)

 +-- logger (name, additivity)  | category

 |     |

 |     +-- level (class, value)

 |     |     |

 |     |     +-- param (name, value)

 |     +-- appender-ref (ref)

 +-- root

 |

 +-- param (name, class)

 +-- level

 |     |

 |     +-- param (name, value)

 +-- appender-ref (ref)  

          

xml declaration and DTD

xml配置文件的頭部包括兩個部分:xml聲明和DTD聲明。頭部的格式如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

          

Log4jconfigurationroot element

  • xmlns:log4j [#FIXED attribute] : 定義log4j的名字空間,取定值"http://jakarta.apache.org/log4j/"

  • appender [* child] : 一個appender子元素定義一個日誌輸出目的地

  • logger [* child] : 一個logger子元素定義一個日誌寫出器

  • root [? child] : root子元素定義了root logger

appender

appender元素定義一個日誌輸出目的地。

  • name [#REQUIRED attribute] : 定義appender的名字,以便被後文引用

  • class [#REQUIRED attribute] : 定義appender對象所屬的類的全名

  • param [* child] : 創建appender對象時傳遞給類構造方法的參數

  • layout [? child] : appender使用的layout對象

layout

layout元素定義與某一個appender相聯繫的日誌格式化器。

  • class [#REQUIRED attribute] : 定義layout對象所屬的類的全名

  • param [* child] : 創建layout對象時傳遞給類構造方法的參數

logger

logger元素定義一個日誌輸出器。

  • name [#REQUIRED attribute] : 定義logger的名字,以便被後文引用

  • additivity [#ENUM attribute] : 取值爲"true"(默認)或者"false",是否繼承父logger的屬性

  • level [? child] : 定義該logger的日誌級別

  • appender-ref [* child] : 定義該logger的輸出目的地

root

root元素定義根日誌輸出器root logger

  • param [* child] : 創建root logger對象時傳遞給類構造方法的參數

  • level [? child] : 定義root logger的日誌級別

  • appender-ref [* child] : 定義root logger的輸出目的地

level

level元素定義logger對象的日誌級別。

  • class [#IMPLIED attribute] : 定義level對象所屬的類,默認情況下是"org.apache.log4j.Level

  • value [#REQUIRED attribute] : level對象賦值。可能的取值從小到大依次爲"all""debug""info""warn""error""fatal""off"。當值爲"off"時表示沒有任何日誌信息被輸出

  • param [* child] : 創建level對象時傳遞給類構造方法的參數

appender-ref

appender-ref元素引用一個appender元素的名字,爲logger對象增加一個appender

  • ref [#REQUIRED attribute] : 一個appender元素的名字的引用

  • appender-ref元素沒有子元素

param

param元素在創建對象時爲類的構造方法提供參數。它可以成爲appenderlayoutfiltererrorHandlerlevelcategoryFactoryroot等元素的子元素。

  • name and value [#REQUIRED attributes] : 提供參數的一組名值對

  • param元素沒有子元素

 

Log4j的編碼習慣

  • 讓每個類都擁有一個private staticLogger對象,用來輸出該類中的全部日誌信息

  • 使用xml文件來完成對log4j環境的配置。在項目的main class中的靜態初始化塊裏放log4j環境的配置代碼。注意:在一個項目中,log4j環境只需要被配置一次,而不是在每個使用了logger的類裏都需要調用一次

  • MyClass.class作爲參數創建該類的靜態Logger對象   ,這個繼承RootLogger的配置

  

 

 

 

我的應用
在項目測試過程中,由於登錄服務器查看日誌比較麻煩,而測試過程中又需要經常查看日誌,可通過TelenetAppenderApplet結合動態展現日誌內容。增加TelnetAppender logging.xml中,
<appender name="telnetAppender" class="org.apache.log4j.net.TelnetAppender" >
        <param name="port" value="9999"/>
       <layout class="org.apache.log4j.PatternLayout">
           <param name="ConversionPattern" value="%d{ISO8601} %-5p %10c - %m%n" />
       </layout>
    </appender>
 
<root>
       <priority value="debug" />
       <appender-ref ref="telnetAppender"/>
    </root>
下面是一張效果圖。
系統日誌遠程查看Applet
 
Applet中通過線程監聽TelnetAppender設置的端口,頁面模仿AxisSOAPMonitor設計。可通過StartStop按鈕開始和停止輸出日誌內容。點擊狀態欄在輸出域輸出About信息。程序可從資源中下載,兩個Java文件,可直接編譯後放在WebContent下,稍作改動可作爲Java應用程序使用。
在實際部署中,內部服務器不會對外開放,也就是說你通過Applet訪問服務器的IP和端口時,不能建立鏈接,變通的方法是採用Ajax+Servlet。在一個Servlet中實現類似Applet提供的功能,這樣只會和Log4J 建立一條Socket鏈接,考慮到頁面反應時間的問題,在Servlet對日誌的後10000條記錄進行緩存,然後後面的覆蓋前面的數據,根據建立的Session中保存的記錄編號提取日誌。在JSP頁面中通過Ajax每隔2秒鐘提取一次日誌內容增加到TextArea。運行良好。頁面效果:
頁面動態查看日誌內容
 
系統中增加了對日誌的記錄級別的動態調整和日誌輸出對象的調整,通過程序調整RootLogLevelAppender,removeAppender或者addAppender
不足的方面在於如果在同一個容器中的多個應用,那麼每個應用不能共享同一個端口,每個應用TelnetAppender必須使用不同的端口,應可以改善,同時在有些容器中有時候會在關閉應用的時候,TelnetAppender不能關閉,導致啓動的時候報錯。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章