log4j的基本使用和參數設定


1、簡介

apache的一個開放源代碼項目。

精確控制日志的輸出,包括輸出的格式,輸出的目的地,輸出的過濾(不同級別日志的輸出)等。

配置簡單,不需要在代碼中配置環境,支持兩種配置文件格式,XML和Java特性文件(鍵=值,常見的.properties),常用后者如 log4j.properties




2、核心組件

Log4j中有三個主要的組件,它們分別是 Logger、Appender和Layout。

Log4j 允許開發人員定義多個Logger,每個Logger擁有自己的名字,Logger之間通過名字來表明隸屬關系。有一個Logger稱為Root,它永遠存在,且不能通過名字檢索或引用,可以通過Logger.getRootLogger()方法獲得,其它Logger通過 Logger.getLogger(String name)方法。

Appender則是用來指明將所有的log信息存放到什么地方,Log4j中支持多種appender,如 console、files、GUI components、NT Event Loggers等,一個Logger可以擁有多個Appender,也就是你既可以將Log信息輸出到屏幕,同時存儲到一個文件中。

Layout的作用是控制Log信息的輸出方式,也就是格式化輸出的信息。

Log4j中將要輸出的Log信息定義了5種級別,依次為DEBUG、INFO、WARN、ERROR和FATAL,當輸出時,只 有級別高過配置中規定的級別的信息才能真正的輸出,這樣就很方便的來配置不同情況下要輸出的內容,而不需要更改代碼。

2.1 Logger

公共類Logger, 負責處理日志記錄的大部分操作。

日志記錄器(Logger)將 只輸出那些級別高於或等於它的級別的信息。如果 沒有設置日志記錄器(Logger)的級別,那么它將會繼承最近的祖先的級別

例如在包com.foo.bar中創建一個日志記錄器(Logger)並且沒有設置級別,那它將會繼承在包com.foo中創建的日志記錄器(Logger)的級別。如果在com.foo中沒有創建日志記錄器(Logger)的話,那么在com.foo.bar中創建的日志記錄器(Logger)將繼承root日志記錄器(Logger)的級別。

可以為日志指定不同的級別,級別 從低到高支持以下幾種:
ALL     打開所有日志
DEBUG     細粒度信息事件,對調試應用程序是非常有幫助的    
INFO     粗粒度信息事件,突出強調應用程序的運行過程    
WARN     可能出現潛在錯誤的情形    
ERROR     雖然發生錯誤事件,但仍然不影響系統的繼續運行    
FATAL     指出每個嚴重的錯誤事件將會導致應用程序的退出
OFF     關閉所有日志

比較常用的Logger創建方法,就是根據類名實例化一個靜態的全局日志記錄器:
static Logger logger = Logger.getLogger(test.class);  

日志記錄器都可以用下面方法設置級別: 
logger.setLevel((Level)Level.WARN); 

當然,這是代碼設置的方式。我們剛才提到過,可以使用配置文件的方式進行配置,那么我們后面會提到。

2.2 Appender

公共接口Appender,負責控制日志記錄操作的輸出。

下面是API中提供的輸出方式(常用的見紅字),也可以自己實現Appender接口,創建以自己的方式進行日志輸出的Appender:
ConsoleAppender 使用用戶指定的布局(layout)輸出日志事件到System.out或者 System.err。默認的目標是System.out
FileAppender 把日志事件寫入一個文件
DailyRollingFileAppender 擴展FileAppender,因此多個日志文件可以以一個用戶選定的頻率進行循環日志記錄
RollingFileAppender 擴展FileAppender,備份容量達到一定大小的日志文件
WriterAppender 根據用戶的選擇把日志事件寫入到Writer或者OutputStream
SMTPAppender 當特定的日志事件發生時,一般是指發生錯誤或者重大錯誤時,發送一封郵件
SocketAppender 給遠程日志服務器(通常是網絡套接字節點)發送日志事件(LoggingEvent)對象
SocketHubAppender 給遠程日志服務器群組(通常是網絡套接字節點)發送日志事件(LoggingEvent)對象
SyslogAppender 給遠程異步日志記錄的后台精靈程序(daemon)發送消息
TelnetAppender 一個專用於向只讀網絡套接字發送消息的log4j appender

2.3 Layout

公共抽象類,負責格式化Appender的輸出。

Appender必須使用一個與之相關聯的 Layout,這樣它才能知道怎樣格式化它的輸出。

log4j常見的三種類型的Layout:
HTMLLayout 格式化日志輸出為HTML表格
PatternLayout 根據指定的轉換模式格式化日志輸出,或者如果沒有指定任何轉換模式,就使用默認的轉換模式
SimpleLayout 以一種非常簡單的方式格式化日志輸出,它打印級別 Level,然后跟着一個破折號“-“ ,最后才是日志消息
 


3、配置文件的設置

3.1 根 Logger

log4j.rootLogger = [ level ] , appenderName, appenderName, ... 
  • level  優先級,ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF 
  • appenderName  指定日志信息輸出到哪個地方。您可以同時指定多個輸出目的地

3.2 某個包或類的 Logger

之前我們提到過,日志記錄器(Logger)將只輸出那些級別高於或等於它的級別的信息,如果沒有設置日志記錄器(Logger)的級別,那么它將會繼承最近的祖先的級別。

假如你在配置文件中沒有針對有些包或者類進行單獨的級別設置,那么它會直接繼承最近祖先的級別,依次往上如果都沒有那么最終會繼承 RootLogger 根日志記錄器的級別。

配置語法如下:
log4j.logger.xxx.xxx.xxx=level

這里的xxx.xxx可以是包,比如com.greejoy;也可以是具體的類,比如com.greejoy.action.LoginAction

示例:
log4j.rootLogger=WARN,A
log4j.logger.com.opensymphony.xwork2.interceptor.TimerInterceptor=DEBUG

log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern==%-d{yyyy-MM-dd HH:mm:ss} [%p]-[%c] %m%n

假如現在有類indiv.dulk.wechat.InitWechatServlet,此處沒有配置level,默認繼承到了根Logger的level,即WARN。此時如果類中有log輸出語句如下:
log.info("微信accessToken刷新 " + WechatAPI.getAccessToken());

最終在控制台是不會輸出的,因為INFO的等級比WARN等級低,不會輸出。如果我們改下配置文件:
log4j.rootLogger=WARN,A
log4j.logger.indiv.dulk=DEBUG
log4j.logger.com.opensymphony.xwork2.interceptor.TimerInterceptor=DEBUG

log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern==%-d{yyyy-MM-dd HH:mm:ss} [%p]-[%c] %m%n

定義了indiv.dulk包level為DEBUG,indiv.dulk.wechat.InitWechatServlet沒有單獨設置level,往上找最終繼承indiv.dulk的level,即DEBUG,此時剛才的log輸出語句就會輸出在控制台上。因為INFO的等級比DEBUG的等級高。

回顧下等級大小:
ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF

需要注意的是單獨配置的類或包,都是受全局管理的,意思就是說, 除了滿足單獨配置Logger要求的日志會輸出,同時滿足根配置Logger的日志也會輸出

這就給我們帶來了麻煩,假如都設置在控制台輸出,只是單獨配置的Logger格式設定不一樣,那么在控制台你會看到內容相仿的兩條日志輸出。

也就是說,假如我們有如下配置文件,最終會出現如下的情況:
log4j.rootLogger=WARN,A
log4j.logger.indiv.dulk.wechat=DEBUG,wechat

log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p]-[%c] %m%n

log4j.appender.wechat=org.apache.log4j.ConsoleAppender
log4j.appender.wechat.layout=org.apache.log4j.PatternLayout
log4j.appender.wechat.layout.ConversionPattern=[%p]-[%c] %m%n
 
這顯然不是我們想要的,所以需要改下配置, 讓指定的包不受全局管理
log4j.rootLogger=WARN,A
log4j.logger.indiv.dulk.wechat=DEBUG,wechat

#不受全局管理
log4j.additivity.indiv.dulk.wechat=false

log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p]-[%c] %m%n

log4j.appender.wechat=org.apache.log4j.ConsoleAppender
log4j.appender.wechat.layout=org.apache.log4j.PatternLayout
log4j.appender.wechat.layout.ConversionPattern=[%p]-[%c] %m%n
 
這樣,就得到了我們想要的結果。

3.3 日志輸出地址 Appender

log4j.appender.appenderName = fully.qualified.name.of.appender.class  (有資格的appender類的全名)
log4j.appender.appenderName.option1 = value1  
log4j.appender.appenderName.option = valueN 

Log4j提供的appender有以下幾種:
  • org.apache.log4j.ConsoleAppender(控制台)
  • org.apache.log4j.FileAppender(文件)
  • org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件)
  • org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件)
  • org.apache.log4j.WriterAppender(將日志信息以流格式發送到任意指定的地方)

3.4 日志輸出格式 Layout

log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class  
log4j.appender.appenderName.layout.option1 = value1  
log4j.appender.appenderName.layout.option = valueN  

Log4j提供的layout有以下幾種:
  • org.apache.log4j.HTMLLayout(以HTML表格形式布局)
  • org.apache.log4j.PatternLayout(可以靈活地指定布局模式)
  • org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串)
  • org.apache.log4j.TTCCLayout(包含日志產生的時間、線程、類別等等信息)

打印的參數設置示例:
log4j.appender.log.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t ] %m%n  
  • %m   輸出代碼中指定的消息
  • %p   輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL
  • %r   輸出自應用啟動到輸出該log信息耗費的毫秒數
  • %c   輸出所屬的類目,通常就是所在類的全名
  • %t   輸出產生該日志事件的線程名
  • %n   輸出一個回車換行符,Windows平台為“/r/n”,Unix平台為“/n”
  • %d   輸出日志時間點的日期或時間。默認格式為ISO8601,也可以在其后指定格式。比如:%d{yyy MMM dd HH:mm:ss , SSS},輸出類似:2002年10月18日 22:10:28, 921
  • %l   輸出日志事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數
 

3.5 配置示例

示例1:
### 設置###
log4j.rootLogger = debug,stdout,D,E

### 輸出信息到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 輸出DEBUG 級別以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
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

### 輸出ERROR 級別以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
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

注意:例如 log4j.appender.log.Threshold = ERROR 表示在總控開關的前提,覺得精確,只有達到這個級別的日志才被記錄到這個文件中

示例2:
#指定目錄下包下的日志信息都存放到數據庫 
log4j.logger.database=DEBUG,oracledb 

log4j.appender.oracledb=org.apache.log4j.jdbc.JDBCAppender 
log4j.appender.oracledb.Driver=oracle.jdbc.driver.OracleDriver 
log4j.appender.oracledb.URL=jdbc:oracle:thin:@192.168.20.92:1521:chshsid(切忌此處為sid而不是數據庫名) 
log4j.appender.oracledb.user=scott 
log4j.appender.oracledb.password=tiger 
#log4j.appender.encoding=utf-8 
log4j.appender.oracledb.sql=INSERT INTO enter_ora_log4j VALUES ('%d{yyyy-MM-dd HH:mm:ss}', '%t', '%p', '%l', '%m') 
log4j.appender.oracledb.layout=org.apache.log4j.PatternLayout 

示例3:
#指定目錄下的java類的日志信息都存放到該目錄下 
log4j.logger.com.cuigq.TestError=DEBUG,R2 

log4j.appender.R2=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.R2.File=d:/loginfo/html.html 
#log4j.appender.R2.MaxFileSize=500KB 
#log4j.appender.R2.MaxBackupIndex=1 
log4j.appender.R2.layout=org.apache.log4j.HTMLLayout 
#log4j.appender.R2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n 

示例4:
#指定目錄下包下的日志信息都存放到該目錄下 
log4j.logger.cn.com.cuigq.Theard=DEBUG,R1 

log4j.appender.R1=org.apache.log4j.RollingFileAppender 
log4j.appender.R1.File=d:/loginfo/iamSystem1.log 
log4j.appender.R1.MaxFileSize=500KB 
log4j.appender.R1.MaxBackupIndex=1 
log4j.appender.R1.layout=org.apache.log4j.PatternLayout 
log4j.appender.R1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n 



