日志可以記錄我們應用程序的運行情況,我們可以通過日志信息去獲取應用程序更多的信息。常用處理java日志的組件有:slf4j、log4j、logback、common-logging等。其中log4j是使用得最多的日志組件。
而LogBack是基於Log4j基礎上大量改良的一種日志框架,但是它不能單獨使用,推薦配合日志框架SLF4J來使用。
LogBack當前分成三個模塊:logback-core、logback-classic和logback-access;其中logback-core是其它兩個模塊的基礎,就像spring框架里的spring-core一樣。
Logback的核心對象
- Logger:日志記錄器
- Appender:指定日志輸出的目的地,目的地可以是控制台,文件
- Layout:日志布局,指定日志信息的輸出的格式
日志級別
- DEBUG
- INFO
- WARN
- ERROR
DEBUG < INFO < WARN < ERROR
我們一般不會去選擇DEBUG級別,因為DEBUG級別會輸出很多信息,包括一些無用的信息。
Log4j轉換到LogBack
因為目前使用得最廣泛的還是Log4j,要想轉換到LogBack,可以使用這個轉換工具。
比方說我們現在有一個log4j.properties文件。
### 設置日志記錄器###
log4j.rootLogger = debug,stdout,D,E
### 輸出信息到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 輸出DEBUG 級別以上的日志到=D://logs/error.log文件里 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = D://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 輸出ERROR 級別以上的日志到=D://logs/error.log文件里 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
使用上面的轉換工具可以快速的將log4j.properties轉換為logback.xml格式的文件。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--輸出到控制台 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<!--encoder即layout布局 -->
<encoder>
<pattern>[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n</pattern>
</encoder>
</appender>
<!--將DEBUG級別的日志輸出到文件 -->
<appender name="D" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Append>true</Append>
<File>D://logs/log.log</File>
<encoder>
<pattern>%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<!--將ERROR級別的日志輸出到文件 -->
<appender name="E" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>E://logs/error.log</File>
<Append>true</Append>
<encoder>
<pattern>%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!--日志記錄器 -->
<root level="debug">
<appender-ref ref="stdout"/>
<appender-ref ref="D"/>
<appender-ref ref="E"/>
</root>
</configuration>
可以看到轉換前后的各個元素是相互對應的。
SpringBoot整合LogBack
SpringBoot官方文檔里面說:
There are a lot of logging frameworks available for Java. Do not worry if the above list seems confusing. Generally, you do not need to change your logging dependencies and the Spring Boot defaults work just fine
大致意思就是,SpringBoot整合了許多的日志框架,你可能不知道的到底應該選用哪個,但是SpringBoot為你考慮了,就用它默認的配置就OK,而它默認使用的就是LogBack。
1.1、日志格式(Log Format)
SpringBoot默認輸出的日志格式是這樣的。
2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
下面從左邊開始依次做說明:
- 日志產生的時間,精確到毫秒
- 日志級別
- PID:進程ID
- 輸出日志的線程名
- 輸出日志的完成類名
- 詳細信息
SpringBoot啟動默認輸出的 [INFO] 級別。
1.2、自定義日志格式
使用Log4j日志框架時,我們創建的是 log4j.properties 文件。現在SpringBoot默認使用的是LogBack框架,官方建議日志配置文件取名為 logback-spring.xml。
下面是隨意寫的一個日志的配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="consoleApp" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n
</pattern>
</layout>
</appender>
<appender name="fileInfoApp" 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>
%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n
</pattern>
</encoder>
<!-- 滾動策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 輸出路徑 -->
<fileNamePattern>app_log/log/app.info.%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="fileErrorApp" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>
%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n
</pattern>
</encoder>
<!-- 設置滾動策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 路徑 -->
<fileNamePattern>app_log/log/app.err.%d.log</fileNamePattern>
<!-- 控制保留的歸檔文件的最大數量,超出數量就刪除舊文件,假設設置每個月滾動, <maxHistory> 是1,則只保存最近1個月的文件,刪除之前的舊文件 -->
<MaxHistory>1</MaxHistory>
</rollingPolicy>
</appender>
<!--注意這個節點要寫在最后 -->
<root level="INFO">
<appender-ref ref="consoleApp"/>
<appender-ref ref="fileInfoApp"/>
<appender-ref ref="fileErrorApp"/>
</root>
</configuration>
< root level="INFO" >
的意思是,SpringBoot會輸出INFO級別以上的日志信息。
下面我們來測試一下。
@RestController
public class LogBackTest {
//注意Logger和LoggerFactory類都是org.slf4j包里的。
private Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/log")
public String testLog(){
logger.debug("this is debug level");
logger.info("this is info level");
logger.error("this is error level");
logger.warn("this is warn level");
return "sussecc";
}
}
訪問localhost:8080/log。控制台輸出了三行自定義的日志:
2018-06-13 16:44:44.648 INFO [http-nio-8080-exec-3]com.example.demo.controller.LogBackTest.testLog:16 -this is info level
2018-06-13 16:44:44.649 ERROR[http-nio-8080-exec-3]com.example.demo.controller.LogBackTest.testLog:17 -this is error level
2018-06-13 16:44:44.651 WARN [http-nio-8080-exec-3]com.example.demo.controller.LogBackTest.testLog:18 -this is warn level
沒有DEBUG級別的日志,是因為在日志配置文件中我們設置的是< root level="INFO" >
。
下面看日志信息輸出到文件里的情況:
在app.err.2018-06-13.log文件中只有ERROR級別的信息,這是因為這個文件對應的appender中我們使用的的Filter是ch.qos.logback.classic.filter.ThresholdFilter
其中<level>ERROR</level>
,意思是只接收ERROR級別的日志信息寫入。
在app.info.2018-06-13.log文件中只有INFO和WARN級別的信息,這是因為雖然在文件對應的appender中我們使用的Filter是ch.qos.logback.classic.filter.LevelFilter
,其中過濾規則是:
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
意思是只接收除了ERROR級別外的日志文件。當然不包括DEBUG級別,因為我們一開始在<root>
節點里就沒有讓DEBUG級別的日志信息輸出。
以上就是SpringBoot里使用LogBack的大致思路,更多的資料可以查閱SpringBoot的官方文檔。