java 日志框架總結


在項目開發過程中,我們可以通過 debug 查找問題。而在線上環境我們查找問題只能通過打印日志的方式查找問題。因此對於一個項目而言,日志記錄是一個非常重要的問題。因此,如何選擇一個合適的日志記錄框架也非常重要。

在Java開發中,常用的日志記錄框架有JDKLog、Log4J、LogBack、SLF4J、SLF4J。這些日志記錄框架各有各的特點,各有各的應用場景。了解這些框架的特點及應用場景,有利於我們做技術選型的時候做出正確的判斷。

JDKLog:日志小刀

JDKLog是JDK官方提供的一個記錄日志的方式,直接在JDK中就可以使用。

import java.util.logging.Logger; /**** ** JDKLog Demo **/ public class JDKLog { public static void main( String[] args ) { Logger logger = Logger.getLogger("JDKLog"); logger.info("Hello World."); } }

JDKLog 的有點是使用非常簡單,直接在 JDK 中就可以使用。但 JDKLog 功能比較太過於簡單,不支持占位符顯示,拓展性比較差,所以現在用的人也很少。

Log4J:日志大炮

Log4J 是 Apache 的一個日志開源框架,有多個分級(DEBUG/INFO/WARN/ERROR)記錄級別,可以很好地將不同日志級別的日志分開記錄,極大地方便了日志的查看。

Log4J 有 1.X 版本和 2.X 版本,現在官方推薦使用 2.X 版本,2.X 版本在架構上進行了一些升級,配置文件也發生了一些變化。但好在官方的配置說明文檔非常清楚,通過查閱文檔能解決大部分的問題。

使用 Log4J 框架首先需要引入依賴的包:

<!-- Log4J --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.6.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.6.2</version> </dependency>

增加配置文件 log4j2.xml 放在 resource 目錄下:

<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>

其中節點的 level 屬性表示輸出的最低級別。

最后編寫一個測試類:

import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /**** ** Log4J Demo **/ public class Log4jLog { public static void main(String args[]) { Logger logger = LogManager.getLogger(Log4jLog.class); logger.debug("Debug Level"); logger.info("Info Level"); logger.warn("Warn Level"); logger.error("Error Level"); } }

運行測試類輸出結果:

10:16:08.279 [main] INFO com.chanshuyi.Log4jLog - Info Level 10:16:08.280 [main] WARN com.chanshuyi.Log4jLog - Warn Level 10:16:08.280 [main] ERROR com.chanshuyi.Log4jLog - Error Level

如果沒有配置 log4j2.xml 配置文件,那么LOG4J將自動啟用類似於下面的的配置文件:

<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>

使用默認配置文件的輸出結果:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. 11:40:07.377 [main] ERROR com.chanshuyi.Log4jLog - Error Level

從上面的使用步驟可以看出 Log4J 的使用稍微復雜一些,但是條理還是很清晰的。而且因為 Log4J 有多個分級(DEBUG/INFO/WARN/ERROR)記錄級別,所以可以很好地記錄不同業務問題。因為這些優點,所以在幾年前幾乎所有人都使用 Log4J 作為日志記錄框架,群眾基礎可謂非常深厚。

但 Log4J 本身也存在一些缺點,比如不支持使用占位符,不利於代碼閱讀等缺點。但是相比起 JDKLog,Log4J 可以說是非常好的日志記錄框架了。

LogBack:日志火箭

LogBack 其實可以說是 Log4J 的進化版,因為它們兩個都是同一個人(Ceki Gülcü)設計的開源日志組件。LogBack 除了具備 Log4j 的所有優點之外,還解決了 Log4J 不能使用占位符的問題。

使用 LogBack 需要首先引入依賴:

<!-- LogBack --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> </dependency>

配置 logback.xml 配置文件:

<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern> </layout> </appender> <logger name="com.chanshuyi" level="TRACE"/> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>

LogBack 的日志級別區分可以細分到類或者包,這樣就可以使日志記錄變得更加靈活。之后在類文件中引入Logger類,並進行日志記錄:

import org.slf4j.Logger; import org.slf4j.LoggerFactory; /**** ** LogBack Demo **/ public class LogBack { static final Logger logger = LoggerFactory.getLogger(LogBack.class); public static void main(String[] args) { logger.trace("Trace Level."); logger.debug("Debug Level."); logger.info("Info Level."); logger.warn("Warn Level."); logger.error("Error Level."); } }

輸出結果:

14:34:45.747 [main] TRACE com.chanshuyi.LogBack - Trace Level. 14:34:45.749 [main] DEBUG com.chanshuyi.LogBack - Debug Level. 14:34:45.749 [main] INFO com.chanshuyi.LogBack - Info Level. 14:34:45.749 [main] WARN com.chanshuyi.LogBack - Warn Level. 14:34:45.749 [main] ERROR com.chanshuyi.LogBack - Error Level.

LogBack 解決了 Log4J 不能使用占位符的問題,這使得閱讀日志代碼非常方便。除此之外,LogBack 比 Log4J 有更快的運行速度,更好的內部實現。並且 LogBack 內部集成了 SLF4J 可以更原生地實現一些日志記錄的實現。

SLF4J:適配器

上面說了 JDKLog、Log4J、LogBack 這幾個常用的日志記錄框架,它們都有各自的優缺點,適合在不同的場景下使用。可能簡單的項目直接用 JDKLog 就可以了,而復雜的項目需要用上 Log4J。

很多時候我們做項目都是從簡單到復雜,也就是我們很可能一開始使用的是 JDKLog,之后業務復雜了需要使用 Log4J,這時候我們如何將原來寫好的日志用新的日志框架輸出呢?

一個最死板的方法就是一行行代碼修改,把之前用 JDKLog 的日志代碼全部修改成 Log4J 的日志接口。但是這種方式不僅效率低下,而且做的工作都是重復性的工作,這怎么能忍呢。

正式因為在實際的項目應用中,有時候可能會從一個日志框架切換到另外一個日志框架的需求,這時候往往需要在代碼上進行很大的改動。為了避免切換日志組件時要改動代碼,這時候一個叫做 SLF4J(Simple Logging Facade for Java,即Java簡單日志記錄接口集)的東西出現了。

SLF4J(Simple Logging Facade for Java,即Java簡單日志記錄接口集)是一個日志的接口規范,它對用戶提供了統一的日志接口,屏蔽了不同日志組件的差異。這樣我們在編寫代碼的時候只需要看 SLF4J 這個接口文檔即可,不需要去理會不同日之框架的區別。而當我們需要更換日志組件的時候,我們只需要更換一個具體的日志組件Jar包就可以了。

而整合 SLF4J 和日志框架使用也是一件很簡單的事情。

SLF4J+JDKLog

SLF4J + JDKLog 需要在 Maven 中導入以下依賴包:

<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.21</version> </dependency>

編寫測試類:

import org.slf4j.Logger; import org.slf4j.LoggerFactory; /**** ** SLF4J + JDKLog **/ public class Slf4jJDKLog { final static Logger logger = LoggerFactory.getLogger(Slf4jJDKLog.class); public static void main(String[] args) { logger.trace("Trace Level."); logger.info("Info Level."); logger.warn("Warn Level."); logger.error("Error Level."); } }

輸出結果:

七月 15, 2016 3:30:02 下午 com.chanshuyi.slf4j.Slf4jJDKLog main 信息: Info Level. 七月 15, 2016 3:30:02 下午 com.chanshuyi.slf4j.Slf4jJDKLog main 警告: Warn Level. 七月 15, 2016 3:30:02 下午 com.chanshuyi.slf4j.Slf4jJDKLog main 嚴重: Error Level.

SLF4J+LOG4J

需要依賴的 Jar 包:slf4j-api.jar、slf4j-412.jar、log4j.jar,導入Maven依賴:

<!-- 2.SLF4J + Log4J --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>

配置 log4j.xml 文件:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' > <appender name="myConsole" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n" /> </layout> <!--過濾器設置輸出的級別--> <filter class="org.apache.log4j.varia.LevelRangeFilter"> <param name="levelMin" value="debug" /> <param name="levelMax" value="error" /> <param name="AcceptOnMatch" value="true" /> </filter> </appender> <!-- 根logger的設置--> <root> <priority value ="debug"/> <appender-ref ref="myConsole"/> </root> </log4j:configuration>

我們還是用上面的代碼,無需做改變,運行結果為:

[15 16:04:06,371 DEBUG] [main] slf4j.SLF4JLog - Debug Level. [15 16:04:06,371 INFO ] [main] slf4j.SLF4JLog - Info Level. [15 16:04:06,371 WARN ] [main] slf4j.SLF4JLog - Warn Level. [15 16:04:06,371 ERROR] [main] slf4j.SLF4JLog - Error Level.

SLF4J+LogBack

導入依賴:

<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.7</version> </dependency>

配置 logback.xml 文件:

<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern> </layout> </appender> <logger name="com.chanshuyi" level="TRACE"/> <root level="warn"> <appender-ref ref="STDOUT" /> </root> </configuration>

我們還是用上面的代碼,無需做改變,運行結果為:

16:08:01.040 [main] TRACE com.chanshuyi.slf4j.SLF4JLog - Trace Level. 16:08:01.042 [main] DEBUG com.chanshuyi.slf4j.SLF4JLog - Debug Level. 16:08:01.043 [main] INFO com.chanshuyi.slf4j.SLF4JLog - Info Level. 16:08:01.043 [main] WARN com.chanshuyi.slf4j.SLF4JLog - Warn Level. 16:08:01.043 [main] ERROR com.chanshuyi.slf4j.SLF4JLog - Error Level.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM