Log4j 筆記

Log4j 彷佛已經被淘汰了爲何還要寫這篇文章?html

log4j、log4j二、logback 從基礎思想上三者的實現是一致的,無非就是輸出內容到文件,且看配置文件也都大同小異(logger、appender、layout),無非後二者比前者具備更多的高級功能,此塊能夠單獨拎出講。因此若是想了解本質,從最開始的版本開始會比較好下手。java

簡單體驗

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
複製代碼

測試類:mysql

public static void main(String[] args) {
    Logger logger = Logger.getLogger(Log4jTest.class);
    logger.debug("log4j debug");
    logger.info("log4j info");
    logger.error("log4j error");
}
複製代碼

輸出到控制檯:log4j.propertiessql

# 定義一個名爲 csAppender 的日誌附加器
log4j.appender.csAppender=org.apache.log4j.ConsoleAppender
log4j.appender.csAppender.Threshold=INFO
log4j.appender.csAppender.Target=System.out
log4j.appender.csAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.csAppender.layout.ConversionPattern=[%d] [%t] [%c.%M:%L] [%-5p]: %m%n

# 配置根日誌級別爲 debug,並設置輸出器爲剛定義的 csAppender
log4j.rootLogger=debug,csAppender
複製代碼

輸出到文件:log4j.properties數據庫

# 定義一個名爲 fileAppender 的日誌附加器
log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.fileAppender.Threshold=INFO
log4j.appender.fileAppender.File=D://data//usr//local//logs//home//log4j-log.log
log4j.appender.fileAppender.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.fileAppender.Encoding=UTF-8
log4j.appender.fileAppender.Append=true
log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern=[%d] [%t] [%-5p] [%c.%M:%L]: %m%n
# 配置根日誌級別爲 debug,並設置輸出器爲剛定義的 fileAppender
log4j.rootLogger=debug,fileAppender
複製代碼

上面示例配置中的 root 日誌實例分別使用 csAppender(控制檯)、fileAppender(文件)附加器將日誌內容輸出到目的地。固然也能夠同時輸出。log4j 官網並無對配置進行說明,但在 org.apache.log4j.PropertyConfigurator#doConfigure 方法註釋上可看到完整的說明。apache

第一步須要配置根 Logger 格式以下:多線程

log4j.rootLogger = [level] , appenderName1, appenderName2, …
複製代碼
  • level 設定日誌記錄的最低級別,可設的值有 OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定義的級別,好比在這裏設定了INFO級別,則應用程序中全部DEBUG級別的日誌信息將不會被打印出來。app

  • appenderNamesocket

    就是指定日誌信息要輸出到哪裏。能夠同時指定多個輸出目的地,用逗號隔開。 例如:log4j.rootLogger=INFO,A1,B2,C3佈局

第二步配置日誌信息輸出目的地(appender)格式以下:

# For appender named
log4j.appender.appenderName=fully.qualified.name.of.appender.class
# Set appender specific options.
log4j.appender.appenderName.option1=value1
...
log4j.appender.appenderName.optionN=valueN
複製代碼

三大組件

Log4j has three main components: loggers, appenders and layouts. These three types of components work together to enable developers to log messages according to message type and level, and to control at runtime how these messages are formatted and where they are reported.

Log4j 有三個主要的組件:Loggers(記錄器),Appenders (輸出源)和 Layouts(佈局)。這裏可簡單理解爲日誌類別,日誌要輸出的地方和日誌以何種形式輸出。綜合使用這三個組件能夠輕鬆地記錄信息的類型和級別,並能夠在運行時控制日誌輸出的樣式和位置。

Logger

Loggers 組件在此係統中被分爲五個級別:DEBUG、INFO、WARN、ERROR和FATAL。這五個級別是有順序的,DEBUG < INFO < WARN < ERROR < FATAL,分別用來指定這條日誌信息的重要程度。Log4j 有一個規則:只輸出級別不低於設定級別的日誌信息。假設 Loggers 級別設定爲 INFO,則 INFO、WARN、ERROR 和 FATAL 級別的日誌信息都會輸出,而級別比 INFO 低的 DEBUG 則不會輸出。

