Spring?Boot日志SLF4J和Logback示例詳解
日志的分類
SpringBoot中的日志庫分為兩種:
- 實(shí)現(xiàn)庫:提供具體的日志實(shí)現(xiàn),例如日志級(jí)別的控制、打印格式、輸出目標(biāo)等。
- 外觀庫:自身不提供日志實(shí)現(xiàn),而是對其他日志庫進(jìn)行封裝,從而方便使用?;谕庥^模式實(shí)現(xiàn)。
關(guān)于外觀庫的出現(xiàn),可設(shè)想一下:現(xiàn)在有多種日志庫,每一種接口都不同。于是我們在不同項(xiàng)目中往往需要調(diào)用不同的API。于是希望,無論哪一種日志庫,我們都在外面套一層殼,使用時(shí)調(diào)用這層殼的接口,這樣就統(tǒng)一了。這層殼就是外觀庫。
對于這兩種庫,常見的有:
- 實(shí)現(xiàn)庫:
Log4j
、Log4j2
、Logback
- 外觀庫:
Slf4j
、Apache Commons Logging
通常只需要引入Slf4j
依賴,然后通過Slf4j
來調(diào)用Logback
或Log4j
。
對應(yīng)地,配置文件除了對Slf4j
進(jìn)行配置,也可以對Logback
或Log4j
進(jìn)行配置。
Logback相比于Log4j,性能提高了10倍以上的性能,占用的內(nèi)存也變小了,并且文檔十分詳細(xì)。推薦使用Slf4j
+Logback
。
官網(wǎng):
官方文檔:
Slf4j
、Logback
和Log4j
是同一個(gè)作者,使用了相同的設(shè)計(jì),因此Slf4j
直接可調(diào)用Logback
和Log4j
。而對于其他日志實(shí)現(xiàn)庫,例如java.util.logging
等,需要使用一個(gè)適配器模塊來將Apache Commons Logging
的接口轉(zhuǎn)換為Slf4j
的可調(diào)用接口。
Spring Boot日志
依賴
Spring Boot
默認(rèn)使用Logback
。只需要引入spring-boot-starter
或spring-boot-starter-web
就會(huì)默認(rèn)包含,不需要再單獨(dú)引入。lombok
中默認(rèn)包含了Slf4j
,因此只要引入了lombok
就無需再單獨(dú)引入Slf4j
:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency>
日志對象
要打印,就要先獲取日志對象。
通常地,使用Slf4j
包中的LoggerFactory
來得到日志對象,然后打印:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LoggerController { // 得到日志對象 private Logger logger = LoggerFactory.getLogger(LoggerController.class); @RequestMapping("/logger") public String logger() { // 日志打印 logger.trace("日志級(jí)別: trace"); logger.debug("日志級(jí)別: debug"); logger.info("日志級(jí)別: info"); logger.warn("日志級(jí)別: warn"); logger.error("日志級(jí)別: error"); return "logger"; } }
如果項(xiàng)目中引入了lombok
組件,則可在類前添加@Slf4j
注解,這樣就可在類中直接使用log
日志對象,而無需通過LoggerFactory
來獲取。
import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j // 通過lombok的`@Slf4j`得到日志實(shí)例 public class LoggerController { @RequestMapping("/logger") public String logger() { // 日志打印 log.trace("日志級(jí)別: trace"); log.debug("日志級(jí)別: debug"); log.info("日志級(jí)別: info"); log.warn("日志級(jí)別: warn"); log.error("日志級(jí)別: error"); return "logger"; } }
日志級(jí)別及配置
日志級(jí)別
日志有8個(gè)級(jí)別:
- ALL: 開啟所有日志
- TRACE: 追蹤,程序每次執(zhí)行一步都輸出。級(jí)別較低,通常不會(huì)使用
- DEBUG: 調(diào)試日志,細(xì)粒度
- INFO: 普通日志,粗粒度
- WARN: 警告日志
- ERROR: 錯(cuò)誤日志,但不影響系統(tǒng)同運(yùn)行
- FATAL: 嚴(yán)重錯(cuò)誤日志,會(huì)導(dǎo)致系統(tǒng)退出
- OFF: 關(guān)閉所有日志
對于這8個(gè)級(jí)別,級(jí)別依次遞增。級(jí)別越高,打印的日志越少。
通常地,只使用TRACE
、DEBUG
、INFO
、WARN
、ERROR
這5個(gè)等級(jí)。
Spring Boot會(huì)打印指定級(jí)別及更高級(jí)的日志。
例如日志設(shè)置為INFO
級(jí),那么Spring Boot會(huì)打印INFO
、WARN
、ERROR
。
配置文件
logback的配置可在application.yml和xml中配置,其中xml配置更加靈活。
若多個(gè)配置同時(shí)存在,則其加載順序?yàn)椋?br />logback.xml → application.yml → logback-spring.xml
后加載的會(huì)覆蓋先加載的。因此application.yml會(huì)覆蓋logback.xml中的相同配置。即后加載的優(yōu)先級(jí)更高。
同理,若要使用 application.yml 中定義的變量,應(yīng)使用 logback-spring.xml 。官方推薦使用 logback-spring.xml 。
logback.xml
加載logback.xml時(shí),默認(rèn)會(huì)在classpath
查找以下文件: 用戶自定義xml > logback-test.xml > logback.groovy > logback.xml 。
如果上述4個(gè)配置文件都不存在,那么logback會(huì)調(diào)用BasicConfigurator
來創(chuàng)建一個(gè)最小化配置將日志輸出到控制臺(tái)。最小化配置會(huì)構(gòu)造一個(gè)父為<ROOT>
的<ConsoleAppender>
,PatternLayoutEncoder
為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
。
其中用戶自定義xml
是在application.yml中通過logging.config=classpath:logging-config.xml
配置的。
yml配置
logging: config: classpath:logback.xml # 自定義配置文件 pattern: file: "%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15} - %msg %n)" # 文件輸出 console: "%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15} - %msg %n)" # 控制臺(tái)輸出 file: name: E:\logs\test.log # 日志文件輸出路徑 level: root: INFO # root輸出級(jí)別 com.spring: WARN # 特定包的輸出級(jí)別
xml結(jié)構(gòu)
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> </appender> <appender name="ROLLING" class="ch.qos.logback.core.RollingFileAppender"> </appender> <root></root> <logger></logger> </configuration>
注意區(qū)分屬性和配置的區(qū)別:
- 屬性:標(biāo)簽自身的屬性,直接寫在標(biāo)簽標(biāo)簽內(nèi),例如
<appender name ="CONSOLE">,
name就是
`標(biāo)簽的屬性。 - 配置:標(biāo)簽的功能設(shè)置,使用子標(biāo)簽進(jìn)行配置,例如
<appender><file>testFile.log</file></appender>
,<file>
就是<appender>
標(biāo)簽的配置。
最外層標(biāo)簽<configuration>
<configuration>
是最外層的標(biāo)簽,所有其他標(biāo)簽都要定義在該標(biāo)簽內(nèi)。<configuration>
可設(shè)置多個(gè)屬性:
- scan: 啟用掃描。默認(rèn)為true。當(dāng)為true時(shí),若配置文件發(fā)生變更,將會(huì)被重新加載。
- scanPeriod: 配置文件掃描時(shí)間間隔。默認(rèn)單位是毫秒,可修改。當(dāng)scan為true時(shí),此屬性生效。默認(rèn)時(shí)間間隔為1分鐘。
- debug: 默認(rèn)為false。若設(shè)為true,將實(shí)時(shí)打印出logback內(nèi)部日志信息。
例如:
<configuration scan="false" scanPeriod="60 seconds" debug="false">
<contextName>上下文名稱
為了避免同一服務(wù)器上多個(gè)web應(yīng)用的logger產(chǎn)生上下文沖突,可使用<contextName>
標(biāo)簽設(shè)置上下文的名稱,確保每個(gè)xml的<contextName>
唯一即可。
例如:
<contextName>Test</contextName>
<appender>標(biāo)簽
<appender>
標(biāo)簽負(fù)責(zé)寫日志。定義了日志的輸出位置、觸發(fā)策略、格式等。注意只負(fù)責(zé)寫,不負(fù)責(zé)日志等級(jí)。
一個(gè)<appender>
標(biāo)簽負(fù)責(zé)一種日志。由于一個(gè)系統(tǒng)中往往包含多種日志,因此通常同時(shí)使用多個(gè)<appender>
標(biāo)簽。<appender>
包含2個(gè)屬性:
name
: 指定<appender>
的名稱,可自定義。需在root
標(biāo)簽中引用。class
: 指定所使用實(shí)現(xiàn)庫中Appender
類的含路徑名稱。
關(guān)于class
,有以下幾個(gè)常用取值:
ch.qos.logback.core.ConsoleAppender
: 輸出到控制臺(tái)。ch.qos.logback.core.FileAppender
: 輸出到靜態(tài)記錄文件。ch.qos.logback.core.rolling.RollingFileAppender
: 輸出到滾動(dòng)日志文件。ConsoleAppender
ConsoleAppender
最為簡單,直接輸出到控制臺(tái)。通常用于開發(fā)調(diào)試。ConsoleAppender
常用的設(shè)置為:
<encoder>
: 對記錄事件進(jìn)行格式化。
例如:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>console %d %p - %m%n</pattern> </encoder> </appender>
FileAppender
FileAppender
會(huì)將所有的日志信息都寫入到一個(gè)文件中。因此若append
屬性為true
,則日志文件會(huì)越來越大。FileAppender
常用的設(shè)置為:
<file>
: 文件名。無默認(rèn)值,必須設(shè)置。其路徑可以為絕對或相對。若上級(jí)目錄不存在則會(huì)自動(dòng)創(chuàng)建。<append>
: 是否開啟追加。默認(rèn)為true。若為true
,則新的日志會(huì)追加到文件末尾;若為false
,則寫新日志前會(huì)清空日志文件。<encoder>
: 對記錄事件進(jìn)行格式化。<prudent>
: 是否安全寫入文件。默認(rèn)為false。效率低。
例如:
<appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>testFile.log</file> <append>true</append> <encoder> <pattern>%d %p - %m%n</pattern> </encoder> </appender
RollingFileAppender
RollingFileAppender
會(huì)將日志滾動(dòng)記錄,即寫入一個(gè)文件,當(dāng)滿足條件時(shí),再寫入下一個(gè)文件。例如設(shè)置文件大小為30MB,則當(dāng)寫入的日志文件達(dá)到30MB時(shí)會(huì)再新建一個(gè)日志文件進(jìn)行寫入。達(dá)到條件這個(gè)行為稱為滾動(dòng)。RollingFileAppender
常用的設(shè)置為:
<file>
: 文件名。無默認(rèn)值,必須設(shè)置。其路徑可以為絕對或相對。若上級(jí)目錄不存在則會(huì)自動(dòng)創(chuàng)建。<append>
: 是否開啟追加。默認(rèn)為true。若為true
,則新的日志會(huì)追加到文件末尾;若為false
,則寫新日志前會(huì)清空日志文件。<rollingPolicy>
: 滾動(dòng)策略。通常包含:滾動(dòng)條件(例如最大日志文件大?。?,文件命名格式,日志文件保存期限,等等。<layout>
: 日志輸出格式。
例如:
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>testFile.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${app-name}-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <MaxHistory>30</MaxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>30MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 日志輸出格式: --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %-5level ] [ %thread ] - [ %logger{50} : %line ] - %msg%n</pattern> </layout> </appender
<rollingPolicy>
滾動(dòng)策略
<rollingPolicy>
使用class
屬性指定滾動(dòng)策略,不同的策略有不同的配置。
1.基于時(shí)間的滾動(dòng)策略:ch.qos.logback.core.rolling.TimeBasedRollingPolicy
。
該策略根據(jù)時(shí)間來判定是否觸發(fā)滾動(dòng)。最常用。
常用配置為:
<fileNamePattern>
: 文件名格式,必須??梢允褂?code>%d轉(zhuǎn)換符來接收一個(gè)java.text.SimpleDateFormat
對象,例如%d{yyyy-MM-dd HH:mm:ss.SSS}
。<maxHistory>
: 日志文件保留天數(shù)。
2.基于文件大小的滾動(dòng)策略:ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy
。
該策略會(huì)監(jiān)視日志文件大小,當(dāng)文件超過指定大小時(shí)觸發(fā)滾動(dòng)。
<maxFileSize>
: 日志文件大小,默認(rèn)為10MB。<prudent>
: 是否安全寫入文件。若為true
,不支持FixedWindowRollingPolicy
。支持TimeBasedRollingPolicy
,但此時(shí)必須滿足:1不支持也不允許文件壓縮;2不能設(shè)置file屬性。<triggeringPolicy>
: 告知 RollingFileAppender 何時(shí)激活滾動(dòng)。
<root>標(biāo)簽
<root>
標(biāo)簽有2個(gè)作用:
- 定義日志的輸出等級(jí)。
- 指定哪些
<appender>
啟用。
<root>
其name
屬性固定為ROOT
,且沒有上級(jí),故而<root>
只有一個(gè)屬性:
level
: 最重要,指定日志的打印等級(jí),默認(rèn)為DEBUG
。其值可以為:ALL
,TRACE
,DEBUG
,INFO
,WARN
,ERROR,
FATAL,
OFF。不可以設(shè)置為
INHERITED或
NULL`。
可以在<root>
下配置多個(gè)<appender-ref>
,標(biāo)識(shí)對應(yīng)的<appender>
被添加到<root>
下,從而可以繼承<root>
的屬性和內(nèi)容。
例如:
<root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE" /> <appender-ref ref="ROLLING" /> </root>
其中<appender-ref>
的ref
屬性即為<appender>
或<logger>
的name
屬性。<root>
也是一個(gè)特殊的<logger>
,且為所有<logger>
的最上級(jí)父。<root>
的parent
屬性為null
。
<logger>標(biāo)簽
<logger>
標(biāo)簽非必須,用于對某些日志等級(jí)進(jìn)行單獨(dú)定義。
例如設(shè)置<root level="INFO">
,但希望springframework
的等級(jí)為WARN
,此時(shí)就可添加一個(gè)<logger>
標(biāo)簽:
<logger name="org.springframework" level="WARN"/>
<logger>
常用屬性為:
name
: 指定需單獨(dú)設(shè)置的組件類名。level
: 設(shè)置組件的日志等級(jí)。其值可以為:ALL
,TRACE
,DEBUG
,INFO
,WARN
,ERROR,
FATAL,
OFF??稍O(shè)置為
INHERITED或
NULL`。若不設(shè)置,則默認(rèn)繼承上級(jí)的level。additivity
: 是否向上級(jí)<logger>
傳遞打印信息。默認(rèn)為true
。若為true
,則本<logger>
打印一次,然后傳遞給上級(jí)<logger>
,上級(jí)<logger>
會(huì)再打印一次,這樣就會(huì)造成重復(fù)打印。因此通常都設(shè)置為false
。
例如:
<logger name="TEST_PARENT" level="INFO" additivity="false"> <appender-ref ref="TEST_CHILD"/> </logger>
這樣就形成了父子關(guān)系,TEST_CHILD
的上級(jí)為TEST_PARENT
。<logger>
有一個(gè)parent
屬性,指向其父<logger>
。每個(gè)<logger>
都有parent
,只有<root>
除外,<root>
是根節(jié)點(diǎn)。因此<root>
和所有的<logger>
會(huì)形成一棵樹。注意父子關(guān)系是由parent
屬性形成的,而非類繼承這樣的關(guān)系。
定義變量
變量有兩種:本地變量和配置文件變量。
本地變量<property>
在xml中定義一個(gè)變量,然后在整個(gè)xml文件中引用。格式為:
<property name="變量名" value="變量值" />
通過${變量名}
格式使用變量。例如:
<!-- 定義變量 --> <property name="LOG_HOME" value="E:/logs/" /> <!-- 使用變量 --> <appender> <file>${LOG_HOME}/${app-name}.log</file> </appender>
配置文件變量<springProperty>
若希望從yml或.properties中讀取變量值在xml中使用,則需要使用<springProperty>
。
例如,在application.yml中定義了一個(gè)logback_app_property.level
變量:
logback_app_property: level: INFO
現(xiàn)在希望引用這個(gè)level
變量,則可在xml中添加<springProperty>
標(biāo)簽,并令其source
屬性指向logback_app_property.level
變量。
<springProperty name="YML_LEVEL" source="logback_app_property.level" defaultValue="INFO"/>
同樣是通過${變量名}
格式使用變量:
<root level="${YML_LEVEL}"> </root>
實(shí)例
首先在yml中定義
logging: # 指定 logback-app.xml 作為logback的配置文件 config: classpath:logback-app.xml # 用于 logback-app.xml 文件配置的參數(shù)值 logback_app_property: # TRACE < DEBUG < INFO < WARN < ERROR level: INFO
然后在logback-app.xml中定義:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <contextName>Application</contextName> <jmxConfigurator/> <!-- 定義日志的保存目錄 --> <!-- <property name="LOG_HOME" value="/app/logs/" /> --> <property name="LOG_HOME" value="E:/logs/" /> <property name="app-name" value="test-admin"/> <property name="filename" value="server"/> <!-- 編碼設(shè)置 --> <property name="ENCODER_PATTERN" value="%red(%date{ISO8601}]) %highlight(%-5level) %green([%10.10thread]) [%X{X-B3-TraceId}] %boldMagenta(%logger{20}) - %cyan(%msg%n)" /> <!-- 控制臺(tái)輸出 --> <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${ENCODER_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 滾動(dòng)輸出到文件:將日志記錄到指定文件,滿足條件時(shí),再寫入下一個(gè)文件 --> <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 指定日志文件的名稱 --> <file>${LOG_HOME}/${app-name}.log</file> <!-- TimeBasedRollingPolicy: 基于時(shí)間的滾動(dòng)策略,該策略根據(jù)時(shí)間來判定是否觸發(fā)滾動(dòng)。 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 滾動(dòng)時(shí)產(chǎn)生的文件的存放位置及文件名稱 %d{yyyy-MM-dd}:按天進(jìn)行日志滾動(dòng) %i:當(dāng)文件大小超過maxFileSize時(shí),按照i進(jìn)行文件滾動(dòng) --> <fileNamePattern>${LOG_HOME}/${app-name}-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <!-- 可選節(jié)點(diǎn),控制保留的歸檔文件的最大數(shù)量,超出數(shù)量就刪除舊文件。 假如設(shè)置每天滾動(dòng),maxHistory是365,則只保存最近365天的文件,刪除之前的舊文件。 注意,刪除舊文件時(shí)那些為了歸檔而創(chuàng)建的目錄也會(huì)被刪除。 --> <MaxHistory>30</MaxHistory> <!-- 當(dāng)日志文件超過maxFileSize指定的大小時(shí),根據(jù)上面提到的%i進(jìn)行日志文件滾動(dòng)。 注意此處配置SizeBasedTriggeringPolicy是無法實(shí)現(xiàn)按文件大小進(jìn)行滾動(dòng)的,必須配置timeBasedFileNamingAndTriggeringPolicy --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>30MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 日志輸出格式: --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %-5level ] [ %thread ] - [ %logger{50} : %line ] - %msg%n</pattern> </layout> </appender> <!-- error信息輸出 --> <appender name="errorLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${app-name}-error.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${app-name}-error-%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>90</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %-5level ] [ %thread ] - [ %logger{50} : %line ] - %msg%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level> </filter> </appender> <!-- 這些日志不要打印debug,不然數(shù)量太多 --> <!-- 選擇使用的框架進(jìn)行配置 --> <logger name="org.springframework" level="WARN"/> <logger name="org.spring" level="WARN"/> <logger name="org.hibernate" level="WARN"/> <logger name="io.grpc.netty" level="OFF"/> <logger name="org.eclipse.jetty" level="WARN"/> <logger name="jndi" level="WARN"/> <logger name="redis.clients" level="WARN"/> <logger name="application" level="WARN"/> <logger name="springfox.documentation" level="WARN"/> <logger name="com.netflix" level="WARN"/> <logger name="org.reflections" level="WARN"/> <logger name="org.apache" level="WARN"/> <logger name="io.grpc.internal.ClientCallImpl" level="OFF"/> <logger name="org.springframework.amqp.rabbit" level="ERROR"/> <logger name="com.baomidou.dynamic.datasource.DynamicRoutingDataSource" level="WARN"/> <logger name="com.zaxxer.hikari.pool.HikariPool" level="WARN"/> <logger name="org.quartz.core.QuartzSchedulerThread" level="ERROR"/> <logger name="io.lettuce.core.protocol.RedisStateMachine" level="INFO"/> <logger name="io.lettuce.core.RedisChannelHandler" level="INFO"/> <logger name="io.lettuce.core.protocol.CommandHandler" level="INFO"/> <logger name="io.lettuce.core.protocol.CommandEncoder" level="INFO"/> <logger name="io.lettuce.core.protocol.DefaultEndpoint" level="INFO"/> <logger name="io.lettuce.core.protocol.ConnectionWatchdog" level="INFO"/> <logger name="io.lettuce.core.RedisClient" level="INFO"/> <logger name="org.mybatis.spring.mapper.ClassPathMapperScanner" level="INFO"/> <logger name="com.baomidou.mybatisplus.core.MybatisConfiguration" level="INFO"/> <!-- 配置文件變量 --> <springProperty name="LEVEL" source="logback_app_property.level" defaultValue="INFO"/> <root level="${LEVEL}"> <appender-ref ref="consoleAppender"/> <appender-ref ref="appLogAppender" /> <appender-ref ref="errorLogAppender" /> </root> </configuration>
在程序中動(dòng)態(tài)更改日志級(jí)別
在程序中使用代碼來動(dòng)態(tài)修改日志級(jí)別,首先導(dǎo)入庫:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext;
然后獲取<ROOT>
并修改level
:
String loggerName = "ROOT"; String loggerLevel = "DEBUG"; // 獲取日志上下文 LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); // 獲取ROOT ch.qos.logback.classic.Logger logger = loggerContext.getLogger(loggerName); // 修改日志等級(jí) logger.setLevel(Level.valueOf(loggerLevel));
注意這里的loggerName
與JMX不同,是大小寫不敏感的,例如ROOT
可以寫作root
。
Java管理擴(kuò)展 JMX(Java Management Extensions)
JMX是一個(gè)帶窗口的應(yīng)用程序,為運(yùn)行中的應(yīng)用提供管理功能。JMX是跨平臺(tái)的,與具體應(yīng)用無關(guān)。配置logback開啟JMX后即可通過JMX查看logback信息。
配置logback開啟JMX,需在xml中添加一行標(biāo)簽:
<configuration> <jmxConfigurator /> </configuration>
當(dāng)應(yīng)用運(yùn)行后,打開系統(tǒng)的CMD窗口,在其中輸入命令:
jconsole
然后就會(huì)打開JMX的應(yīng)用窗口,并提示新建連接。設(shè)應(yīng)用程序運(yùn)行在本地,則在本地進(jìn)程的列表中選擇對應(yīng)的應(yīng)用程序,然后雙擊或點(diǎn)連接。
之后可能彈出安全連接失敗。是否以不安全的方式重試?,選擇不安全的連接即可。
在上方的標(biāo)簽列表中點(diǎn)擊MBean標(biāo)簽,然后在列表中找到ch.qos.logbak.classic
,依次點(diǎn)擊進(jìn)入default
→ch.qos.logback.classic.jmx.JMXConfigurator
,其下會(huì)列出屬性和操作兩個(gè)列表。在其下分別包含不同的功能。
對于屬性,包含LoggerList
和Statuses
。其中LoggerList
列出了所有的Logger。特殊地,<root>
標(biāo)簽其對應(yīng)名稱為ROOT
,會(huì)列在第一行。
對于操作,可進(jìn)行:
- 重新加載logback的默認(rèn)配置文件。
- 通過指定的URL重新加載配置文件。
- 通過指定的文件重新加載配置文件。
- 設(shè)置指定logger級(jí)別,可設(shè)為
null
。 - 獲取指定logger級(jí)別,可返回
null
。 - 指定logger的有效級(jí)別。
點(diǎn)擊屬性下的LoggerList
,即可看到一個(gè)Logger數(shù)組。第一個(gè)就是ROOT
。
點(diǎn)擊操作下的getLoggerLevel
,需輸入一個(gè)參數(shù)p1
,該參數(shù)就是LoggerList
中的一個(gè)Logger。輸入ROOT
,然后點(diǎn)擊按鈕getLoggerLevel,即可看到ROOT
的等級(jí)。注意這里的p1
是大小寫敏感的,例如ROOT
不可以寫作root
。
點(diǎn)擊操作下的setLoggerLevel
,需輸入兩個(gè)參數(shù)p1
和p2
,p1
為Logger名稱,p2
為level值。例如p1
輸入ROOT
,p2
輸入DEBUG
,然后點(diǎn)擊按鈕setLoggerLevel,即可將ROOT
變更為DEBUG
等級(jí)。
同理,更改應(yīng)用的配置文件 logback.xml ,然后點(diǎn)擊 操作 下的reloadDefaultConfiguration
,并點(diǎn)擊右側(cè)的reloadDefaultConfiguration
按鈕,即可重新加載配置文件。
但在實(shí)際測試中,若配置文件為 logback.xml ,則表現(xiàn)相對正常;而若配置文件為其他名稱,例如 logback-spring.xml ,則重載配置文件后原控制臺(tái)將不再進(jìn)行打印,且對配置文件的修改也不會(huì)生效。似乎reloadDefaultConfiguration
只識(shí)別 logback.xml 。
另外,修改配置文件只能是更改 logback.xml 本身。如果修改的是application.yml中的logback_app_property.level
變量,reloadDefaultConfiguration
時(shí)并不會(huì)重新讀取該變量并應(yīng)用到 logback.xml 中。
一般來說,通過JMX來修改的只有ROOT
,以及l(fā)ogback.xml中配置的多個(gè)<logger>
。
到此這篇關(guān)于Spring Boot日志SLF4J和Logback詳解的文章就介紹到這了,更多相關(guān)Spring Boot SLF4J和Logback內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot3集成SLF4J+logback進(jìn)行日志記錄的實(shí)現(xiàn)
- 詳解Spring Boot 使用slf4j+logback記錄日志配置
- Springboot使用slf4j記錄日志的方法步驟
- Springboot項(xiàng)目使用Slf4j將日志保存到本地目錄的實(shí)現(xiàn)代碼
- 解決springboot使用logback日志出現(xiàn)LOG_PATH_IS_UNDEFINED文件夾的問題
- springboot使用Logback把日志輸出到控制臺(tái)或輸出到文件
- SpringBoot項(xiàng)目的logback日志配置(包括打印mybatis的sql語句)
相關(guān)文章
基于SpringBoot上傳任意文件功能的實(shí)現(xiàn)
下面小編就為大家?guī)硪黄赟pringBoot上傳任意文件功能的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08Spring Data JPA+kkpager實(shí)現(xiàn)分頁功能實(shí)例
本篇文章主要介紹了Spring Data JPA+kkpager實(shí)現(xiàn)分頁功能實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下2017-06-06詳解java.lang.NumberFormatException錯(cuò)誤及解決辦法
這篇文章主要介紹了詳解java.lang.NumberFormatException錯(cuò)誤及解決辦法,本文詳解的介紹了錯(cuò)誤的解決方法,感興趣的可以一起來了解一下2020-05-05搭建Springboot框架并添加JPA和Gradle組件的方法
這篇文章主要介紹了搭建Springboot框架并添加JPA和Gradle組件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07Spring AOP手動(dòng)實(shí)現(xiàn)簡單動(dòng)態(tài)代理的代碼
今天小編就為大家分享一篇關(guān)于Spring AOP手動(dòng)實(shí)現(xiàn)簡單動(dòng)態(tài)代理的代碼,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03