Log4j徹底教程

本文爲轉載學習java

原文連接:http://hi.baidu.com/boyyf/item/cec95635dbd50e169dc65e26mysql


認識Log4j程序員

    在你開發項目的過程過,是否時常使用System.out.println()?考慮是否須要記錄程序運行過程當中出現的錯誤?是否須要記錄用戶的行爲?Apache Log4j項目將幫助咱們逃脫硬編碼寫輸出的痛苦,獨立的日誌輸出程序將使得程序員能夠便利的分級輸出日誌信息。更爲重要的是,Log4j靈活的配置功能使得咱們徹底不須要修改程序,而僅僅修改配置文件便可完全改變日誌輸出的格式、目標等屬性,而且Log4j還爲咱們提供了各類便利的日誌目的地,如「一天一個日誌文件」、套接字、數據庫、電子郵箱,甚至Unix的守護進程和Nt的事件服務。web

Log4j的三大組建sql

    Log4j有三個主要的組件:LoggersAppendersLayouts,這裏可簡單理解爲日誌記錄器日誌要輸出的地方日誌以何種形式輸出數據庫

Loggersapache

    組件在此係統中被分爲五個級別:DEBUG、INFO、WARN、ERROR和FATAL。這五個級別是有順序的,DEBUG < INFO < WARN < ERROR < FATAL,明白這一點很重要,這裏Log4j有一個規則:假設Loggers級別爲P,若是在Loggers中發生了一個級別Q比P高的日誌輸出事件,則會輸出,不然屏蔽掉。服務器

Appendersapp

    禁用與使用日誌請求只是Log4j其中的一個小小的地方,Log4j日誌系統容許把日誌輸出到不一樣的地方,如控制檯(Console)、文件(Files)、根據天數或者文件大小產生新的文件、以流的形式發送到其它地方等等。webapp

常見的Appender有:

      org.apache.log4j.ConsoleAppender(控制檯)

      org.apache.log4j.FileAppender(文件)

      org.apache.log4j.DailyRollingFileAppender(天天產生一個日誌文件),

      org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件)

      org.apache.log4j.WriterAppender(將日誌信息以流格式發送到任意指定的地方)

      org.apache.log4j.net.SMTPAppender(發送到郵箱)

      org.apache.log4j.jdbc.JDBCAppender(儲存到數據庫)

Layouts

    有時用戶但願根據本身的喜愛格式化本身的日誌輸出。Log4j能夠在Appenders的後面附加Layouts來完成這個功能。Layouts提供了四種日誌輸出樣式,如根據HTML樣式、自由指定樣式、包含日誌級別與信息的樣式和包含日誌時間、線程、類別等信息的樣式等等。

    常見的Layout有:

      org.apache.log4j.HTMLLayout(以HTML表格形式佈局),

      org.apache.log4j.PatternLayout(能夠靈活地指定佈局模式),

      org.apache.log4j.SimpleLayout(包含日誌信息的級別和信息字符串),

      org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等等信息)

Layouts有如下各經常使用的佔位符:

      %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 輸出日誌事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10)

Log4j的配置文件

    就本人看來,Log4j的便利之處就在於他的配置很是靈活的依賴於配置文件,能夠說在程序中只須要寫出在哪裏須要輸出日誌,日誌的級別,以及日誌的內容(這些一般都是固定不變的),而對於常須要改變的內容,好比日誌的格式、輸出到哪裏、怎麼儲存,甚至須要那些記錄器都只須要修改配置文件,而無需修改程序。但同時,這也決定了Log4j的使用核心就在配置文件的編寫。

    Log4j的配置文件能夠擁有兩種形式,一是properties文件,另外一種是xml文件,在此,只探討properties文件形式。

    首先請看一段配置文件(因爲properties並不支持中文,複製使用時請將中文註釋刪掉,或者下載源程序包中的配置文件):

#下面是Logger的定義

#定義根logger,其他全部的logger都是它的子logger

log4j.rootLogger=DEBUG

