紛亂日誌框架,你選誰?

#why has these blogshtml

最近在弄項目重構的事情,其中各類項目之間由於時間以及技術選型的問題的日誌使用的框架以及版本不同,各個打印的信息日誌也不規範,以前是使用過最多的是log4j系列的日誌框架,但log4j2的新特性以及帶來的好處並非很清楚,其實對日誌框架中的架構以及實現的機制特別好奇,因而想寫關於日誌的一些的博客,沉澱下本身,學習架構以及源碼提高本身的內力,再者分享給你們,一塊學習交流,俗話說,獨樂樂不如衆樂樂,歡迎你們拍磚。(附圖是幾個項目中日誌框架的狀況)java

log4j 1.x版本 logback log4j2版本

#前言程序員

日誌框架林林總總,包括 log4j 、logback、log4j 2以及jdk中提供的JUL等等,面對這麼多的選擇,結合使用的場景,選擇一種做爲記錄日誌的工具,這仍是一件值得考慮的事情。這就如同做爲一位男嘉賓站到非誠勿擾(固然如今更名叫 緣來非誠勿擾) 的舞臺上面對場上的24位女嘉賓的時候,得去選擇一位你心儀的女嘉賓,若是事先不瞭解,那就通常只能按照顏值以及以前的表現來選擇;但有所瞭解的話,那選擇的維度就會不同。spring

選擇適合的日誌框架亦是如此,這將介紹以及比較各類日誌框架的優劣勢,給你們提供些借鑑,有不妥之處,請留言指正,歡迎交流學習,共同探討。(注:博客將介紹各類框架的配置示例,log4j2的配置及使用會是重點,後期也將對logback以及log4j2的架構和源碼進行學習探討)數據庫

#JULapache

Java提供了本身的日誌框架,相似於Log4J,可是API並不完善,對開發者不是很友好,並且對於日誌的級別分類也不是很清晰,因此不推薦使用這種方式輸出日誌。json

####建立方式:架構

static Logger getLogger(String name) 爲指定子系統查找或建立一個 loggerapp

static Logger getLogger(String name, String resourceBundleName) 爲指定子系統查找或建立一個 logger ####日誌級別:框架

  • SEVERE(最高值)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST(最低值)

#log4j 1.x

Log4j是Apache的一個開放源代碼項目,經過使用Log4j,能夠控制日誌信息輸送的目的地是控制檯、文件、數據庫等;也能夠控制每一條日誌的輸出格式;經過定義每一條日誌信息的級別,可以更加細緻地控制日誌的生成過程。

####日誌級別:

7種不一樣的log級別,按照等級從低到高依次爲:TRACE<DEBUG<INFO<WARN<ERROR<FATAL<OFF;

若是配置爲OFF級別,表示關閉log。
####配置方式: Log4j支持兩種格式的配置文件:properties和xml,主要包含的組件:Logger、appender、Layout ####配置示例: <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender class="org.apache.log4j.ConsoleAppender" name="CONSOLE"> <!--增長控制檯appender--> <param value="System.err" name="Target" /> <layout class="org.apache.log4j.PatternLayout"> <!--日誌格式--> <param value="[framework] %d -%-4r [%t] %-5p %c %x - logid-%X{logid} - %m%n" name="ConversionPattern" /> </layout> </appender> <appender name="statAsyncAppender" class="org.apache.log4j.AsyncAppender"> <appender-ref ref="statAppender"/> </appender> <logger name="statAccesslog" additivity="false"> <!--appender關聯至logger對象--> <level value="debug" /> <appender-ref ref="statAccessAppender" /> </logger> <logger name="org.springframework" additivity="true"> <!--指定包的日誌級別--> <level value="error" /> </logger> <root> <level value="info" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration>

#logback

一個「可靠、通用、快速而又靈活的Java日誌框架」,logback當前分紅三個模塊:logback-core,logback- classic和logback-access。

logback-core是其它兩個模塊的基礎模塊,logback-classic是log4j的一個改良版本,此外logback-classic完整實現SLF4J API使你能夠很方便地更換成其它日誌系統如log4j或JDK14 Logging。ogback-access訪問模塊與Servlet容器集成提供經過Http來訪問日誌的功能。(後續學習高級特性以及源碼將詳細介紹三個模塊) ####特色&優點 詳細介紹可參見官網:http://logback.qos.ch/reasonsToSwitch.html

  1. 速度:比log4j要快大約10倍且消耗更少的內存;
  2. 遷移成本低:logback-classic模塊直接實現了SLF4J的接口,遷移到logback幾乎零開銷;
  3. 支持groovy配置格式:同時支持xml以及groovy格式的配置文件,groovy風格更加直觀,簡潔;
  4. 熱部署:logback-classic檢測到配置文件的更新,自動從新加載配置文件;
  5. 及時恢復:優雅的從I/O異常中恢復,無需從新啓動應用程序恢復logger;
  6. 歷史日誌:根據上限值或者週期自動刪除歷史日誌文件;
  7. 壓縮日誌:支持自動壓縮日誌文件。
  8. 條件判斷支持:支持條件判斷(if-then-else),可避免不一樣的環境配置文件的重複;
  9. 強大過濾支持:擁有更多filter,執行相應過濾操做;
  10. 系統集成:logback-access和Jetty、Tomcat集成提供了功能強大的HTTP-access日誌;

####加載配置 resources目錄下創建logback.xml文件,加載配置文件順序是:logback先查找logback.groovy文件;若未找到,則查找logback-test.xml文件;若未找到,則查找logback.xml文件;若仍未找到,則使用默認配置(打印到控制檯) ####配置示例 <configuration>
<Properties> <!---設置property屬性--> <Property name="LOG_FILE">app.log</Property> </Properties> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--定義控制檯appender--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!--增長 filter--> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <charset>UTF-8</charset> <pattern>%d [%thread] %-5level %logger{68} %line - logId[%X{client}] - %msg%n</pattern> </encoder> </appender> <appender name="testAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>/opt/data/app.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--歷史日誌處理策略--> <!-- rollover daily --> <fileNamePattern> <fileNamePattern>/history/%d{yyyy-MM,aux}/${LOG_FILE}_%d</fileNamePattern> </fileNamePattern> <maxHistory>60</maxHistory> <cleanHistoryOnStart>false</cleanHistoryOnStart> </rollingPolicy> <encoder> <charset>UTF-8</charset> <pattern>%d [%thread] %-5level %logger{68} %line - logId[%X{client}] - %msg%n</pattern> </encoder> </appender> <logger name="cn.test"> <level value="INFO"/> <appender-ref ref="testAppender"/> </logger> <root level="INFO"> <appender-ref ref="CONSOLE"/> </root> </configuration> 其它詳細配置能夠參見官網:http://logback.qos.ch/manual/

#log4j2

Apache軟件基金會最近發佈了Log4j 2.0通用版本,相比以前Log4j的1.x版本有了很大的性能提高。本版本的靈感來自於諸如Log4j 1.x和java.util.logging之類的已有日誌解決方案,它是通過了數年的努力從頭開始編寫完成的。

Log4j 2.0引入了新的插件系統、對properties的支持、對基於 JSON配置的支持和配置的自動化重載。它支持不少已有的日誌框架,包括SLF4J、Commons Logging、Apache Flum、Log4j 1.x,並提供了新的程序員API。

在Asynchronous Logging這塊確實有較大的性能提高,關於性能這塊官網專門有個章節介紹,能夠參考官網的數據統計:http://logging.apache.org/log4j/2.x/performance.html log4j2-性能(摘自官網)

####加載配置

與logback類似,log4j能夠支持多種格式的配置文件,包括,log4j2也有自身加載配置的一套機制,總結下來:log4j2先找log4j.configurationFile指定路徑的配置文件,若還沒有配置,則找classpath下以log4j-test爲前綴的配置文件,若沒發現,再找classpath下找以log4j2爲前綴的配置文件,尚未的話,則會使用DefaultConfiguration,將error級別日誌輸出至控制檯,具體加載順序以下:

  1. 讀取系統屬性log4j.configurationFile配置指定路徑的配置文件;
  2. 若沒有,則找 classpath下log4j2-test.properties;
  3. 若沒有,則找 classpath下 log4j2-test.yaml or log4j2-test.yml;
  4. 若沒有,則找 classpath下 log4j2-test.json or log4j2-test.jsn;
  5. 若沒有,則找 classpath下 log4j2-test.xml;
  6. 若沒有,則找 classpath下 log4j2.properties;
  7. 若沒有,則找 classpath下 log4j2.yaml or log4j2.yml;
  8. 若沒有,則找 classpath下 log4j2.json or log4j2.jsn;
  9. 若沒有,則找 classpath下 log4j2.xml;
  10. 若沒有,則啓用默認配置,將error級別日誌輸出至控制檯;

官方解釋以下: log4j自動加載配置

####配置示例 <Configuration status="WARN" monitorInterval="30"> <!--配置自動加載更新,週期30s,最小週期爲5s--> <Properties> <Property name="testProperty">test.log</Property> <!--設置配置自己property屬性--> </Properties> <Appenders> <RollingFile name="Console" fileName="stdout.log" filePattern="stdout.log.%d{yyyy-MM-dd}"> <PatternLayout pattern="${testProperty} %d{yyyy-MM-dd HH:mm:ss.SSS} test_log %-5level %C{36} %logger{36} %line - logid-%X{logid} - %msg%n"/> <!--引用testProperty變量--> <Policies> <!--日誌文件處理策略--> <TimeBasedTriggeringPolicy /> <!--時間策略--> </Policies> <DefaultRolloverStrategy> <Delete basePath="/"> <IfFileName glob="stdout.log.*"></IfFileName> <IfLastModified age="2d"></IfLastModified> <!--保留兩天--> </Delete> </DefaultRolloverStrategy> </RollingFile> <Loggers> <Logger name="com.foo.Bar" additivity="false"> <!--是否向上疊加日誌--> <AppenderRef ref="Console"/> </Logger> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration> 問題記錄

  • 加載非classpath下的log4j2.xml

問題:在某些場景下,會將log4j2的配置文件打包至根目錄下,這時項目啓動會沒法加載到log4j2的配置文件而致使日誌沒法打印; log4j_outer_config

解決方案:配置環境變量log4j.configurationFile,項目啓動的時候,讓log4j去指定的目錄加載相應的配置文件;上面提到的問題,加上以下參數便可:-Dlog4j.configurationFile=../log4j2.xml;

#後記

程序員是一羣善於自嘲,踏實奮進的羣體,在別人眼中是"猿人",卻改變着世界以及生活,老是低調謙虛好學,我很高興是羣體中一員並對技術懷揣着無限熱情,今天正好是公元2016年10月24日,1024 Engineer's Day,祝各位節日快樂,升職加薪早日找到白富美,踏上人生巔峯~~~(昨日與女朋友吵架,心情不美麗,博客未完待續......)

相關文章
相關標籤/搜索