1. 程式人生 > >簡潔易用的日誌模組——log4j

簡潔易用的日誌模組——log4j

開發中最常見的事情就是輸出程式的各種執行資訊,在公司裡看到同事各種syso,syse等,隨意輸出,寫的多了,最後就顯得雜亂無章了,比如說除錯的時候只需要顯示提示資訊,釋出之後就需要只顯示嚴重錯誤資訊。因此從筆記中翻出曾經的一點關日誌記錄的文章——Log4j。當然現在也有Log4j2了,至於區別下次有時間再寫。

log4j詳解

簡介

程式開發環境中的日誌記錄是由嵌入在程式中以輸出一些對開發人員有用資訊的語句所組成。例如,跟蹤語句(trace),結構轉儲和常見的 System.out.printlnprintf除錯語句。log4j提供分級方法在程式中嵌入日誌記錄語句。日誌資訊具有多種輸出格式和多個輸出級別。

使用一個專門的日誌記錄包,可以減輕對成千上萬的System.out.println語句的維護成本,因為日誌記錄可以通過配置指令碼在執行時得以控制。 log4j維護嵌入在程式程式碼中的日誌記錄語句。通過規範日誌記錄的處理過程,一些人認為應該鼓勵更多的使用日誌記錄並且獲得更高程度的效率。

安裝

http://logging.apache.org/log4j/2.x/中下載jar,新增的路徑中。

基本概念

使用log4j大概涉及3個主要概念:

Logger負責處理日誌記錄的大部分操作。

日誌記錄器(Logger)是日誌處理的核心元件。log4j具有5種正常級別(Level)日誌記錄器(Logger)

的可用級別Level:

1static Level  DEBUG

DEBUG Level指出細粒度資訊事件對除錯應用程式是非常有幫助的。

2static Level  INFO

INFO level表明訊息在粗粒度級別上突出強調應用程式的執行過程。

3static Level  WARN

WARN level表明會出現潛在錯誤的情形。

4static Level  ERROR

ERROR level指出雖然發生錯誤事件,但仍然不影響系統的繼續執行。

5static Level  FATAL

FATAL level指出每個嚴重的錯誤事件將會導致應用程式的退出。

級別順序:DEBUG< INFO < WARN < ERROR < FATAL

(優先順序:低->高)

另外,還有兩個可用的特別的日誌記錄級別:

static Level ALL

ALL Level是最低等級的,用於開啟所有日誌記錄。

static Level OFF

OFF Level是最高等級的,用於關閉所有日誌記錄。

日誌記錄器(Logger)的行為是分等級的。日誌記錄器(Logger)將只輸出那些級別高於或等於它的級別的資訊。如果沒有設定日誌記錄器(Logger)的級別,那麼它將會繼承最近的祖先的級別(也就是繼承父包)。因此,如果在包com.foo.bar中建立一個日誌記錄器(Logger)並且沒有設定級別,那它將會繼承在包com.foo中建立的日誌記錄器(Logger)的級別。如果在com.foo中沒有建立日誌記錄器(Logger)的話,那麼在com.foo.bar中建立的日誌記錄器(Logger)將繼承root日誌記錄器(Logger)的級別,root日誌記錄器(Logger)經常被例項化而可用,它的級別為DEBUG

日誌記錄器的使用:

1、建立一個日誌記錄器(Logger)的方法:

1Logger logger = Logger.getRootLogger();

2Logger logger = Logger.getLogger("MyLogger");

3static Logger logger = Logger.getLogger(test.class);

2、為日誌記錄器設定級別:

logger.setLevel((Level)Level.WARN);

可以使用7個級別中的任何一個; Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR,Level.FATAL, Level.ALL and Level.OFF.

Appender負責控制日誌記錄操作的輸出。

1ConsoleAppender:使用使用者指定的佈局(layout)輸出日誌事件到System.out或者 System.err。預設的目標是System.out

2DailyRollingFileAppender擴充套件FileAppender,因此多個日誌檔案可以以一個使用者選定的頻率進行迴圈日誌記錄。

3FileAppender把日誌事件寫入一個檔案

4RollingFileAppender擴充套件FileAppender備份容量達到一定大小的日誌檔案。

5WriterAppender根據使用者的選擇把日誌事件寫入到Writer或者OutputStream

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

7SocketAppender給遠端日誌伺服器(通常是網路套接位元組點)傳送日誌事件(LoggingEvent)物件。

8SocketHubAppender給遠端日誌伺服器群組(通常是網路套接位元組點)傳送日誌事件(LoggingEvent)物件。

9SyslogAppender給遠端非同步日誌記錄的後臺精靈程式(daemon)傳送訊息。

10TelnetAppender一個專用於向只讀網路套接字傳送訊息的log4j appender

還可以實現 Appender介面,建立以自己的方式進行日誌輸出的Appender

使用方法:

1、使用ConsoleAppender

ConsoleAppender appender = new ConsoleAppender(new PatternLayout());

建立了一個控制檯appender,具有一個預設的PatternLayout。它使用了預設的System.out輸出。

2、使用FileAppender

FileAppender appender = null;

try {

appender = new FileAppender(new PatternLayout(),"filename");

} catch(Exception e) {}

