1.1 前言
說出來真是丟臉,最近被公司派到客戶公司面試外包開發崗位,本來準備了什麼redis、rabbitMQ、SSM框架的相關面試題以及自己做過的一些項目回顧,信心滿滿地去面試,結果別人一上來就問到了最近項目使用的日誌系統是什麼?日誌級別是怎麼配置的?當時我都蒙X了,平時都是項目經理搭的,我自己也是隨便上網一搜往配置文件一黏貼就OK了。我就這麼說完後面試官深深定了我一眼,當時我的內心羞愧到......
1.2 閒話少說,講講日誌的發展故事(如果已經了解的可以跳過,直接看1.3日誌配置)
要想對日誌技術實現深入了解,我個人建議去看:logback + slf4j。至於日誌配置,還是了解log4j比較好,因為目前絕大部分的項目還是使用log4j的。好了,下面開始講講日誌的發展故事:
1999年,Apache開源社區發布了log4j,一時轟動整個程序界,從此成為日誌的標準並廣泛為java程序員所使用。隨後Sun公司也在JDK1.4版本時發布了Logging機制(java.util.logging,以下簡稱JUL),但是該機制並未獲得公眾的認可,真是可憐。不久Apache又推出了commons-logging日誌框架(能夠讓開發者抽像日志實現方式而不必關注具體使用哪個日誌技術,通俗地說就是你要用手機叫滴滴,如果你是在北京你就會叫來北京的滴滴,在香港你就會叫來香港的滴滴),該框架彷彿是對Sun公司的鄙睨,其可以自動查找調用當前環境下的日誌技術進行日誌輸出,該日誌框架可支持log4j或JUL。 commons-logging+log4j在其後的很長一段時間內成為了Java日誌的經典組合。然而之後commons-logging有一段時間沒更新了,不知道是不是commons-logging當初的設計不夠好,想再優化也比較多困難,為什麼這麼說呢?因為接下來一個優秀的日誌框架slf4j誕生了,該作者(Ceki Gülcü)就是log4j的作者之一,他的slf4j設計上更優雅,並且他還實現了logback技術,也是比log4j更前沿。至此,日誌體係由commons-logging+log4j一家獨大的局面開始受到動搖,各種commons-logging+log4j? slf4j+log4j? slf4j+logback?搭配,真是讓人揪心。更恐怖的是,Ceki Gülcü大佬又幫忙優化了log4j,從此世界又多了一項日誌技術--log4j2。這是要學騰訊搞微信和QQ嗎,真是666。因此,如果大家想對日誌技術深入了解的話,可以去找找logback + slf4j的相關資料。至於配置文件,我認為你就了解下我下面寫的log4j配置詳解就好了,畢竟現在還是比較多公司用log4j框架的。
1.3 進入正題,log4j日誌基本配置
1.在項目的classpath下或者resource包下(maven項目)新建一個log4j.properties文件,初始項目配置如下參數就足夠了,更詳細配置可繼
續看1.4 log4j日誌級別配置;
#通過根日誌記錄器指定日誌級別及輸出源#日誌輸出的優先級: debug < info < warn < error < fatal#定義根日誌記錄器的日誌級別(info)及輸出源的別名(console,myFile)#該定義讓日誌在控制台和文件輸出,並且只輸出info級別以上的日誌log4j.rootLogger=info,console,myFile#######配置輸出源console的具體實現為控制台輸出########定義輸出源別名console(即根日誌記錄器定義的輸出源)#的實現類是ConsoleAppender(控制台輸出源)log4j.appender.console=org.apache.log4j.ConsoleAppender #指定日誌輸出格式的格式轉換器為PatternLayout實現類log4j.appender.console.layout=org.apache.log4j.PatternLayout#定義日誌輸出的具體格式log4j.appender.console.layout.ConversionPattern=%d %-5p [%c.%M()] - %m%n #######配置輸出源myFile的具體實現為文件輸出########定義輸出源別名myFile(即根日誌記錄器定義的輸出源)#的實現類是RollingFileAppender(文件輸出源)log4j.appender.myFile=org.apache.log4j.RollingFileAppender#定義日誌文件的存儲路徑log4j.appender.myFile.File=src/log/logProperties/log4j.log#定義日誌文件的大小log4j.appender.myFile.MaxFileSize=1024kb#定義日誌文件最多生成幾個(從0開始算1個,即此處最多3個文件)#超過該大小則會覆蓋前面生成的文件log4j.appender.myFile.MaxBackupIndex=2#指定日誌輸出格式的格式轉換器為PatternLayout實現類log4j.appender.myFile.layout=org.apache.log4j.PatternLayout#定義日誌輸出的具體格式log4j.appender.console.layout.ConversionPattern=%d %-5p [%c.%M()] - %m%n #######輸出格式解釋########%d: 日誌打印的時間點,默認格式為ISO8601,也可以另外指定格式, #定義如下: %d{yyy年MM月dd日HH時mm分ss秒SSS},則會輸出: #2018年01月06日14時47分45秒590#%p: 輸出日誌級別,即DEBUG,INFO,WARN,ERROR,FATAL #%-5p:表示字符小於5位,則字符居左(不加“-”號則字符居右),你可以舉一反三#%c: 日誌所在類的全名#%M: 日誌所在方法的名字#%m: 日誌信息#%n: 輸出一個回車換行符#%L: 輸出代碼中的行號2.調用日誌測試配置結果。
import org.apache.log4j.LogManager;import org.apache.log4j.Logger;import org.apache.log4j.PropertyConfigurator;public class LogPropertiesTest { public static void main(String[] args) { /*解析非classpath下的配置文件String log4jPath=System.getProperty("user.dir")+"//src//log//logProperties//log4j.properties"; PropertyConfigurator.configure(log4jPath);*/ Logger log = LogManager.getLogger(LogPropertiesTest.class); log.debug("調試"); log.info("信息"); log.warn("警告"); log.error("錯誤"); log.fatal("致命錯誤"); }}1.4日誌級別配置
日誌級別配置可分為3類,一類如上配置是配置父類日誌記錄器的日誌級別,第二類是配置子類日誌記錄器的日誌級別,第三類是配置輸出源(控制台、文件等)的日誌級別。他們的日誌級別解析優先級由低到高排列。具體表述原諒我說不清楚,直接上案例,大家應該能夠懂!
1.如果配置(也必須要配置)了父類日誌記錄器(rootLogger)的日誌級別(假設是INFO級別),沒有配置子類日誌記錄器的日誌級別,也沒有配置輸出源的日誌級別,則輸出源只能輸出INFO級別以上的;
2.如果配置(也必須要配置)了父類日誌記錄器(rootLogger)的日誌級別(假設是INFO級別),配置了子類日誌記錄器的日誌級別(假設是DEBUG級別),沒有配置輸出源的日誌級別,則輸出源輸出DEBUG級別以上的;
3.如果配置(也必須要配置)了父類日誌記錄器(rootLogger)的日誌級別(假設是INFO級別),配置了子類日誌記錄器的日誌級別(假設是DEBUG級別),配置了輸出源的日誌級別(假設是INFO級別),則輸出源輸出INFO級別以上的;
4.如果配置(也必須要配置)了父類日誌記錄器(rootLogger)的日誌級別(假設是INFO級別),沒有配置子類日誌記錄器的日誌級別,配置
了輸出源的日誌級別(假設是DEBUG級別),則輸出源輸出INFO級別以上的;
因此,從上述的案例中我們可以知道日誌記錄器和輸出源輸出日誌級別存在2個邏輯關係:
1.輸出源如果沒有定義日誌級別,它會繼承最接近它的子類日誌記錄器的日誌級別;子類日誌記錄器沒有定義日誌級別,它會繼承最接近它的父類日誌記錄器。
2.打印日誌時輸出源會根據自身定義的日誌級別與最接近它的子類日誌記錄器定義的日誌級別比較,如果輸出源定義的級別高於子類日誌記錄器,則按輸出源定義的日誌級別輸出日誌,反之則按子類日誌記錄器的日誌級別輸出。
所以在項目中可以按日下配置方式配置日誌級別:
#控制父類日誌記錄器的日誌級別為info,默認所有模塊下只輸出info級別以上的日誌log4j.rootLogger=info,console#單獨控制某個模塊下的日誌級別為error,只有發生異常的時候才輸出日誌log4j.logger.log.logProperties=error#單獨控制某個類的日誌級別debug,方便輸出調試信息log4j.logger.log.logProperties.LogPropertiesTest=debug############# 日誌輸出到控制台############# #日誌輸出到控制台使用的api類log4j.appender.console=org.apache.log4j.ConsoleAppender #指定當前輸出源的日誌級別,有了前面的配置,就不需要配置該項了#log4j.appender.console.Threshold = info#指定日誌輸出的格式:靈活的格式log4j.appender.console.layout=org.apache.log4j.PatternLayout #具體格式的內容log4j.appender.console.layout.ConversionPattern=%d %-2p [%c.%M()] - %m%n
1.5結束語
到此,相信你日誌配置有了基本的掌握了。文中有很多地方可能會有不對的地方,歡迎各位大俠指出。我也是為了能夠深刻理解該技術的配置,才撰文總結,這樣我就會對它有更深層次的理解了。