JAVA - 優雅的記錄日誌(log4j實戰篇)

 

 寫在前面

項目開發中,記錄錯誤日誌有如下好處:java

  1. 方便調試
  2. 便於發現系統運行過程當中的錯誤
  3. 存儲業務數據,便於後期分析

在java中,記錄日誌有不少種方式:程序員

  • 本身實現

    本身寫類,將日誌數據,以io操做方式,寫數據到文本文件、數據庫中。數據庫

  • 使用log4j

    log4j能夠將日誌輸出到console窗口、文本文件、數據庫等,功能強大!apache

  • 使用slfj

    slfj也是一個很強大的功能,slfj旨在一統天下,提供了logging.jar 和 log4j的接口,能夠經過slfj來調用log4j,也能夠調用jdk的logging。windows

  • 使用jdk自帶的logging.jar中的方法

log4j須要導入的包

通常使用log4j須要與logging配合使用:多線程

  • commons-logging-1.0.4.jar
  • log4j-1.2.15.jar

添加配置文件

在src下,把log4j的配置文件添加進去log4j.properties。app

創建類文件+主函數

修改配置文件,將日誌輸出到console

log4J配置文件爲:

### 設置級別和目的地(這裏多個目的地) ###
log4j.rootLogger = DEBUG,CONSOLE
### 這裏的me是包,也就是在這個包記錄日誌時,是隻記錄debug及以上級別的日誌
log4j.logger.me=DEBUG
### 輸出到控制檯 ###
log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target = System.out
log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n 

main主函數調用:

import org.apache.log4j.Logger;

public class Log4jTest {
   public static Logger logger1 = Logger.getLogger(Log4jTest.class);
   public static void main(String[] args) {
       //logger1
       logger1.trace("我是logger1,trace");
       logger1.debug("我是logger1,debug");
       logger1.info("我是logger1,info");
       logger1.warn("我是logger1,warn");
       logger1.error("我是logger1,error");
       logger1.fatal("我是logger1,fatal");
   }
}

能夠看到console中輸出內容:

16:51:16,575 DEBUG Log4jTest:15 [main:0]- 我是logger1,debug
16:51:16,578  INFO Log4jTest:16 [main:3]- 我是logger1,info
16:51:16,578  WARN Log4jTest:17 [main:3]- 我是logger1,warn
16:51:16,578 ERROR Log4jTest:18 [main:3]- 我是logger1,error
16:51:16,578 FATAL Log4jTest:19 [main:3]- 我是logger1,fatal

設定輸出的格式

在標題4中,看到console的輸出內容,是按必定格式輸出,格式的配置仍是來自於配置文件log4j.propertieseclipse

日誌輸出格式,所用到的參數以下,按需添加:

%p: 輸出日誌信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也能夠在其後指定格式,好比:%d{yyy MMM dd HH:mm:ss,SSS},輸出相似:2002年10月18日 221028921
%r: 輸出自應用啓動到輸出該log信息耗費的毫秒數
%c: 輸出日誌信息所屬的類目,一般就是所在類的全名
%t: 輸出產生該日誌事件的線程名
%l: 輸出日誌事件的發生位置,至關於%C.%M(%F:%L)的組合,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10)
%x: 輸出和當前線程相關聯的NDC(嵌套診斷環境),尤爲用到像java servlets這樣的多客戶多線程的應用中。
%%: 輸出一個」%」字符
%F: 輸出日誌消息產生時所在的文件名稱
%L: 輸出代碼中的行號
%m: 輸出代碼中指定的消息,產生的日誌具體信息
%n: 輸出一個回車換行符,Windows平臺爲」\r\n」,Unix平臺爲」\n」輸出日誌信息換行
能夠在%與模式字符之間加上修飾符來控制其最小寬度、最大寬度、和文本的對齊方式。如:
1)%20c:指定輸出category的名稱,最小的寬度是20,若是category的名稱小於20的話,默認的狀況下右對齊。
2)%-20c:指定輸出category的名稱,最小的寬度是20,若是category的名稱小於20的話,」-」號指定左對齊。
3)%.30c:指定輸出category的名稱,最大的寬度是30,若是category的名稱大於30的話,就會將左邊多出的字符截掉,但小於30的話也不會有空格。
4)%20.30c:若是category的名稱小於20就補空格,而且右對齊,若是其名稱長於30字符,就從左邊交遠銷出的字符截掉。

將日誌輸出到文本文件

log4j配置文件:

### 設置級別和目的地(這裏多個目的地) ###
log4j.rootLogger = trace,CONSOLE,zhangsanLog
log4j.logger.me=DEBUG