上面用到的建構函式:

FileAppender(Layout layout, String filename)

例項化一個FileAppender並且開啟變數"filename"指定的檔案。

另一個有用的建構函式是:

FileAppender(Layout layout, String filename, boolean append)

例項化一個FileAppender並且開啟變數"filename"指定的檔案。

這個建構函式還可以選擇是否對指定的檔案進行追加的方式輸出。如果沒有指定值,那麼預設的方式就是追加。

3、使用WriterAppender

WriterAppender appender = null;

try {

appender = new WriterAppender(new PatternLayout(),new FileOutputStream("filename"));

} catch(Exception e) {}

這個WriterAppender使用的建構函式帶有PatternLayoutOutputStream引數,在這種情況下, FileOutputStream用於向一個檔案輸出。當然,它還具有其他可用的建構函式。

Layout負責格式化Appender的輸出。

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

HTMLLayout格式化日誌輸出為HTML表格。

PatternLayout根據指定的轉換模式格式化日誌輸出,或者如果沒有指定任何轉換模式,就使用預設的轉換模式。

SimpleLayout以一種非常簡單的方式格式化日誌輸出,它列印級別Level,然後跟著一個破折號-,最後才是日誌訊息。

TTCCLayout 包含日誌產生的時間、執行緒、類別等等資訊

程式碼示例1

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.apache.log4j.SimpleLayout;

import org.apache.log4j.FileAppender;

public class simpandfile {

static Logger logger = Logger.getLogger(simpandfile.class);

public static void main(String args[]) {

SimpleLayout layout = new SimpleLayout();

FileAppender appender = null;

try {

appender = new FileAppender(layout,"output1.txt",false);

} catch(Exception e) {}

logger.addAppender(appender);

logger.setLevel((Level) Level.DEBUG);

logger.debug("Here is some DEBUG");

logger.info("Here is some INFO");

logger.warn("Here is some WARN");

logger.error("Here is some ERROR");

logger.fatal("Here is some FATAL");

}

}

程式碼示例2

import java.io.*;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.apache.log4j.HTMLLayout;

import org.apache.log4j.WriterAppender;

public class htmlandwrite {

static Logger logger = Logger.getLogger(htmlandwrite.class);

public static void main(String args[]) {

HTMLLayout layout = new HTMLLayout();

WriterAppender appender = null;

try {

FileOutputStream output = newFileOutputStream("output2.html");

appender = new WriterAppender(layout,output);

} catch(Exception e) {}

logger.addAppender(appender);

logger.setLevel((Level) Level.DEBUG);

logger.debug("Here is some DEBUG");

logger.info("Here is some INFO");

logger.warn("Here is some WARN");

logger.error("Here is some ERROR");

logger.fatal("Here is some FATAL");

}

}

程式碼示例3

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.apache.log4j.PatternLayout;

import org.apache.log4j.ConsoleAppender;

public class consandpatt {

static Logger logger = Logger.getLogger(consandpatt.class);

public static void main(String args[]) {

// Note, %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);

ConsoleAppender appender = new ConsoleAppender(layout);

logger.addAppender(appender);

logger.setLevel((Level) Level.DEBUG);

logger.debug("Here is some DEBUG");

logger.info("Here is some INFO");

logger.warn("Here is some WARN");

logger.error("Here is some ERROR");

logger.fatal("Here is some FATAL");

}

}

1Log4j經常與外部日誌檔案聯合使用,這樣很多可選項不必硬編碼在軟體中。使用外部配置檔案的優點就是修改可選項不需要重新編譯程式。唯一的缺點就是,由於用到io指令,速度稍微有些減慢。

2Log4j由三個重要的元件構成:日誌資訊的優先順序,日誌資訊的輸出目的地,日誌資訊的輸出格式。

3、日誌資訊的優先順序從高到低有ERRORWARNINFODEBUG,分別用來指定這條日誌資訊的重要程度;日誌資訊的輸出目的地指定了日誌將列印到控制檯還是檔案中;而輸出格式則控制了日誌資訊的顯示內容。

log4j可以使用3種配置器來初始化:

BasicConfigurator,DOMConfigurator,PropertyConfigurator

對於一般的javaproject可以不使用上面的語句初始化log4jlog4j會自動在classpath下,找到配置檔案並初始化。如果log4j不能自動初始化配置檔案,那麼就需要用上面的方法進行初始化。

注意:初始化配置檔案,最好只在系統啟動的時候執行一次,如果執行多次,一是浪費資源,二就是對於老版本的log4j,使用DailyRollingFileAppender時,可能會出現問題。

有兩個方法可以用來指定外部配置檔案:文字檔案或者XML檔案。

AXML方式:

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

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

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

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

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

</appender>

<root>

<priority value ="debug" />

<appender-ref ref="ConsoleAppender"/>

</root>

</log4j:configuration>

檔案以標準的XML宣告作為開始,後面跟著指出DTD(文件型別定義)的DOCTYPE宣告,它定義了XML檔案的結構,例如,什麼元素可以嵌入在其他元素中等等。接著看看封裝所有元素的 log4j:configuration元素,它在DOCTYPE宣告中被指定為根元素。嵌入在根元素中有兩個結構:

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

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

</appender>

<