定義 logger

Log4J 中老是存在一個 rootLogger,即便沒有顯示配置也是存在的,而且默認輸出級別爲 DEBUG。其它的 logger 都繼承自這個 rootLogger(若是其餘logger未單獨定義其輸出級別)。

其次,Log4J 中的層次(Hierarchy)是用 '.' 來分隔的,如 log4j.logger.com.example.test,並非說 log4j.logger 後面必定是具體的包名乃至類名,這個名稱能夠自定義,咱們甚至能夠定義一個log4j.logger.A.B.C,以下例所示,創建了 3 個 logger 實例,它們分別是 AA.BA.B.C

## log4j.properties
log4j.logger.A.B.C = ERROR,appenderName
## 在代碼中獲取名爲 A.B 的日誌對象
Logger logger = Logger.getLogger("A.B")
複製代碼

當獲取不到當前須要的 logger 時,查找動做會傳遞,直到 root 節點仍沒找到對應名字的 logger,就返回 root logger 實例。

Appender

Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy

log4j 官網這句話的意思是,logger 對象能夠繼承,且 appender 是能夠累加的。當調用層次較低的 logger 對象輸出日誌時,log4j 會把該請求輸出到當前全部附加在此 logger 上的全部 appender。

假設存在以下配置文件:

log4j.rootLogger=DEBUG,consoleAppender

log4j.logger.com=DEBUG,consoleAppender
log4j.logger.com.A.B=INFO,consoleAppender
log4j.logger.com.X=INFO,consoleAppender

## ... 省略 consoleAppender 配置
複製代碼

則 log4j 日誌容器中存在以下圖示實例關係:

對於名爲 A.B 的 logger 輸出的日誌會往控制檯輸出三次,緣由是 A.B 繼承 A 的以及A 的父 logger 的全部 appender,這種繼承關係僅僅是把父 logger 的 appender 添加到本身的 appender 列表中,父 logger 的輸出 level 不會影響子 logger 的輸出。

log4j.rootLogger=DEBUG,consoleAppender
log4j.logger.A=DEBUG,consoleAppender
log4j.logger.A.B=INFO,consoleAppender
log4j.additivity.A.B=false
複製代碼

名爲 A.B 的 logger 日誌僅會輸出到本身的 appender 中,不會繼承任何父 logger 的 appender。

若想對輸出到 appender 中的日誌級別進行限制的話,就須要用到 threshold 來控制。

log4j.threshold=ERROR
複製代碼

用來控制全部的 appender,即輸出到全部appender的日誌,無論原來是什麼級別的,都不能低於threshold所規定的級別。

log4j.appender.Console.threshold=ERROR 
複製代碼

用來控制指定的 appender 的輸出級別。

Log4j 日誌系統還提供許多強大的功能,好比容許把日誌輸出到不一樣的地方,如控制檯(Console)、文件(Files)等,能夠根據天數或者文件大小產生新的文件,能夠以流的形式發送到其它地方等等。

控制檯(console)

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
複製代碼

日誌文件(logFile)

log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.Threshold=DEBUG
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/logs/log.log4j
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
複製代碼

回滾文件(rollingFile)

  • Threshold=WARN:指定日誌信息的最低輸出級別,默認爲DEBUG
  • ImmediateFlush=true:表示全部消息都會被當即輸出,設爲false則不輸出,默認值是true。
  • Append=false:true表示消息增長到指定文件中,false則將消息覆蓋指定的文件內容,默認值是true。
  • File=D:/logs/logging.log4j:指定消息輸出到logging.log4j文件中。
  • MaxFileSize=100KB:後綴能夠是KB, MB 或者GB。在日誌文件到達該大小時,將會自動滾動,即將原來的內容移到logging.log4j.1文件中。
  • MaxBackupIndex=2:指定能夠產生的滾動文件的最大數,例如,設爲2則能夠產生logging.log4j.1,logging.log4j.2兩個滾動文件和一個logging.log4j文件。
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.Threshold=DEBUG
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.Append=true
log4j.appender.rollingFile.File=D:/logs/log.log4j
log4j.appender.rollingFile.MaxFileSize=200KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
複製代碼

