log4j+commons-logging結合使用

1.參考文獻:

  1. Apache Commons-logging使用實例php

  2. Apache Log4j配置說明html

  3. log4j.properties配置詳解java

  4. commons-logging結合Log4j的問題c++

  5. Properties文件相關web

  6. Apache通用日誌工具commons-logging和Log4j使用總結apache

2.Commons-Loggin簡介

Apache針對不一樣的語言平臺爲作了一系列日誌工具包,可應用於java、.net、php、c++,這些日誌包都是免費的,使用很是方便,能夠極大提升編程效率。而且,Apache爲了讓衆多的日誌工具備一個相同操做方式,還實現作了一個通用日誌工具包:commons-logging,也稱Jakarta Commons Logging (JCL)。commons-logging是爲那些須要創建在不一樣環境下使用不一樣日誌架構的組件或庫的開發者建立的,其中包括Apache Log4j以及Java log的日誌架構。把日誌信息commons-logging的Log接口,並由commons-logging在運行時決定使用哪一種日誌架構。如今,Apache通用日誌工具commons-logging和Log4j已經成爲Java日誌的標準工具。編程

3.快速入門

JCL有兩個基本的抽象類:Log(基本記錄器)和LogFactory(負責建立Log實例)。當commons-logging.jar被加入到CLASSPATH(一般將commons-logging.jar放在web project下的WebContent\WEB-INF\lib目錄中)以後,它會合理地猜想你想用的日誌工具,而後進行自我設置,用戶根本不須要作任何設置。默認的LogFactory是按照下列的步驟去發現並決定那個日誌工具將被使用的(按照順序,尋找過程會在找到第一個工具時停止,這個順序很是重要):架構

  1. 尋找當前factory中名叫org.apache.commons.logging.Log配置屬性的值app

  2. 尋找系統中屬性中名叫org.apache.commons.logging.Log的值工具

  3. 若是應用程序的classpath中有log4j,則使用相關的包裝(wrapper)類(Log4JLogger)

  4. 若是應用程序運行在jdk1.4的系統中,使用相關的包裝類(Jdk14Logger)

  5. 使用簡易日誌包裝類(SimpleLog)

上述的加載順序能夠經過commons-logging中LogSource.java的源代碼能夠看出,源代碼以下,具體能夠參考註釋:

package log.sample;
public class ca {
     static {
            // Is Log4J Available?用戶Log4J是否可用
            try {
                /**
                 * 經過Class.forName("org.apache.log4j.Logger"))來查找Log4J,
                 * 只有將log4j.jar添加到classpath之後才能找到,
                 * 這也是爲何默認狀況下只要將log4j.jar文件放在lib文件夾中
                 * 而不須要在common-logging.properties配置文件中進行配置就能自動使用log4j的緣由
                 */
                if (null != Class.forName("org.apache.log4j.Logger")) {
                    log4jIsAvailable = true;
                } else {
                    log4jIsAvailable = false;
                }
            } catch (Throwable t) {
                log4jIsAvailable = false;
            }
            // Is JDK 1.4 Logging Available?原來同上面的Log4J
            try {
                if ((null != Class.forName("java.util.logging.Logger")) &&
                    (null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"))) {
                    jdk14IsAvailable = true;
                } else {
                    jdk14IsAvailable = false;
                }
            } catch (Throwable t) {
                jdk14IsAvailable = false;
            }
            // Set the default Log implementation,經過common-logging.properties配置文件來決定日誌實現方式
            String name = null;
            try {
                name = System.getProperty("org.apache.commons.logging.log");
                if (name == null) {
                    name = System.getProperty("org.apache.commons.logging.Log");
                }
            } catch (Throwable t) {
            }
            if (name != null) {
                try {
                    setLogImplementation(name);
                } catch (Throwable t) {
                    try {
                        setLogImplementation
                                ("org.apache.commons.logging.impl.NoOpLog");
                    } catch (Throwable u) {
                        ;
                    }
                }
            } else {
                try {
                    if (log4jIsAvailable) {//若是log4j可用,默認優先使用Log4JLogger
                        setLogImplementation
                                ("org.apache.commons.logging.impl.Log4JLogger");
                    } else if (jdk14IsAvailable) {//第二優先使用Jdk14Logger
                        setLogImplementation
                                ("org.apache.commons.logging.impl.Jdk14Logger");
                    } else {//最後使用commoms-logging中的自帶的實現,但它不進行任何操做
                        setLogImplementation
                                ("org.apache.commons.logging.impl.NoOpLog");
                    }
                } catch (Throwable t) {
                    try {
                        setLogImplementation
                                ("org.apache.commons.logging.impl.NoOpLog");
                    } catch (Throwable u) {
                        ;
                    }
                }
            }
        }
}

org.apache.commons.logging.Log的具體實現大體有以下幾類:

  • -org.apache.commons.logging.impl.Jdk14Logger:使用JDK1.4。

  • -org.apache.commons.logging.impl.Log4JLogger:使用Log4J。

  • -org.apache.commons.logging.impl.Log4JCategoryLog:使用Log4J,該實現已被棄用,推薦使用Log4JLogger

  • -org.apache.commons.logging.impl.LogKitLogger:使用 avalon-Logkit。

  • -org.apache.commons.logging.impl.SimpleLog:common-logging自帶日誌實現類。它實現了Log接口,把日誌消息都輸出到系統錯誤流System.err 中。 

  • -org.apache.commons.logging.impl.NoOpLog:common-logging自帶日誌實現類。它實現了Log接口。 其輸出日誌的方法中不進行任何操做。

4.信息級別

  確保日誌信息在內容上和反應問題的嚴重程度上的恰當,是很是重要的。log4j主要有以下的信息級別:

  1. fatal:很是嚴重的錯誤,致使系統停止。指望這類信息能當即顯示在狀態控制檯上。

  2. error:其它運行期錯誤或不是預期的條件。指望這類信息能當即顯示在狀態控制檯上。

  3. warn:使用了不同意使用的API、很是拙劣使用API, '幾乎就是'錯誤, 其它運行時不合須要和不合預期的狀態但還不必稱爲 "錯誤"。指望這類信息能當即顯示在狀態控制檯上。

  4. info:運行時產生的有意義的事件。指望這類信息能當即顯示在狀態控制檯上。

  5. debug:系統流程中的細節信息。指望這類信息僅被寫入log文件中。

  6. trace:更加細節的信息。指望這類信息僅被寫入log文件中。

  一般狀況下,咱們但願將info級別以上的日誌信息輸出到控制檯,而debug級別以上的信息寫入到log文件中,而error信息寫入到一個單獨的文件中去,下面咱們的實例將會實現這樣的功能。

4.使用commons-logging結合log4j進行開發

4.1. 下載必要的jar包

   下載commons-logging.jar和log4j.jar包,而後把它們放到工程的lib目錄下,引入工程中。

4.2. 編寫common-logging.properties配置文件

  在屬性文件common-logging.properties中設置實現接口的類。以下(這裏設置Log4j爲所使用的日誌包):

org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

  這裏須要注意的是,若是common-logging.properties配置使用Log4JCategoryLog,會報錯誤,具體見參考文獻4。配置以下:

org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JCategoryLog

  在第三節中咱們講到如何在項目中引入了log4j.jar,那麼common-logging默認會使用log4j最爲日誌實現方式。

4.3.log4j.properties配置實現日誌的不一樣輸出形式(實測log4j.properties須要在src目錄下可默認加載配置文件)

前面咱們講到要求在控制檯輸入info級別的日誌,而後有一個log.log記錄debug級別以上的日誌,一個error.log記錄error級別以上的日誌。log4j.properties配置以下:

### set log levels ###
log4j.rootLogger = debug , stdout , D , E
### 輸出到控制檯 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
## 輸出INFO級別以上的日誌
log4j.appender.stdout.Threshold = INFO
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
### 輸出到日誌文件 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = D:/logs/log.log
log4j.appender.D.Append = true
## 輸出DEBUG級別以上的日誌
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 保存異常信息到單獨文件 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
## 異常日誌文件名
log4j.appender.E.File = D:/logs/error.log 
log4j.appender.E.Append = true
 ## 只輸出ERROR級別以上的日誌!!!
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

4.4.單獨使用log4j實例:Log4jTest.java

package log.sample;
import org.apache.log4j.Logger;
public class Log4jTest {
    private static Logger log = Logger.getLogger(Log4jTest.class);
    public void log() {
        log.debug("Debug info.");
        log.info("Info info");
        log.warn("Warn info");
        log.error("Error info");
        log.fatal("Fatal info");
    }
    public static void main(String[] args) {
        Log4jTest test = new Log4jTest();
        test.log();
    }
}

4.5.common-logging結合log4j實例:JCLTest.java

package log.sample;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class JCLTest {
    private static Log log = LogFactory.getLog(JCLTest.class);
    public void log(){
       log.debug("Debug info.");
       log.info("Info info");
       log.warn("Warn info");
       log.error("Error info");
       log.fatal("Fatal info");
    }
    public static void main(String[] args) {
       JCLTest test = new JCLTest();
       test.log();
    }
}

說明:4.4和4.5的輸出結果是同樣的。

相關文章
相關標籤/搜索