Java程序員修煉之道 之 Logging(1/3) - Logback 配置
Posted on 2014-08-10 02:46 Justfly Shi 閱讀(19798) 評論(1) 編輯 收藏 所屬分類: Java程序員修煉之道寫在前面的話:
作為《Java程序員修煉之道》博文的第一個主題Logging,我計劃中按照如下三篇來寫:
- Logback的簡單介紹和配置
- 在Java代碼中如何使用SLF4J來寫日志以及寫日志的要點
- 作為一個程序員,在日常工作中如何分析和挖掘Log。
1. 緣起
寫代碼中的日志是一個除了用代碼實現功能之外最基礎最基礎的一個技能了,是一個必須掌握的技能。但是目前為止,關于如何日志的文章和書籍還是不多。
1.1 寫日志的必要性
碰到QA提的一個bug的時候,我見識過兩種方式的答復:a)請給我重現步驟和重現數據;b)把當時的日志給我。答復前者的,一般需要花很多時間去找問題出現在那里,如果是別人開發的模塊的話,花費的時間更多。答復后者的,一般能很快的找到出問題的點,然后就可以開始進入修復的流程。
從概念上來說:日志是一個可運行的、可維護的軟件的基礎組成部分;通過日志,我們可以了解軟件系統在運行中的實時狀態,歷史狀態和異常狀態等。一個沒有良好日志的軟件是所有人的噩夢。
如果你不想給自己找麻煩,你還是把日志好好寫寫。
1.2 為什么選Logback?
原因有倆:
- 我最近幾年用的都是Logback
- 在前幾天Log4j 2.0出來之前,logback的Logger用得比較爽
2. 如何配置Logback
2.1 Logback簡單介紹
簡單來說就是Log4j 1流行了,發現有一些問題是無法解決的,于是又出來了Logback,在Log4j的基礎上提升了性能,提高了功能等等。不過前幾天有出來了Log4j 2,據說是相對于Logbak來說又提升了性能提高了功能。
2.2 關于SLF4J和Logback
SLF4J(slf4j.org)又稱Simple Logging Facade for Java,是一個通用的logging接口,它試圖一統Logging框架的天下,兼容了(Log4j 1, java.util.logging和Jakarta Commons Logging)這三個最流行的Logging框架。Logback就是SLF4J的默認實現。
2.3 依賴包導入
2.3.1 一般程序
Maven版
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
非Maven版
把http://logback.qos.ch/dist/logback-1.1.2.zip下載下來之后,在其根目錄下有logback-core-1.1.2.jar和logback-classic-1.1.2.jar這倆個Jar,在logback-examples\lib下有slf4j-api-1.7.6.jar這個jar,把這三個Jar添加到你的代碼包路徑中。
2.3.2 非獨立運行程序
如果你做的是一個Lib或者API,那么你就不應該依賴于具體的slf4j實現。所以你對logback的依賴應該是在運行測試代碼的時候,具體實現方式如下文所示:
Maven版
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
非Maven版
在發布的時候不要把只有Logback才用到jar打包進你的發布程序里面。(如果覺得繞口再多讀兩遍)
2.4 與遺留Logging框架兼容
目前行業除了Logback之外,廣泛使用的還有其他四種Logging框架:
- Log4j 1 (http://logging.apache.org/log4j/1.2/)
- Log4j 2 (http://logging.apache.org/log4j/2.x/)
- java.util.logging (http://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html)
- Apache commons Logging (http://commons.apache.org/proper/commons-logging/)
Log4j 2因為是剛出來的,目前SLF4J對其的兼容性還未知,對于其他的三種框架,SLF4J都提供了兼容性的支持。下面介紹了如何讓Logbak兼容這些框架,另外,也可以閱讀官方說明:http://www.slf4j.org/legacy.html
2.4.1 兼容Log4j 1和Apache Commons Logging
SLF4J對于Log4J 1和Apache commons Logging的支持方式是提供了實現Log4j和Apache commons Logging接口的SLF4J實現。使用方式是
- 去取對Log4J和Apache commons Logging的Jar包的引用
- 引入SLF4J的對應接口的實現包。
2.4.1.1 移除引用
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
如何找到哪些第三方包引用了Log4j或者Apache commons Logging呢?有倆個方法:
- 使用 mvn dependency:tree 命令,如下圖所示,可以看出需要在org.springframework.ldap:spring-ldap-core中排除掉對Apache commons Logging的引用。

- 第二種方式是使用Eclipse的m2e Maven插件。如下圖所示,打開pom.xml文件后,選擇Dependency Hierarchy標簽,然后在Filter中輸入logging或者log4j進行過濾,在左側的Dependency Hierarchy中使用右鍵菜單就可以自動過濾了。

2.4.1.2 Maven導入對應的SLF4J實現包
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.6</version>
</dependency>
<!-- Apache commons Logging 的SLF4J實現 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.6</version>
</dependency>
2.4.1.3 非Maven版導入對應的SLF4J實現包
直接刪除掉log4j-1.**.jar和commons-logging-1.**.jar文件,把http://slf4j.org/dist/slf4j-1.7.6.zip下載下來,把壓縮包里的log4j-over-slf4j-1.7.6.jar或者(和)jcl-over-slf4j-1.7.6.jar文件放到classpath中。
2.4.2 兼容java.util.logging
SLF4J的jul-to-slf4j模塊實現了一個java.util.logging handler,該handler會把對java.util.logging的調用都轉化成對SLF4J實現的調用。所以需要以下倆個步驟:
- 導入jul-to-slf4j模塊
- 啟用jul-to-slf4j模塊
2.4.2.1 導入jul-to-slf4j模塊maven版
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.6</version>
</dependency>
2.4.2.2 導入jul-to-slf4j模塊非Maven版
把http://slf4j.org/dist/slf4j-1.7.6.zip下載下來,把壓縮包里的jul-to-slf4j-1.7.6.jar放到classpath中。
2.4.2.3 啟用jul-to-slf4j模塊
在logging.properties中添加如下一行:
2.5 Logback 配置文件簡介
2.5.1 Logback配置文件名稱、位置和編寫策略
Logback 會按照如下的順序在classpath中讀取配置文件,如果讀取到任何一個,則停止繼續尋找。
- logback.groovy 這個是使用groovy語法的配置文件
- logback-test.xml
- logback.xml
- 輸出格式 %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- 輸出方向:System.out
- 輸出級別:Debug
- 在src/test/resources目錄中放置logback-test.xml,該配置文件中log的輸出是到輸出到console,對于本應用的代碼是debug級別,對于其他的是info級別。
- 在src/main/resources目錄中放置logback.xml,該配置文件中log的輸出是輸出到文件中,該文件每日滾動壓縮打包備份,對于本應用的代碼是info級別,對于其他的是warn級別。
- 對于web項目,logback.xml放置到WEB-INF/classes目錄下,配置方式建議參考上面說的
- 對于其他項目,放置到應用啟動運行時的classpath根目錄下
2.5.2 Logback配置文件示例
<configuration scan="true" scanPeriod="30 seconds">
<!--Appendar詳解: http://logback.qos.ch/manual/appenders.html#RollingFileAppender -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 當前Log文件名 -->
<file>ldap-pwd.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 非當天的Log文件壓縮備份為 archive/ldap-pwd.2014-08-10.zip -->
<fileNamePattern>archive/ldap-pwd.%d{yyyy-MM-dd}.zip</fileNamePattern>
<!-- 超過30天的備份文件會被刪除 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!-- 格式說明:http://logback.qos.ch/manual/layouts.html#ClassicPatternLayout -->
<Pattern>%d [%thread] %-5level %40logger{40} - %msg%n</Pattern>
</layout>
</appender>
<logger name="cn.justfly.training.logging" level="info" />
<root level="warn">
<appender-ref ref="FILE" />
</root>
</configuration>
<configuration>
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d [%thread] %-5level %40logger{40} - %msg%n</pattern>
</encoder>
</appender>
<logger name="cn.justfly.training.logging" level="debug" />
<root level="info">
<appender-ref ref="Console" />
</root>
</configuration>