#logger的定義策略1:根據類名定義logger

#這裏就定義了兩個logger,一個名爲"com.ins1000.log4j.servlets",另外一個名

#爲"com.ins1000.log4j.servlets"。#logger的命名是具備層次性和隸屬性的,跟

#類的全名同樣,能夠說"com.ins1000.log4j.servlets.Test"這個logger是"com.

#ins1000.log4j.servlets"這個的子logger。

log4j.logger.com.ins1000.log4j.servlets=DEBUG,CONSOLE

log4j.logger.com.ins1000.log4j.servlets.Test=DEBUG,CONSOLE,DailyRollingFile


#logger的定義策略2:根據用途定義logger

#定義了一個名爲sa(system action)的logger,用於記錄程序的系統行爲,如程

#序啓動,初始化完成等

log4j.logger.sa=DEBUG,CONSOLE_SA

#定義了一個名爲us(users action)的logger,用於記錄用戶的通常行爲,如註冊

#發佈文章、發佈做品等

log4j.logger.ua=DEBUG,DailyRollingFile_UA

#定義了一個名爲e(Errors或Exceptions)的logger,用於記錄程序運行中出現的

#錯誤和異常

log4j.logger.e=DEBUG,CONSOLE_E,ROLLING_FILE_E

#以上各個定義的等號右方DEBUG的表示該logger的日誌輸出起始級別,接着後面是

#這個logger要輸#出的Appender,能夠有多個,用逗號隔開。

#其次,這裏提到了兩種logger的命名策略,雖然互聯網上幾乎全部的教程皆稱以類

#的全名是最簡單也最好的命名策略,由於其層次結構跟咱們的項目徹底一致,可是

#本人處於應用須要,仍是提出了另外一種根據用途命名的策略,即把全部須要記錄的

#日誌信息分爲3中(系統行爲、用戶行爲、異常),分別輸出到不一樣的地方。


#下面定義各個層次是否繼承父輩的屬性(初始級別和Appenders)

log4j.additivity.com.ins1000.log4j=true

log4j.additivity.com.ins1000.log4j.Test=true

log4j.additivity.e=false

log4j.additivity.sa=false

log4j.additivity.ua=false

log4j.addivity.org.apache=true

#下面定義各個Appenders

###################################

# Console Appender

###################################

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender

log4j.appender.Threshold=DEBUG

log4j.appender.CONSOLE.Target=System.out

log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout

log4j.appender.CONSOLE.layout.ConversionPattern=[ins1000]%p: %m [%c]%n

###################################

# Console Appender For SystemAction

###################################

log4j.appender.CONSOLE_SA=org.apache.log4j.ConsoleAppender

log4j.appender.Threshold=DEBUG

log4j.appender.CONSOLE_SA.Target=System.out

log4j.appender.CONSOLE_SA.layout=org.apache.log4j.PatternLayout

log4j.appender.CONSOLE_SA.layout.ConversionPattern=[ins1000]\u7cfb\u7edf\u4fe1\u606f: %m%n

###################################

# Console Appender For Errors and Exceptions

###################################

log4j.appender.CONSOLE_E=org.apache.log4j.ConsoleAppender

log4j.appender.Threshold=DEBUG

log4j.appender.CONSOLE_E.Target=System.out

log4j.appender.CONSOLE_E.layout=org.apache.log4j.PatternLayout

log4j.appender.CONSOLE_E.layout.ConversionPattern=[ins1000]\u7cfb\u7edf\u5f02\u5e38: %m [%l]%n

#上面的Appender都是輸出到控制檯,多個項目的信息均可能被輸出到控制檯,因此

#通常都會加上項目名稱,如[ins1000]

########################

# Rolling File For Errors and Exceptions

########################

log4j.appender.ROLLING_FILE_E=org.apache.log4j.RollingFileAppender

log4j.appender.ROLLING_FILE_E.Threshold=ERROR

log4j.appender.ROLLING_FILE_E.File=${webappHome}/WEB-INF/log/errors/ins1000.log

#日誌文件的位置,其中${webappHome}表明環境變量中webappHome的值,Log4j會在

#初始化的死後自動期待,因此咱們能夠在Log4j初始化的時候將webapp的絕對路徑存

#入系統環境標量中,從而解決要手動修改日誌文件的問題

log4j.appender.ROLLING_FILE_E.Append=true

log4j.appender.ROLLING_FILE_E.MaxFileSize=5120KB

#一個文件的大小(當超過這個大小時,自動更換一個文件)

log4j.appender.ROLLING_FILE_E.MaxBackupIndex=1

log4j.appender.ROLLING_FILE_E.layout=org.apache.log4j.PatternLayout

log4j.appender.ROLLING_FILE_E.layout.ConversionPattern=%n%n[%d{yyyy-MM-dd HH:mm:ss}]%m [%l]%n

########################

# DailyRollingFile Appender

#######################

log4j.appender.DailyRollingFile=org.apache.log4j.DailyRollingFileAppender

log4j.appender.DailyRollingFile.DatePattern=yyyy-MM-dd'.log'

#日期戳後綴的格式

log4j.appender.DailyRollingFile.File=${webappHome}/WEB-INF/log/ins1000_

log4j.appender.DailyRollingFile.Append=true

log4j.appender.DailyRollingFile.layout=org.apache.log4j.PatternLayout

log4j.appender.DailyRollingFile.layout.ConversionPattern=[%-5p]%m [%c][%d{yyyy-MM-dd HH:mm:ss}]%n

#這個Appender的工做機理是先將日誌寫在/WEB-INF/log/ins1000_,待到了次日,自動將其改名爲

#ins1000_yyyy-MM-dd.log(其中yyyy-MM-dd是第一天的日期)。而後仍將次日的日誌先記錄在在

#ins1000_中,第三天再更名,以此類推。

########################

# DailyRollingFile Appender For Users Action

#######################

log4j.appender.DailyRollingFile_UA=org.apache.log4j.DailyRollingFileAppender

log4j.appender.DailyRollingFile_UA.DatePattern=yyyy-MM-dd'.log'

log4j.appender.DailyRollingFile_UA.File=${webappHome}/WEB-INF/log/users_action/ins1000_

#${webappHome} is an enviorment variable which is setted in Log4jInit

#it refers to the absolute path of the webapp

log4j.appender.DailyRollingFile_UA.Append=true

log4j.appender.DailyRollingFile_UA.layout=org.apache.log4j.PatternLayout

log4j.appender.DailyRollingFile_UA.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] %m%n

 


本人在網上到處尋覓,都沒有發現有對Log4j配置文件詳細介紹的文檔,若是你們English不錯的話,建議你們須要的時候能夠看看Log4j的API,應該有比較詳細的介紹。在此,本人只再介紹幾個經常使用的Appender的配置:

#####################

# File Appender

#####################

log4j.appender.FILE=org.apache.log4j.FileAppender

log4j.appender.FILE.File=file.log

log4j.appender.FILE.Append=false

log4j.appender.FILE.layout=org.apache.log4j.PatternLayout

log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

# Use this layout for LogFactor 5 analysis

########################

# Rolling File

########################

log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender

log4j.appender.ROLLING_FILE.Threshold=ERROR

log4j.appender.ROLLING_FILE.File=rolling.log

log4j.appender.ROLLING_FILE.Append=true

log4j.appender.ROLLING_FILE.MaxFileSize=10KB

log4j.appender.ROLLING_FILE.MaxBackupIndex=1

log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout

log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

####################

# Socket Appender

####################

log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender

log4j.appender.SOCKET.RemoteHost=localhost

log4j.appender.SOCKET.Port=5001

log4j.appender.SOCKET.LocationInfo=true

# Set up for Log Facter 5

log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout

log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n

########################

# Log Factor 5 Appender

########################

log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender

log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

########################

# SMTP Appender

#######################

log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender

log4j.appender.MAIL.Threshold=FATAL

log4j.appender.MAIL.BufferSize=10

log4j.appender.MAIL.SMTPHost=mail.hollycrm.com

log4j.appender.MAIL.Subject=Log4J Message

log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout

log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

########################

# JDBC Appender

#######################

log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender

log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test

log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver

log4j.appender.DATABASE.user=root

log4j.appender.DATABASE.password=

log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES (’[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n’)

log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout

log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender

log4j.appender.A1.File=SampleMessages.log4j

log4j.appender.A1.DatePattern=yyyyMMdd-HH’.log4j’

log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout  

 


自動初始化Log4j的Servlet

package com.ins1000.log4j.servlets;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.log4j.PropertyConfigurator;
public class Log4jInit extends HttpServlet {
    public void init(ServletConfig config) throws ServletException {
       //獲取本webapp所在的絕對路徑
       String prefix = config.getServletContext().getRealPath("/");
       //從web.xml讀取配置文件名
       String file = config.getInitParameter("Log4j-init-file");
       //對絕對路徑進行修飾
       String editedPrefix = prefix.substring(0,prefix.length()-1).replace("\\", "/");
       //將修飾後的絕對路徑存入系統環境變量
       System.setProperty("webappHome", editedPrefix);
       //執行Log4j的初始化
       PropertyConfigurator.configure(prefix + file);
    }
}

 爲了讓這個Servlet在Web服務器啓動時自動運行,還須要在項目的web.xml寫入:

<servlet>
    <description>Log4jInit</description>
    <display-name>Log4jInit</display-name>
    <servlet-name>Log4jInit</servlet-name>
    <servlet-class>com.ins1000.log4j.servlets.Log4jInit</servlet-class>
    <init-param> 
        <param-name>Log4j-init-file</param-name> 
        <param-value>WEB-INF/config/Log4j.properties</param-value> 
    </init-param> 
<load-on-startup>1</load-on-startup> 
</servlet>

在程序中使用Log4j

    在程序中使用Log4j,也就是要輸出日誌信息,通常分爲兩個步驟:首先得到一個Logger實例,而後調用此實例的debug()、info()、warn()、error()、fatal()等進行日誌的輸出。

    在上面的配置文件中,講到了兩種命名策略,一種是直接根據類的全名命名,另外一種是根據用途命名,那麼在實例化和使用的時候,就會稍微有些不一樣。

    根據類全命命名:

Logger logger = Logger.getLogger(this.getClass());

   //實例化一個logger,這裏this.getClass()將返回這個類的全名,若是這個名字在配置文件中定義了,則這個logger有其相關定義了的屬性,若是沒有,則看是否認義了其父類和時候設置了繼承。若是都沒有,則擁有rootLogger的屬性。

    //固然,logger的實例化能夠任意取名,好比Logger logger = Logger.getLogger("myLogger"),但一句相關的策略,將會更加便於管理。

logger.debug("按類取名測試:DEBUG");
    logger.info("按類取名測試:INFO");
    logger.warn("按類取名測試:WARN");
    logger.error("按類取名測試:ERROR");
    logger.error("按類取名測試:ERROR", Exception e);
    logger.fatal("按類取名測試:FATAL");

    //這就是條用logger的各類方法輸出日誌信息。其中logger.error("按類取名測試:ERROR", Exception e)也會將異常堆棧e的相關信息也輸出到相應的Appender

    根據用途命名:

Logger logger_sa = Logger.getLogger("sa");
    logger_sa.info("Log4j演示程序啓動成功");
    Logger logger_ua = Logger.getLogger("ua");
    logger_ua.info("用戶boyyf註冊成功");
    Logger logger_e = Logger.getLogger("e");
    try {
        Integer.parseInt("a");
    } catch (Exception e) {
        logger_e.error("出現數值轉換異常",e);
        //這樣會在日誌中記錄異常堆棧
    }
相關文章
相關標籤/搜索