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(佈局)。這裏可簡單理解爲日誌類別,日誌要輸出的地方和日誌以何種形式輸出。綜合使用這三個組件能夠輕鬆地記錄信息的類型和級別,並能夠在運行時控制日誌輸出的樣式和位置。
Loggers 組件在此係統中被分爲五個級別:DEBUG、INFO、WARN、ERROR和FATAL。這五個級別是有順序的,DEBUG < INFO < WARN < ERROR < FATAL,分別用來指定這條日誌信息的重要程度。Log4j 有一個規則:只輸出級別不低於設定級別的日誌信息。假設 Loggers 級別設定爲 INFO,則 INFO、WARN、ERROR 和 FATAL 級別的日誌信息都會輸出,而級別比 INFO 低的 DEBUG 則不會輸出。
Log4J 中老是存在一個 rootLogger,即便沒有顯示配置也是存在的,而且默認輸出級別爲 DEBUG。其它的 logger 都繼承自這個 rootLogger(若是其餘logger未單獨定義其輸出級別)。
其次,Log4J 中的層次(Hierarchy)是用 '.' 來分隔的,如 log4j.logger.com.example.test
,並非說 log4j.logger 後面必定是具體的包名乃至類名,這個名稱能夠自定義,咱們甚至能夠定義一個log4j.logger.A.B.C,以下例所示,創建了 3 個 logger 實例,它們分別是 A
、A.B
、A.B.C
## log4j.properties
log4j.logger.A.B.C = ERROR,appenderName
## 在代碼中獲取名爲 A.B 的日誌對象
Logger logger = Logger.getLogger("A.B")
複製代碼
當獲取不到當前須要的 logger 時,查找動做會傳遞,直到 root 節點仍沒找到對應名字的 logger,就返回 root logger 實例。
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)等,能夠根據天數或者文件大小產生新的文件,能夠以流的形式發送到其它地方等等。
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
複製代碼
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
複製代碼
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
複製代碼
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
複製代碼
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
複製代碼
有時用戶但願根據本身的喜愛格式化本身的日誌輸出,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
的日誌對象。
LOG_HOME=D://data//usr//local//logs//home1
log4j.rootLogger=debug,fileAppender
# ...
log4j.appender.fileAppender.File=${LOG_HOME}//log4j-log.log
複製代碼
差很少是隱藏功能了...
不一樣模塊:以包名爲 loggerName 定義多個 logger 實例
不一樣文件:定義多個 fileAppender,並與對應的 loggerName 的 logger 實例關聯
參考:www.cnblogs.com/0201zcr/p/5…