爲什麼不用log4j了呢?
因爲log4j和Logback都是同一個作者(ceki)寫的,他本人說:log4j太爛了,不想再改了。所以寫了一個log4j的升級版本,那就是Logback。我想開發者本人說的,應該夠權威了吧!
怎麼用好Logback(日誌實現)呢?
和SLF4J(日誌門面,和上面兩個框架都是同一個作者寫的)搭配使用,效果更佳!(springboot中用的也是這兩個)
slf4j的簡單使用
slf4j(Simple Logging Facade for Java,4是for的意思)作爲日誌門面,還是很不錯的,舉個例子:
一般我們都要傳入類名對應的class對象給logger,如:
private final Logger log = LoggerFactory.getLogger(LogTest.class);
但是使用@Slf4j註解,程序就可以直接使用log了,還是挺方便的。
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
class RiverApplicationTests {
@Test
void logSomething() {
log.error("Slf4j");//可以直接使用log對象
}
}
說明:使用@Slf4j,需要添加相應的依賴和在idea中安裝lombok插件。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
</dependency>
還有如打印多個變量,也挺方便的:
//{}是佔位符
log.info("userName: {}, password: {}", userName, password);
Logback的使用
可以有兩種配置方式:一種是application.yml(功能簡單),另一種是logback-spring.xml(功能強大)
application.yml配置(輸出格式、輸出路徑和日誌級別等)
logging:
pattern:
console: "%d -- %msg%n" #%d爲日期,%msg爲日誌信息,%n是換行
file:
path: log #配置路徑,如果沒有設置name,默認會生成spring.log文件
#name: log/test.log
level:
root: info #根日誌級別爲info
com.boot.river.RiverApplicationTests: error #特定類的日誌級別爲error
輸出日誌信息的控制符如下:
%c: 輸出日誌信息所屬的類目,通常就是所在類的全名
%L: 輸出代碼中的行號
%F: 輸出日誌消息產生時所在的文件名稱
%m: 輸出代碼中指定的消息,產生的日誌具體信息
%l: 輸出日誌事件的發生位置,相當於%C.%M(%F:%L)的組合,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main (TestLog4.java:10)
%d: 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也可以在其後指定格式,比如:%d{yyyy年MM月dd日 HH:mm:ss},2019年12月26日 22:45:57
%p: 輸出日誌信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL,
%r: 輸出自應用啓動到輸出該log信息耗費的毫秒數
%t: 輸出產生該日誌事件的線程名
%x: 輸出和當前線程相關聯的NDC(嵌套診斷環境),尤其用到像Java servlets這樣的多客戶多線程的應用中。
%%: 輸出一個”%”字符
%n: 輸出一個回車換行符,Windows平臺爲”\r\n”,Unix平臺爲”\n”輸出日誌信息換行
logback-spring.xml配置(error和info信息分開打印、每天一個日誌文件等)
<?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><!--命中error日誌,則不打印-->
<onMismatch>ACCEPT</onMismatch><!--沒命中error日誌,都打印出來-->
</filter>
<encoder>
<pattern>
%msg%n
</pattern>
</encoder>
<!--滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路徑,日期作爲文件名的一部分-->
<fileNamePattern>log/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><!--只打印error級別的日誌,因爲是ThresholdFilter,所以如果是WARN,則會打印WARN和ERROR日誌-->
</filter>
<encoder>
<pattern>
%msg%n
</pattern>
</encoder>
<!--滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路徑,日期作爲文件名的一部分-->
<fileNamePattern>log/error.%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="consoleLog" />
<appender-ref ref="fileInfoLog" />
<appender-ref ref="fileErrorLog" />
</root>
</configuration>
覺得有用的老鐵贊一下唄~