日誌:slf4j+logback 的配置與使用
阿新 • • 發佈:2019-01-29
1. 常用日誌元件和選擇
java開發日誌處理是發現和除錯bug所 必不可少的,那麼現在企業中常用的日誌元件有哪些呢,JCL 、 JUL、 SLF4j、Log4j、 Log4j2 、 Logback、 jboss-loggin 等,一般日誌是配套出現的,一般是由 一個日誌門面 和 一個日誌實現 配套使用, 那麼 組成以下結構 日誌門面 日誌實現 JCL log4j SLF4j log4j2 jboss-loggin logback JUL 那麼,下面開始 一個個排除 JUL:實現簡陋,很多地方受到開發者的吐槽,所以 首先排除 jboss-loggin:自誕生之初,就不是為了服務大眾,不受到什麼青睞,所以 也排除 log4j:log4j雖然聲名顯赫,但是在這裡 首先要知道一點 slf4j 、log4j、logback 這三個框架都是同一個作者ceki 開發的,作者說 log4j 太爛,不想修改了,因此開發了 升級版的 log4j,也就是 logback ,因此在這裡 我們劃掉 log4j log4j2:log4j2不是log4j的升級版,而是apache開發的,log4j2 該框架很優秀,正是因為太優秀,設計時與 部分框架對其支援的程度有限,不一定會什麼時候踩坑,而log4j2在設計時的效能是優於logback的,但是 99%的開發者不會有機會體會到這種差距,因為 logback也很優秀,足夠我們日常開發,所以我們劃掉 log4j2 JCL:劃掉JCL 主要是因為 日誌實現上我們選擇了 logback,而 logback和slf4j 畢竟是同一個作者寫的,親生的,合得來,而且在springboot 中 ,也是使用的 slf4j + logback,所以我們劃掉了 JCL 因此,最後剩下的就是我們 這篇部落格的 內容了 ,如何配置和使用 SLF4j + logback2. 日誌的使用
在這裡 ,我們需要在每個類中 建立一個 Logger物件,並且使用 當前類的類名來建立,那麼 這個類名存在的意義在哪裡?我們可以先執行 第一個測試,看下結果package com.lonely; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * Created by 15072 on 2018/1/6. */ @RunWith(SpringRunner.class) @SpringBootTest public class LoggerTest { private static Logger logger = LoggerFactory.getLogger(LoggerTest.class); @Test public void testLogger(){ logger.debug("debug:...."); logger.info("info..."); logger.error("error..."); } }
由上圖可知,我們的類名在 日誌中 是為了方便我們找到異常是在哪個類中,進行鎖定,不信的話,我們可以在新建一個測試類, LoggerTest2,裡面什麼都不寫, 然後將 LoggerFactory.getLogger(LoggerTest2.class); ,我們可以在測試一次,看看結果
因此,使用類名建立的logger 的作用就是在這裡,但是如果我們需要在每個類中都這樣的建立一個logger物件,不方便,因此可以通過 一個註解來幫我們實現 那就是 @Slf4j ,該註解就可以幫我們自動建立一個 log物件 但是 如果使用 @Slf4j 註解 需要兩點, 2.新增 lombok的依賴
測試一下,編寫測試方法
@Test
public void testSl4j(){
log.debug("sl4j.debug...");
log.info("sl4j.info");
log.error("sl4j.error");
}
這裡的日誌輸出格式 是預設的,我們可以通過的教程 來配置 日誌輸出配置
3. 日誌的配置
日誌可以通過兩種方法配置,一種是 application.yml配置,一種是 lobback-spring.xml配置 3.1 application.yml配置,這種配置方法 配置項較少,一般有以下屬性配置 1. 配置輸出格式 為 時間 - 訊息 換行logging:
pattern:
console: "%d - %msg%n"
2. 配置日誌輸出位置 比如磁碟 e盤
logging:
pattern:
console: "%d - %msg%n"
path: e:/
執行後,我們可以看到 在 e盤下生成了一個檔案 spring.log 這檔案是spring生成3. 配置日誌輸出檔案 ,這樣可以指定日誌輸出到哪個位置
logging:
pattern:
console: "%d - %msg%n"
path: e:/
file: e:/sell.log
我們可以看到 在e盤下生成了以下檔案
這裡注意:我們可以配置日誌儲存位置,以及具體輸出的檔案,如果同時配置的話,會使用我們指定的file為主,可以測 試,看e盤下具體生成什麼檔案 4. 配置日誌 輸出級別 日誌一般主要看重的有5個級別,優先順序如 DEBUG<INFO<WARN<ERROR<FATAL等,而springboot預設配置 是 INFO級別,所以 我們測試程式碼中寫了三行,在結果中我們只看到了 info 和 error的 因為 debug優先順序比info低,所以我們 看不到。那麼我們配置一下格式 logging.level.包名或類名: 級別 即可, 舉例如下
logging:
pattern:
console: "%d - %msg%n"
#path: e:/
file: e:/sell.log
level:
#這裡可以是包名也可以是類名
com.lonely: debug
執行後,我們可以看到 原來只能看到 info 和 error 的,現在的debug也可以看到
3.2 lobback-spring.xml 配置
1. 我們先把 application.yml的關於日誌的註釋掉,新建一個檔案 logback-spring.xml,為什麼要取這個名字呢,Spring Boot官方推薦優先使用帶有-spring的檔名作為你的日誌配置(如使用logback-spring.xml,而不是logback.xml),如果我們想自定義名字,也可以,可以在 application.yml中通過 logging.config=classpath:/xxx.xml等方式配置。 2. 注意幾個 xml節點的含義 appender:配置項,規則,通過這個節點內容配置,我們可以配置輸出位置(控制檯,檔案),輸出格式等 root:根節點,表明整個專案基本的日誌級別,裡面可以應用多個appender規則 demo如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d -- %msg%n</pattern>
</layout>
</appender>
<root level="info">
<appender-ref ref="consoleLog" />
</root>
</configuration>
在上面的 logback-spring.xml中,appender配置了一個規則, ConsoleAppender表明日誌輸出到控制檯,layout表明輸出格式,root節點配置表明該專案基礎的日誌級別為info,引入 控制檯輸出的規則,那麼我們執行看結果
從結果上來看,配置的是 info級別,所以 debug的沒有輸出,現在如果我想把日誌輸出到檔案怎麼處理呢,可以使用如下配置,新增一個 appender規則,由於日誌可能比較多,一般是按照日期來輸出日誌,因此如下配置了每天一個日誌到指定位置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d -- %msg%n</pattern>
</layout>
</appender>
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d -- %msg%n</pattern>
</encoder>
<!--滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路徑-->
<fileNamePattern>e:/info-%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="consoleLog" />
<appender-ref ref="fileInfoLog"/>
</root>
</configuration>
3. 如果我們想 把 info 的日誌 和 error的日誌區分到兩個檔案放置,該怎麼寫呢?
我們現在 在新建一個規則,結構如上圖,只是在裡面添加了一個過濾器,使用的是範圍過濾,也就是攔截Error級別的資訊,demo如下
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d -- %msg%n</pattern>
</layout>
</appender>
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d -- %msg%n</pattern>
</encoder>
<!--滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路徑-->
<fileNamePattern>e:/info-%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--新增 範圍 過濾-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>%d -- %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>e:/error-%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="consoleLog" />
<appender-ref ref="fileInfoLog"/>
<appender-ref ref="fileErrorLog"/>
</root>
</configuration>
執行後,我們可以在 e盤下的 error.log中看到 裡面只有一條記錄,關於error的記錄,但是我們在info的那個檔案中,依舊有info和error的資訊,那麼如果將info提取出來呢? 能不能也想這樣新增一個過濾器呢,測試一下,經過測試我們發現沒有作用,因為攔截info,error還是會顯示,因為error的優先順序高,那麼我們可以利用如下方法來處理,demo如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d -- %msg%n</pattern>
</layout>
</appender>
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--要攔截的日誌級別-->
<level>ERROR</level>
<!--如果匹配,則禁止-->
<onMatch>DENY</onMatch>
<!--如果不匹配,則允許記錄-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>%d -- %msg%n</pattern>
</encoder>
<!--滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路徑-->
<fileNamePattern>e:/info-%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--新增 範圍 過濾-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>%d -- %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>e:/error-%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="consoleLog" />
<appender-ref ref="fileInfoLog"/>
<appender-ref ref="fileErrorLog"/>
</root>
</configuration>
執行後,發現確實實現了 info 和 error的日誌分開,但是 在上圖例子中,雖然我們排除了 error,但是除開info,如果我們還有 warn級別的日誌資訊,還是會輸出在 info.log檔案中,因為warn優先順序比info高,但是我們只是攔截了error而已。
以上就是 關於 slf4j日誌的總結,邊學邊敲邊分享~