<meta http-equiv="refresh" content="1"/>
# log4j日誌組件 #
- SLF4J,一個**通用日誌接口**
log4j、logback、log4j2等日誌系統均可以無縫對接
- log4j的配置詳解
- 如何實現自定義過濾輸出
### SLF4J ###
> + SLF4J,即簡單日誌門面(Simple Logging Facade for Java),不是具體的日誌解決方案,它只服務於各類各樣的日誌系統。
> + 實際上,SLF4J所提供的核心API是一些接口以及一個LoggerFactory的工廠類。從某種程度上,SLF4J有點相似JDBC,不過比JDBC更簡單,在JDBC中,你須要指定驅動程序,而在使用SLF4J的時候,不須要在代碼中或配置文件中指定你打算使用那個具體的日誌系統。如同使用JDBC基本不用考慮具體數據庫同樣,SLF4J提供了統一的記錄日誌的接口,只要按照其提供的方法記錄便可,最終日誌的格式、記錄級別、輸出方式等經過具體日誌系統的配置來實現,所以能夠在應用中靈活切換日誌系統。
> + log4j是Apache的一個開源項目,log4j2和log4j是一個做者,只不過log4j2是從新架構的一款日誌組件,他拋棄了以前log4j的不足,以及吸收了優秀的logback的設計從新推出的一款新組件,性能較之log4j有了近10倍的提高,社區活躍度很高。
### log4j配置 ###
> ```
> # log4j有三大組件:logger appender layout
> # logger 日誌級別相關
> # appender 日誌輸出相關
> # layout 輸出格式相關
>
> # log4j的根配置
> # -第一個位置表示輸出日誌的級別[level], debug --> info --> warn --> error
> # -以後的表示自定義輸出的logger,用來分別按需求進行處理
> # level參數:表示默認狀況下的輸出級別,若是一個包或者類沒有指定輸出級別,那麼就會按照這個默認的來
> log4j.rootLogger = INFO, stdout, fileout
> # 若是指定了某個包的輸出級別,他會與默認的rootLogger進行merge操做(level會覆蓋掉)
> #log4j.logger.logtest=ERROR
> # logger 不只能夠指定輸出級別,還能夠指定輸出器輸出
> log4j.logger.logtest=DEBUG, logtestout
>
> # Appender 爲日誌輸出目的地,Log4j提供的appender有如下幾種:
> # org.apache.log4j.ConsoleAppender(控制檯),
> # org.apache.log4j.FileAppender(文件),
> # org.apache.log4j.DailyRollingFileAppender(天天產生一個日誌文件),
> # org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件),
> # org.apache.log4j.WriterAppender(將日誌信息以流格式發送到任意指定的地方)
> #
> # 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:每週滾動一次文件,即每週產生一個新的文件。固然也能夠指定按月、周、天、時和分。即對應的格式以下:
> # 1)'.'yyyy-MM: 每個月
> # 2)'.'yyyy-ww: 每週
> # 3)'.'yyyy-MM-dd: 天天
> # 4)'.'yyyy-MM-dd-a: 天天兩次
> # 5)'.'yyyy-MM-dd-HH: 每小時
> # 6)'.'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:指定能夠產生的滾動文件的最大數。
>
> # Layout:日誌輸出格式,Log4j提供的layout有如下幾種:
> # org.apache.log4j.HTMLLayout(以HTML表格形式佈局),
> # org.apache.log4j.PatternLayout(能夠靈活地指定佈局模式),
> # org.apache.log4j.SimpleLayout(包含日誌信息的級別和信息字符串),
> # org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等等信息)
>
> # 打印參數: Log4J採用相似C語言中的printf函數的打印格式格式化日誌信息,以下:
> # %p: 輸出日誌信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL,
> # %d: 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也能夠在其後指定格式,好比:%d{yyy MMM dd HH:mm:ss,SSS},輸出相似:2002年10月18日 22:10:28,921
> # %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"輸出日誌信息換行
> #
> # 能夠在%與模式字符之間加上修飾符來控制其最小寬度、最大寬度、和文本的對齊方式。如:
> # 相似於 C語言的格式化輸出printf 和 Java中的StringFormat中的佔位符
> # 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.appender.stdout=org.apache.log4j.ConsoleAppender
> # Threshold=level 只是顯示當前定義的logger中≥level的纔會顯示
> # 若是定義了 DEBUG、WARN和ERROR級別的信息,可是Threshold設置的是WARN,那麼只會顯示WARN和ERROR的信息
> log4j.appender.stdout.Threshold=DEBUG
> log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
> log4j.appender.stdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss},%6.6r]%-5p[%t]%x(%F\:%L) - %m%n
>
> log4j.appender.fileout=org.apache.log4j.DailyRollingFileAppender
> log4j.appender.fileout.Threshold=WARN
> log4j.appender.fileout.File=d:/fileout-WARN.log
> log4j.appender.fileout.DatePattern='.'yyyy-MM-dd
> log4j.appender.fileout.layout=org.apache.log4j.PatternLayout
> log4j.appender.fileout.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss},%6.6r]%-5p[%t]%x(%F\:%L) - %m%n
>
> log4j.appender.logtestout=org.apache.log4j.DailyRollingFileAppender
> log4j.appender.logtestout.Threshold=WARN
> log4j.appender.logtestout.File=d:/logtestout-WARN.log
> log4j.appender.logtestout.DatePattern='.'yyyy-MM-dd
> log4j.appender.logtestout.layout=org.apache.log4j.PatternLayout
> log4j.appender.logtestout.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss},%6.6r]%-5p[%t]%x(%F\:%L) - %m%n
> ```
### 測試階段 ###
> ```
> 導入maven依賴,包含slf4j-api-xxx.jar、slf4j-log4j12-xxx.jar、log4j-xxx.jar
> <!-- 日誌組件 -->
> <dependency>
> <groupId>org.slf4j</groupId>
> <artifactId>slf4j-log4j12</artifactId>
> <version>1.7.19</version>
> </dependency>
>
> 將上面的log4j.properties拷貝到classpath中,SE程序在src根目錄,WEB程序放在WEB-INF或者src根目錄,MAVEN程序放在resources中
>
> 測試包的代碼
> /**
> * 日誌配置,log4j.properties的測試
> */
> public class LoggerTest {
>
> Logger log = LoggerFactory.getLogger(this.getClass());
>
> public LoggerTest() {
> log.debug("init the LoggerText...");
> }
>
> public void test( ) {
> log.info("initialize the variable of i...");
> int i = 0;
> log.warn("self add the variable of i...");
> i++;
> log.error("print the variable of i...");
> System.err.println("i = " + i);
> }
>
> // Run this program
> public static void main(String[] args) {
> new LoggerTest().test();
> }
> }
>
> 輸出結果:
> [2018-08-24 11:51:49, 0]DEBUG[main](LoggerTest.java:16) - init the LoggerText...
> [2018-08-24 11:51:49, 7]INFO [main](LoggerTest.java:20) - initialize the variable of i...
> [2018-08-24 11:51:49, 7]WARN [main](LoggerTest.java:22) - self add the variable of i...
> [2018-08-24 11:51:49, 8]ERROR[main](LoggerTest.java:24) - print the variable of i...
> i = 1
> 磁盤放置了兩個文件夾,分別是上邊配置的logtestout-WARN.log.yyyy-MM-dd和fileout-WARN.log.yyyy-MM-dd
> 輸出內容與本身定義的級別同樣
> ```java