按期回滾日誌文件(dailyFile)

DatePattern='.'yyyy-MM:即每個月產生一個新的日誌文件。當前月的日誌文件名爲 logging.log4j,前一個月的日誌文件名爲 logging.log4j.yyyy-MM。另外,也能夠指定按周、天、時、分等來滾動日誌文件,對應的格式以下:

- yyyy-MM:每個月
- yyyy-ww:每週
- yyyy-MM-dd:天天
- yyyy-MM-dd-a:天天兩次
- yyyy-MM-dd-HH:每小時
- yyyy-MM-dd-HH-mm:每分鐘
複製代碼
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.Threshold=DEBUG
log4j.appender.dailyFile.ImmediateFlush=true
log4j.appender.dailyFile.Append=true
log4j.appender.dailyFile.File=D:/logs/log.log4j
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
複製代碼

應用於 socket

log4j.appender.socket=org.apache.log4j.RollingFileAppender
log4j.appender.socket.RemoteHost=localhost
log4j.appender.socket.Port=5001
log4j.appender.socket.LocationInfo=true
複製代碼

發送日誌到指定郵件

log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=FATAL
log4j.appender.mail.BufferSize=10
log4j.appender.mail.From = xxx@mail.com
log4j.appender.mail.SMTPHost=mail.com
log4j.appender.mail.Subject=Log4J Message
log4j.appender.mail.To= xxx@mail.com
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
複製代碼

應用於數據庫

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('=[%-5p] %d(%r) --> [%t] %l: %m %x %n')
log4j.appender.database.layout=org.apache.log4j.PatternLayout
複製代碼

Layout

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

- org.apache.log4j.HTMLLayout(以HTML表格形式佈局)
- org.apache.log4j.PatternLayout(能夠靈活地指定佈局模式)
- org.apache.log4j.SimpleLayout(包含日誌信息的級別和信息字符串)
- org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等信息)
複製代碼

格式化符號說明

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

實戰分析

定義兩個 appender 分別輸出到控制檯和文件,針對名爲 com.fingard.rh.rhf.ryb.manager.UnifiedServiceManager 日誌輸出級別調成 ERROR,且禁用 appender 繼承,只在當前 logger 的 appender 中輸出。在類 UnifiedServiceManager 中如果使用以下方式獲取 logger 則日誌只有在 ERROR 級別及以上會輸出

Logger logger1 = Logger.getLogger(UnifiedServiceManager.class)
複製代碼

分析 Logger getLogger(Class clazz) 源碼可知,默認使用類全路徑做爲 loggerName 傳入。故獲取到的 logger1 即爲配置文件中指定名爲 com.fingard.rh.rhf.ryb.manager.UnifiedServiceManager 的日誌對象。

使用技巧

在 .properties 配置文件中定義變量

LOG_HOME=D://data//usr//local//logs//home1

log4j.rootLogger=debug,fileAppender
# ...
log4j.appender.fileAppender.File=${LOG_HOME}//log4j-log.log
複製代碼

差很少是隱藏功能了...

log4j 不一樣模塊輸出到不一樣的文件

不一樣模塊:以包名爲 loggerName 定義多個 logger 實例

不一樣文件:定義多個 fileAppender,並與對應的 loggerName 的 logger 實例關聯

參考:www.cnblogs.com/0201zcr/p/5…

日誌輸出動態改變路徑

參考:blog.csdn.net/wiwipetter/…

參考

相關文章
相關標籤/搜索