4、基本使用 和 Web下的使用

4.1 基本步驟流程

4.1.1 得到日志記錄器Logger

使用Log4j,第一步就是獲取日志記錄器,這個記錄器將負責控制日志信息。其語法為:
public static Logger getLogger( String name)

通過指定的名字獲得記錄器,如果必要的話,則為這個名字創建一個新的記錄器。Name一般取本類的名字,比如:

static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName ())

4.1.2 讀取配置文件

當獲得了日志記錄器之后,第二步將配置Log4j環境,其語法為:
BasicConfigurator.configure (): 自動快速地使用缺省Log4j環境
PropertyConfigurator.configure (String configFilename) :讀取使用Java的特性文件編寫的配置文件
DOMConfigurator.configure ( String filename ) :讀取XML形式的配置文件

4.1.3 插入記錄信息

當上兩個必要步驟執行完畢,您就可以輕松地使用不同優先級別的日志記錄語句插入到您想記錄日志的任何地方,其語法如下:
Logger.debug ( Object message ) ;  
Logger.info ( Object message ) ;  
Logger.warn ( Object message ) ;  
Logger.error ( Object message ) ;

4.2 入門使用

不詳細展開描述,詳見參考:

4.3 Web使用

web應用的log4j使用基本上都采用:新建一個servlet,這個servlet在init函數中為log4j執行配置,一般就是讀入配置文件。

1、在web.xml中配置servlet,同時設定load-on-startup為0。配置文件位置在web.xml中配置一個param即可,路徑一般是相對於web的root目錄。

<servlet>
    <servlet-name>InitLog4jServlet</servlet-name>
    <servlet-class>indiv.dulk.wechat.init.InitLog4jServlet</servlet-class>
    <init-param>
        <param-name>propertiesLocation</param-name>
        <param-value>/WEB-INF/classes/log4j.properties</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>

2、這個servlet配置log4j就是讀出配置文件,然后調用configure函數。這里有兩個問題:一、需要知道文件在哪里;二、需要正確的文件類型(文件類型一般有兩種,一個是Java的property文件,另一種是xml文件)

public class InitLog4jServlet extends HttpServlet{

    /**
     * Servlet初始化的執行方法,用以加載log4j配置文件
     *
     * @throws ServletException
     */
    @Override
    public void init() throws ServletException {
        System.out.println("*** Log4jInitServlet正在初始化log4j日志設置信息 ***");
        String log4jLocation = getInitParameter("propertiesLocation");

        if (log4jLocation == null) {
            System.err.println("*** 沒有找到log4j的properties配置文件,使用缺省log4j環境初始化 ***");
            BasicConfigurator.configure();
        } else {
            String webAppPath = getServletContext().getRealPath("/");
            String log4jRealLocation = webAppPath + log4jLocation;
            File log4jFile = new File(log4jRealLocation);
            if (log4jFile.exists()) {
                System.out.println("*** 使用" + log4jRealLocation + "進行log4j環境初始化 ***");
                PropertyConfigurator.configure(log4jRealLocation);
            } else {
                System.err.println("*** " + log4jRealLocation + "文件未找到,使用缺省log4j環境初始化 ***");
                BasicConfigurator.configure();
            }
        }
    }
}

3、完成設置后在其他類中就可以獲取Logger來進行日志打印
public class InitWechatServlet extends HttpServlet{
    private static Logger log = Logger.getLogger(InitWechatServlet.class);

    /**
     * 刷新的間隔時間(單位:毫秒),默認為1h,可以在web.xml自定義配置
     */
    private long period = 3600000;

    /**
     * 時間間隔時需要執行的任務內容
     */
    private TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            //獲取最新的access_token並設定到WeChatAPI類中的靜態屬性中去
            WechatAPI.setAccessToken(WechatUtil.getNewAccessToken());
            log.info("微信accessToken刷新 " + WechatAPI.getAccessToken());
        }
    };
}



5、參考鏈接




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM