寫java也有一段時間了,一直都有用slf4j log4j輸出日誌的習慣。可是始終都是抱着「拿來主義」的態度,複製粘貼下配置文件就開始編碼了,因而這段時間詳細的看了下日誌庫。html
籠統的講就是slf4j是一系列的日誌接口,而log4j logback是具體實現了的日誌框架。接下來咱們跟着官方文檔詳細的來看一下他們的關係。java
The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks, such as java.util.logging, logback and log4j. SLF4J allows the end-user to plug in the desired logging framework at deployment time. Note that SLF4J-enabling your library/application implies the addition of only a single mandatory dependency, namely slf4j-api-1.7.21.jar.數據庫
官方文檔的這一段話已經明確描述了三者的關係。slf4j譯爲簡單日誌門面,是日誌框架的抽象。而log4j和logback是衆多日誌框架中的幾種。apache
這裏寫了幾行簡單的代碼來驗證一下。api
public class Program { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(Program.class); logger.info("hello world"); } }
從運行結果能夠看到,因爲沒有給出具體的logger實現,沒法在控制檯輸出日誌。也就是說咱們在具體開發中,須要綁定一個日誌框架,才能正常的使用slf4j。app
而log4j和logback就是兩個受歡迎的日誌框架。但二者又有不一樣。框架
上圖能夠看到應用程序對日誌框架的調用關係。應用程序調用slf4j api,而日誌的輸出最終是由底層的日誌框架來實現的。這張圖也提現了log4j和logback的不一樣。maven
官方文檔對logback的描述ide
NATIVE IMPLEMENTATION There are also SLF4J bindings external to the SLF4J project, e.g. logback which implements SLF4J natively. Logback's ch.qos.logback.classic.Logger class is a direct implementation of SLF4J's org.slf4j.Logger interface. Thus, using SLF4J in conjunction with logback involves strictly zero memory and computational overhead.性能
能夠看到logback是直接實現了slf4j的接口,是不消耗內存和計算開銷的。而log4j不是對slf4j的原生實現,因此slf4j api在調用log4j時須要一個適配層。
總結:
顯然這裏咱們不推薦單獨使用日誌框架。假設項目中已經使用了log4j,而咱們此時加載了一個類庫,而這個類庫依賴另外一個日誌框架。這個時候咱們就須要維護兩個日誌框架,這是一個很是麻煩的事情。而使用了slf4j就不一樣了,因爲應用調用的抽象層的api,與底層日誌框架是無關的,所以能夠任意更換日誌框架。
做爲log4j的開發者,對log4j必定不陌生,他是apache的一個開源日誌框架。而logback相對於log4j來講,更新一點,是由log4j的做者設計實現的,第一個版本是2011推出的。不管從設計上仍是實現上,Logback相對log4j而言有了相對多的改進。可是二者的用法幾乎差異不大。下面是logback的優點:
以上,從性能的角度,能夠儘快從log4j遷移到logback上來。
因爲如今log4j使用的還比較多,因此介紹下他的基本用法。
這裏咱們使用的IntelliJ IDEA2016.1和maven。
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency>
此時會自動添加三個jar包。
log4j的正常運行須要配置文件,配置文件類型:log4j配置文件能夠是log4j.xml也能夠是log4j.properties。須要爲其配置root、appender、layout等信息。
雖然網上大多數教程都是用log4j.properties來配置的(鍵值對),可是我我的以爲用xml配置,節點更清晰,並且在idea下有代碼提示,能夠下降配置錯誤的機率。下面我就就不具體講配置文件了,只提幾個關鍵的地方。
FATAL ERROR WARN INFO DEBUG
下面給出配置文件。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <!--若干個appender的定義--> <!--org.apache.log4j.ConsoleAppender 輸出到控制檯--> <appender name="myConsole" class="org.apache.log4j.ConsoleAppender"> <!--輸出格式--> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/> </layout> </appender> <!--org.apache.log4j.DailyRollingFileAppender 天天產生一個日誌文件--> <appender name="myFile" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="output.log"/><!--文件位置--> <param name="Append" value="true"/><!--是否選擇追加--> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/> </layout> </appender> <!--org.apache.log4j.RollingFileAppender 滾動日誌文件輸出 文件大小到達必定尺寸時從新產生新的文件--> <!--<appender name="myFile" class="org.apache.log4j.RollingFileAppender"> <param name="File" value="D:/output.log" /> <param name="Append" value="true" /> <param name="MaxFileSize" value="500KB"/> <param name="MaxBackupIndex" value="10" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%p (%c:%L)- %m%n" /> </layout> </appender>--> <!--將各個包中的類日誌輸出到不一樣的日誌文件中 這樣能夠便於日誌的分類。 能夠經過這個設置,把業務邏輯的日誌添加到數據庫。起到過濾的做用 --> <!--這段配置的就是說把包名爲「com.zjut.a1」且優先級爲debug的日誌經過myFile這個appender來處理。 --> <category name="com.zjut.a1"> <priority value="debug"/> <appender-ref ref="myFile"/> </category> <!-- 根logger的設置--> <root> <!--優先級設置,假設設置爲「info」,則沒法輸出debug級別的日誌--> <priority value="debug"/> <!--<priority value="info"/>--> <!--<priority value="warn"/>--> <!--<priority value="error"/>--> <!--<priority value="fatal"/>--> <!--添加剛纔設置的appender--> <appender-ref ref="myConsole"/> <appender-ref ref="myFile"/> </root> </log4j:configuration>
控制檯輸出日誌的配置文件(複製能夠直接用)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <appender name="myConsole" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/> </layout> </appender> <root> <priority value="debug"/> <appender-ref ref="myConsole"/> </root> </log4j:configuration>
配置文件詳解,能夠參考:http://zengxiantao.iteye.com/blog/1881700
// 類名.class Logger logger = LoggerFactory.getLogger(Program.class); // 輸出字符串 logger.debug("this is a debug msg"); // 佔位符 logger.debug("hi,welcome {},today is {}","admin","Sunday");
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> </dependency>
網上教程添加了不少,其實只要添加這一個,其餘的依賴jar都會被下載下來。
配置文件幾乎和log4j差很少,以下。選擇須要的appender就能夠了。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern> </encoder> </appender> <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under the key "bySecond" into the logger context. This value will be available to all subsequent configuration elements. --> <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>testFile-${bySecond}.log</file> <append>true</append> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="DAYFILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logFile.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- daily rollover --> <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- keep 30 days' worth of history capped at 3GB total size --> <maxHistory>30</maxHistory> <totalSizeCap>3GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT"/> <appender-ref ref="DAYFILE"/> <appender-ref ref="FILE"/> </root> </configuration>
詳細配置文件,能夠參考http://logback.qos.ch/manual/index.html
雖然是英文的,可是寫的已是很是清楚了。
同爲slf4j的api,代碼相同。
// 類名.class Logger logger = LoggerFactory.getLogger(Program.class); // 輸出字符串 logger.debug("this is a debug msg"); // 佔位符 logger.debug("hi,welcome {},today is {}","admin","Sunday");