### 輸出到控制檯 ###
log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target = System.out
log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L [%t:%r]- %m%n

### 輸出到日誌文件 ###
log4j.appender.zhangsanLog = org.apache.log4j.DailyRollingFileAppender
log4j.appender.zhangsanLog.File =G\:\\var\\alldata\\zhenduan\\debug.log
#log4j.appender.zhangsanLog.File =/var/alldata/zhenduan/debug.log
log4j.appender.zhangsanLog.Append = true
## 只輸出DEBUG級別以上的日誌
log4j.appender.zhangsanLog.Threshold = DEBUG
#'.'yyyy-MM-dd: 天天產生一個新的文件
log4j.appender.zhangsanLog.DatePattern = '.'yyyy-MM-dd
log4j.appender.zhangsanLog.layout = org.apache.log4j.PatternLayout
log4j.appender.zhangsanLog.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] [%c{1}:%L] [%M] %m%n
log4j.additivity.zhangsanLog = false

main函數調用:

public static Logger logger1 = Logger.getLogger(Log4jTest.class);
public static void main(String[] args) {
   //logger1
   logger1.trace("我是logger1,trace");
   logger1.debug("我是logger1,debug");
   logger1.info("我是logger1,info");
   logger1.warn("我是logger1,warn");
   logger1.error("我是logger1,error");
   logger1.fatal("我是logger1,fatal");
} 

每一小時、天天、每半天生成一個文件

繼續使用標題6的配置,可是須要修改幾個地方。ide

標題6中,有這句話函數

log4j.appender.zhangsanLog = org.apache.log4j.DailyRollingFileAppender

這句話的意思:將日誌追加到文件,問題是多久生成一個文件?

須要修改

log4j.appender.zhangsanLog.DatePattern = '.'yyyy-MM-dd

DatePattern=’.’yyyy-ww:每週滾動一次文件,即每週產生一個新的文件。固然也能夠指定按月、周、天、時和分,即對應的格式以下:

  • ’.’yyyy-MM: 每個月
  • ’.’yyyy-ww: 每週
  • ’.’yyyy-MM-dd: 天天
  • ’.’yyyy-MM-dd-a: 天天兩次
  • ’.’yyyy-MM-dd-HH: 每小時
  • ’.’yyyy-MM-dd-HH-mm: 每分鐘

當文本文件爲3KB大時新建一個文件

一樣使用標題6的代碼:

log4j.appender.zhangsanLog = org.apache.log4j.RollingFileAppender
log4j.appender.zhangsanLog.File =G\:\\var\\alldata\\zhenduan\\debug.log
#log4j.appender.zhangsanLog.File =/var/alldata/zhenduan/debug.log
log4j.appender.zhangsanLog.Append = true
## 輸出DEBUG級別以上的日誌
log4j.appender.zhangsanLog.Threshold = DEBUG
#'.'yyyy-MM-dd: 天天產生一個新的文件
log4j.appender.zhangsanLog.MaxFileSize = 2KB
log4j.appender.zhangsanLog.MaxBackupIndex = 5
log4j.appender.zhangsanLog.layout = org.apache.log4j.PatternLayout
log4j.appender.zhangsanLog.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] [%c{1}:%L] [%M] %m%n
log4j.additivity.zhangsanLog = false

這裏修改的是

log4j.appender.zhangsanLog = org.apache.log4j.RollingFileAppender

MaxFileSize,當文件達到多大存儲空間時,就新建一個文件MaxBackupIndex.

Log4j的日誌級別

由低到高,能夠聯想到windows或unix的錯誤級別:

trace: 是追蹤,就是程序推動如下,你就能夠寫個trace輸出,因此trace應該會特別多,不過不要緊,咱們能夠設置最低日誌級別不讓他輸出。

debug: 調試麼,我通常就只用這個做爲最低級別,trace壓根不用。是在沒辦法就用eclipse或者idea的debug功能就行了麼。

info: 輸出一下你感興趣的或者重要的信息,這個用的最多了。

warn: 有些信息不是錯誤信息,可是也要給程序員的一些提示,相似於eclipse中代碼的驗證不是有error 和warn(不算錯誤可是也請注意,好比如下depressed的方法)。

error: 錯誤信息。用的也比較多。

fatal: 級別比較高了。重大錯誤,這種級別你能夠直接中止程序了,是不該該出現的錯誤麼!不用那麼緊張,其實就是一個程度的問題。

log4j的配置說明

Log4j支持兩種配置文件格式,一種是XML格式的文件,一種是properties格式的文件。通常我經常使用的是properties文件

一、log4j.rootLogger = [ level ] , appenderName, appenderName, …

level:是log4j的日誌級別,優先級從高到低分別是ERROR、WARN、INFO、DEBUG。

