Spring Boot在所有內(nèi)部日志中使用Commons Logging,但是默認配置也提供了對常用日志的支持崖蜜,如:Java Util Logging浊仆,Log4J, Log4J2和Logback客峭。每種Logger都可以通過配置使用控制臺或者文件輸出日志內(nèi)容。
一抡柿、默認日志Logback介紹
??SLF4J(Simple Logging Facade For Java)舔琅,它是一個針對于各類Java日志框架的統(tǒng)一Facade抽象。Java日志框架眾多洲劣,常用的有java.util.logging, log4j, logback备蚓,commons-logging, Spring框架使用的是Jakarta Commons Logging API (JCL)。而SLF4J定義了統(tǒng)一的日志抽象接口囱稽,而真正的日志實現(xiàn)則是在運行時決定的——它提供了各類日志框架的binding郊尝。
??Logback是log4j框架的作者開發(fā)的新一代日志框架,它效率更高战惊、能夠適應(yīng)諸多的運行環(huán)境流昏,同時天然支持SLF4J。
??默認情況下,Spring Boot會用Logback來記錄日志况凉,并用INFO級別輸出到控制臺谚鄙。在運行應(yīng)用程序和其他例子時,你應(yīng)該已經(jīng)看到很多INFO級別的日志了刁绒。
從上圖可以看到闷营,日志輸出內(nèi)容具體如下:
(1)、時間日期:精確到毫秒
(2)知市、日志級別:ERROR, WARN, INFO, DEBUG or TRACE
(3)傻盟、進程ID
(3)、分隔符:--- 標(biāo)識實際日志的開始
(4)嫂丙、線程名:方括號括起來(可能會截斷控制臺輸出)
(5)莫杈、Logger名:通常使用源代碼的類名
(6)、日志內(nèi)容
二奢入、關(guān)于日志依賴
在maven項目的pom.xml中添加spring-boot-starter-logging:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
那么筝闹,我們的Spring Boot應(yīng)用將自動使用logback作為應(yīng)用日志框架,Spring Boot啟動的時候腥光,由org.springframework.boot.logging.LoggingApplicationListener根據(jù)情況初始化并使用关顷。
但是呢,實際開發(fā)中我們不需要直接添加該依賴武福,你會發(fā)現(xiàn)spring-boot-starter其中包含了 spring-boot-starter-logging议双,該依賴內(nèi)容使用的就是Spring Boot默認的日志框架 logback。而我們之前的項目在引入的spring-boot-starter-web依賴中就包含了spring-boot-starter捉片。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot為我們提供了很多默認的日志配置平痰,所以,只要將spring-boot-starter-logging作為依賴加入到項目中伍纫,則"開箱即用"宗雇。
三、application.properties文件中日志配置介紹
1莹规、控制臺輸出
日志級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL赔蒲,如果設(shè)置為WARN,則低于WARN的信息都不會輸出良漱。
Spring Boot中默認配置ERROR舞虱、WARN和INFO級別的日志輸出到控制臺。您還可以通過啟動您的應(yīng)用程序--debug標(biāo)志來啟用"debug"模式(開發(fā)的時候推薦開啟),以下兩種方式皆可:
(1)母市、在運行命令后加入--debug標(biāo)志矾兜,如:$ java -jar springTest.jar --debug
(2)、在application.properties中配置debug=true
注意:該屬性置為true的時候患久,核心Logger(包含嵌入式容器椅寺、hibernate舶沿、spring)會輸出更多內(nèi)容,但是你自己應(yīng)用的日志并不會輸出為DEBUG級別配并。
2括荡、文件輸出
默認情況下,Spring Boot將日志輸出到控制臺溉旋,不會寫到日志文件畸冲。如果要編寫除控制臺輸出之外的日志文件,則需在application.properties中設(shè)置logging.file或logging.path屬性观腊。
(1)邑闲、logging.file
設(shè)置文件,可以是絕對路徑梧油,也可以是相對路徑苫耸。如:logging.file=my.log
(2)、logging.path
設(shè)置目錄儡陨,會在該目錄下創(chuàng)建spring.log文件褪子,并寫入日志內(nèi)容,如:logging.path=/var/log
如果只配置 logging.file骗村,會在項目的當(dāng)前路徑下生成一個 xxx.log 日志文件嫌褪。
如果只配置 logging.path,在 /var/log文件夾生成一個日志文件為 spring.log
備注:二者不能同時使用胚股,如若同時使用笼痛,則只有l(wèi)ogging.file生效
默認情況下,日志文件的大小達到10MB時會切分一次琅拌,產(chǎn)生新的日志文件缨伊,默認級別為:ERROR、WARN进宝、INFO
3刻坊、日志級別
所有支持的日志記錄系統(tǒng)都可以在Spring環(huán)境中設(shè)置記錄級別(例如在application.properties中)
格式為:'logging.level.* = LEVEL'
logging.level:日志級別控制前綴,*為包名或Logger名
LEVEL:選項TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
舉例:
logging.level.com.yubin=DEBUG:com.yubin包下所有class以DEBUG級別輸出
logging.level.root=WARN:root日志以WARN級別輸出
四即彪、自定義日志配置
由于日志服務(wù)一般都在ApplicationContext創(chuàng)建前就初始化了紧唱,它并不是必須通過Spring的配置文件控制活尊。因此通過系統(tǒng)屬性和傳統(tǒng)的Spring Boot外部配置文件依然可以很好的支持日志控制和管理隶校。
根據(jù)不同的日志系統(tǒng),你可以按如下規(guī)則組織配置文件名蛹锰,就能被正確加載:
Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
Log4j2:log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging):logging.properties
Spring Boot官方推薦優(yōu)先使用帶有-spring的文件名作為你的日志配置(如使用logback-spring.xml深胳,而不是logback.xml),命名為logback-spring.xml的日志配置文件铜犬,spring boot可以為它添加一些spring boot特有的配置項(下面會提到)舞终。
上面是默認的命名規(guī)則轻庆,并且放在src/main/resources下面即可。
如果你即想完全掌控日志配置敛劝,但又不想用logback.xml作為Logback配置的名字余爆,可以通過logging.config屬性指定自定義的名字:
logging.config=classpath:logging-config.xml
雖然一般并不需要改變配置文件的名字,但是如果你想針對不同運行時Profile使用不同的日志配置夸盟,這個功能會很有用蛾方。
下面我們來看看一個普通的logback-spring.xml例子:
<configuration scan="true" scanPeriod="10 seconds">
<!-- 每個logger都關(guān)聯(lián)到logger上下文,默認上下文名稱為“default”上陕。但可以使用<contextName>設(shè)置成其他名字桩砰,用于區(qū)分不同應(yīng)用程序的記錄。一旦設(shè)置释簿,不能修改,可以通過%contextName來打印日志上下文名稱亚隅。 -->
<contextName>logback</contextName>
<!-- name的值是變量的名稱,value的值時變量定義的值庶溶。通過定義的值會被插入到logger上下文中煮纵。定義后,可以使"${}"來使用變量偏螺。 -->
<property name="log.path" value="/var/log"/>
<!--1. 輸出到控制臺-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是為開發(fā)使用醉途,只配置最底級別,控制臺輸出的日志級別是大于或等于此級別的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>info</level>
</filter>
<encoder>
<Pattern>%d{HH: mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</Pattern>
<!-- 設(shè)置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--2. 輸出到文檔-->
<!-- 2.1 level為 DEBUG 日志砖茸,時間滾動輸出 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文檔的路徑及文檔名 -->
<file>${log.path}/web_debug.log</file>
<!--日志文檔輸出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 設(shè)置字符集 -->
</encoder>
<!-- 日志記錄器的滾動策略隘擎,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志歸檔 -->
<fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文檔保留天數(shù)-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文檔只記錄debug級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>
1凉夯、根節(jié)點<configuration>包含的屬性
(1)货葬、scan:當(dāng)此屬性設(shè)置為true時,配置文件如果發(fā)生改變劲够,將會被重新加載震桶,默認值為true。
(2)征绎、scanPeriod:設(shè)置監(jiān)測配置文件是否有修改的時間間隔蹲姐,如果沒有給出時間單位,默認單位是毫秒人柿。當(dāng)scan為true時柴墩,此屬性生效。默認的時間間隔為1分鐘凫岖。
(3)江咳、debug:當(dāng)此屬性設(shè)置為true時,將打印出logback內(nèi)部日志信息哥放,實時查看logback運行狀態(tài)歼指。默認值為false爹土。
根節(jié)點<configuration>的子節(jié)點:
<configuration>下面一共有2個屬性,3個子節(jié)點踩身,分別是:
2胀茵、屬性一:設(shè)置上下文名稱<contextName>
每個logger都關(guān)聯(lián)到logger上下文,默認上下文名稱為“default”挟阻。但可以使用<contextName>設(shè)置成其他名字宰掉,用于區(qū)分不同應(yīng)用程序的記錄。一旦設(shè)置赁濒,不能修改,可以通過%contextName來打印日志上下文名稱轨奄。
<contextName>logback</contextName>
3、屬性二:設(shè)置變量<property>
用來定義變量值的標(biāo)簽拒炎,<property> 有兩個屬性邑狸,name和value梨与;其中name的值是變量的名稱,value的值時變量定義的值。通過<property>定義的值會被插入到logger上下文中更扁。定義變量后膏斤,可以使“${}”來使用變量俊扭。
<property name="log.path" value="/var/log"/>
4已添、子節(jié)點一<appender>
appender用來格式化日志輸出節(jié)點,有倆個屬性name和class鸿摇,class用來指定哪種輸出策略石景,常用就是控制臺輸出策略和文件輸出策略。
(1)拙吉、控制臺輸出ConsoleAppender
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是為開發(fā)使用潮孽,只配置最底級別,控制臺輸出的日志級別是大于或等于此級別的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>info</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 設(shè)置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<encoder>表示對日志進行編碼
%d{HH: mm:ss.SSS}:日志輸出時間
%thread:輸出日志的線程名字筷黔,這在Web應(yīng)用以及異步任務(wù)處理中很有用
%-5level:日志級別往史,并且使用5個字符靠左對齊
%logger{36}:日志輸出者的名字
%msg:日志消息
%n:平臺的換行符
ThresholdFilter為系統(tǒng)定義的攔截器,例如我們用ThresholdFilter來過濾掉ERROR級別以下的日志不輸出到文件中佛舱。如果不用記得注釋掉椎例,不然你控制臺會發(fā)現(xiàn)沒日志~
(2)、輸出到文件RollingFileAppende
另一種常見的日志輸出到文件请祖,隨著應(yīng)用的運行時間越來越長订歪,日志也會增長的越來越多,將他們輸出到同一個文件并非一個好辦法损拢。RollingFileAppender用于切分文件日志:
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文檔的路徑及文檔名 -->
<file>${log.path}/web_debug.log</file>
<!--日志文檔輸出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 設(shè)置字符集 -->
</encoder>
<!-- 日志記錄器的滾動策略陌粹,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志歸檔 -->
<fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文檔保留天數(shù)-->
<maxHistory>15</maxHistory>
</rollingPolicy>
</appender>
其中重要的是rollingPolicy的定義福压,上例中<fileNamePattern>logback.%d{yyyy-MM-dd}.log</fileNamePattern>定義了日志的切分方式——把每一天的日志歸檔到一個文件中掏秩,<maxHistory>30</maxHistory>表示只保留最近30天的日志,以防止日志填滿整個磁盤空間荆姆。同理蒙幻,可以使用%d{yyyy-MM-dd_HH-mm}來定義精確到分的日志切分方式。<totalSizeCap>1GB</totalSizeCap>用來指定日志文件的上限大小胆筒,例如設(shè)置為1GB的話邮破,那么到了這個值,就會刪除舊的日志仆救。
5抒和、子節(jié)點二<root>
root節(jié)點是必選節(jié)點,用來指定最基礎(chǔ)的日志輸出級別彤蔽,只有一個level屬性摧莽。
level:用來設(shè)置打印級別,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF顿痪,不能設(shè)置為INHERITED或者同義詞NULL镊辕,默認是DEBUG。
<root>可以包含零個或多個<appender-ref>元素蚁袭,標(biāo)識這個appender將會添加到這個loger征懈。
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
6、子節(jié)點三<loger>
<loger>用來設(shè)置某一個包或者具體的某一個類的日志打印級別揩悄、以及指定<appender>卖哎。<loger>僅有一個name屬性,一個可選的level和一個可選的additivity屬性删性。
name:用來指定受此loger約束的某一個包或者具體的某一個類棉饶。
level:用來設(shè)置打印級別,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF镇匀,還有一個特俗值INHERITED或者同義詞NULL照藻,代表強制執(zhí)行上級的級別。如果未設(shè)置此屬性汗侵,那么當(dāng)前l(fā)oger將會繼承上級的級別幸缕。
additivity:是否向上級loger傳遞打印信息。默認是true晰韵。
loger在實際使用的時候有兩種情況发乔,先來看一看代碼中如何使用:
@RestController
public class ShowLogController {
private Logger logger = LoggerFactory.getLogger(ShowLogController.class);
@GetMapping("/showLog")
public String showLog() {
// 日志級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設(shè)置為WARN雪猪,則低于WARN的信息都不會輸出
logger.trace("日志輸出:trace");
logger.debug("日志輸出:debug");
logger.info("日志輸出:info");
logger.warn("日志輸出:warn");
logger.error("日志輸出:error");
return "success";
}
}
(1)栏尚、帶有l(wèi)oger的配置,不指定級別只恨,不指定appender
<logger name="com.yubin.springboot.controller"/>
上述配置將控制controller包下的所有類的日志的打印译仗,但是并沒用設(shè)置打印級別抬虽,所以繼承他的上級<root>的日志級別“info”;
沒有設(shè)置additivity纵菌,默認為true阐污,將此loger的打印信息向上級傳遞;
沒有設(shè)置appender咱圆,此loger本身不打印任何信息笛辟。
<root level="info">將root的打印級別設(shè)置為“info”,指定了名字為“CONSOLE”等的appender序苏。
當(dāng)執(zhí)行ShowLogController類的showLog方法時手幢,ShowLogController在包com.yubin.springboot.controller中,所以首先執(zhí)行<logger name="com.yubin.springboot.controller"/>忱详,將級別為“info”及大于“info”的日志信息傳遞給root围来,本身并不打印踱阿;
root接到下級傳遞的信息管钳,交給已經(jīng)配置好的名為“CONSOLE”等的appender處理,“CONSOLE”appender將信息打印到控制臺软舌;
打印結(jié)果如下:
(2)才漆、帶有多個loger的配置,指定級別佛点,指定appender
<logger name="com.yubin.springboot.controller" level="warn" additivity="false">
<appender-ref ref="CONSOLE"/>
</logger>
控制com.yubin.springboot.controller類的日志打印醇滥,打印級別為“WARN”
additivity屬性為false,表示此loger的打印信息不再向上級傳遞
指定了名字為“CONSOLE”的appender
這時候執(zhí)行ShowLogController類的showLog方法時超营,先執(zhí)行<logger name="com.yubin.springboot.controlle" level="WARN" additivity="false">,
將級別為“WARN”及大于“WARN”的日志信息交給此loger指定的名為“console”的appender處理鸳玩,在控制臺中打出日志,不再向上級root傳遞打印信息演闭。
打印結(jié)果如下:
7不跟、多環(huán)境日志輸出
據(jù)不同環(huán)境(prod:生產(chǎn)環(huán)境,test:測試環(huán)境米碰,dev:開發(fā)環(huán)境)來定義不同的日志輸出窝革,在 logback-spring.xml中使用 springProfile 節(jié)點來定義,方法如下:
備注:文件名稱不是logback.xml吕座,想使用spring擴展profile支持虐译,要以logback-spring.xml命名。
<springProfile name="dev">
<logger name="com.sdcm.pmp" level="debug"/>
</springProfile>
可以啟動服務(wù)的時候指定 profile (如不指定使用默認)吴趴,如指定prod 的方式為:
java -jar xxx.jar --spring.profiles.active=prod
8漆诽、環(huán)境屬性
<springProperty>標(biāo)簽允許從Spring環(huán)境中獲取屬性,以便在Logback中使用。 如果需要在logback中訪問application.properties文件中的值厢拭,這個標(biāo)簽將非常有用兰英。 標(biāo)簽的工作方式與Logback標(biāo)準(zhǔn)的<property>標(biāo)簽類似,但不是指定直接值蚪腐,而是指定屬性的來源(來自Environment)箭昵。
<springProperty scope="context" name="log.path" source="path.log"/>
9税朴、日志顏色輸出
將上述的配置做如下修改
<property name="CONSOLE_LOG_PATTERN" value="%date{yyyy-MM-dd HH:mm:ss} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n"/>
<!--1. 輸出到控制臺-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--<Pattern>%d{HH: mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</Pattern>-->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 設(shè)置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
效果圖