appenderName:就是指定日誌信息輸出到哪一個地方。可同時指定多個輸出目的地。

二、 配置日誌信息輸出目的地Appender,其語法爲:

log4j.appender.appenderName = fully.qualified.name.of.appender.class

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(將日誌信息以流格式發送到任意指定的地方)

三、設置好appender後,針對appender的配置

也就是設置好要輸出到什麼地方後,其它配置選項

(1).ConsoleAppender選項

Threshold=WARN:指定日誌消息的輸出最低層次。

ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。

Target=System.err:默認狀況下是:System.out,指定輸出控制檯

(2).FileAppender 選項

Threshold=WARN:指定日誌消息的輸出最低層次。

ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。

File=mylog.txt:指定消息輸出到mylog.txt文件。

Append=false:默認值是true,即將消息增長到指定文件中,false指將消息覆蓋指定的文件內容。

(3).DailyRollingFileAppender 選項

Threshold=WARN:指定日誌消息的輸出最低層次。

ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。

File=mylog.txt:指定消息輸出到mylog.txt文件。

Append=false:默認值是true,即將消息增長到指定文件中,false指將消息覆蓋指定的文件內容。

DatePattern=’.’yyyy-ww:每週滾動一次文件,即每週產生一個新的文件。固然也能夠指定按月、周、天、時和分。即對應的格式以下:

  • ’.’yyyy-MM: 每個月
  • ’.’yyyy-ww: 每週
  • ’.’yyyy-MM-dd: 天天
  • ’.’yyyy-MM-dd-a: 天天兩次
  • ’.’yyyy-MM-dd-HH: 每小時
  • ’.’yyyy-MM-dd-HH-mm: 每分鐘
(4).RollingFileAppender 選項

Threshold=WARN:指定日誌消息的輸出最低層次。

ImmediateFlush=true:默認值是true,意謂着全部的消息都會被當即輸出。

File=mylog.txt:指定消息輸出到mylog.txt文件。

Append=false:默認值是true,即將消息增長到指定文件中,false指將消息覆蓋指定的文件內容。

MaxFileSize=100KB: 後綴能夠是KB, MB 或者是 GB. 在日誌文件到達該大小時,將會自動滾動,即將原來的內容移到mylog.log.1文件

MaxBackupIndex=2:指定能夠產生的滾動文件的最大數。

4. 配置日誌信息的佈局,其語法爲:

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(包含日誌產生的時間、線程、類別等等信息) 

關於additivity

log4j.additivity.zhangsanLog = false

這個additivity也是頗有意思的選項。

它是 子Logger 是否繼承 父Logger 的 輸出源(appender) 的標誌位。具體說,默認狀況下子Logger會繼承父Logger的appender,也就是說子Logger會在父Logger的appender裏輸出。如果additivity設爲false,則子Logger只會在本身的appender裏輸出,而不會在父Logger的appender裏輸出。
效果以下:

log4j.rootLogger=WARN,A2,A3
log4j.logger.test=DEBUG 

log4j.appender.A2=org.apache.log4j.RollingFileAppender
log4j.appender.A2.File=../logs/test.log
log4j.appender.A2.Encoding=UTF-8
log4j.appender.A2.Append=true
log4j.appender.A2.MaxFileSize=2MB
log4j.appender.A2.MaxBackupIndex=5
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%-5p %d [%t] %c{3}.%M - %m%n 

log4j.additivity.test.xml=false
log4j.logger.test.xml=DEBUG,A3 

log4j.appender.A3=org.apache.log4j.RollingFileAppender
log4j.appender.A3.File=../logs/test-xml.log
log4j.appender.A3.Encoding=UTF-8
log4j.appender.A3.Append=true
log4j.appender.A3.MaxFileSize=2MB
log4j.appender.A3.MaxBackupIndex=5
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=%-5p %d [%t] %c{3}.%M - %m%n

配置文件中有

log4j.logger.test=DEBUG
log4j.additivity.test.xml=false
log4j.logger.test.xml=DEBUG,A3

這個實例中,經過log4j.additivity.test.xml=false這一句取消了繼承關係,這樣XML的log就只會在A3中輸出.

另:不考慮日誌級別,a.java, b.java, c.java 分別調用本身的logger,將日誌分別寫入到不一樣的文件中。

這個需求主要是在配置文件中,給appender取個名字

而後在調用時,使用名稱的方式調用

public static Logger loggerA = Logger.getLogger(「Alog」);
public static Logger loggerB = Logger.getLogger(「Blog」);
public static Logger loggerC = Logger.getLogger(「Clog」);
相關文章
相關標籤/搜索