spring boot中的日志入门
日志通常不會(huì)在需求階段作為一個(gè)功能單獨(dú)提出來,也不會(huì)在產(chǎn)品方案中看到它的細(xì)節(jié)。但是,這絲毫不影響它在任何一個(gè)系統(tǒng)中的重要地位。
報(bào)警系統(tǒng)與日志系統(tǒng)的關(guān)系
為了保證服務(wù)的高可用,發(fā)現(xiàn)問題一定要及時(shí),定位并解決問題一定要迅速。
生產(chǎn)環(huán)境一旦出現(xiàn)問題,預(yù)警系統(tǒng)就會(huì)通過郵件,短信甚至電話的方式實(shí)施多維轟炸模式,確保相關(guān)負(fù)責(zé)人不會(huì)錯(cuò)過每一個(gè)可能的Bug。
而預(yù)警系統(tǒng)判斷疑似Bug大部分來源于日志系統(tǒng)。比如說某個(gè)微服務(wù)接口由于各種原因?qū)е骂l繁調(diào)用出錯(cuò),此時(shí)調(diào)用段就會(huì)捕獲這樣的異常并打印ERROR級(jí)別的日子,當(dāng)該錯(cuò)誤日志達(dá)到一定出現(xiàn)次數(shù)的時(shí)候就會(huì)觸發(fā)報(bào)警系統(tǒng)。
try {// 調(diào)用某服務(wù) } catch(Exception e) {Logger.error("錯(cuò)誤信息", e); }
因此日志十分重要。
Spring Boot的默認(rèn)日志
Spring Boot默認(rèn)使用Logback日志系統(tǒng),如果不需要更改為其他日志系統(tǒng),如Log4j2等,則無需多余的配置,Logback默認(rèn)將日志打印到控制臺(tái)上。
要使用Logback,原則上是需要添加Maven依賴的。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId> </dependency>
但是由于Spring Boot項(xiàng)目中一般會(huì)引用spring-boot-starter或spring-boot-starter-web,這兩個(gè)起步依賴中都已經(jīng)包含了對(duì)spring-boot-starter-logging的依賴,所以無需額外添加依賴,配置logback-spring.xml就可以了。以logback-spring.xml命名,spring會(huì)自動(dòng)識(shí)別加載。
如果要切換成Log4j2的話,就需要在pom.xml中排除Spring Boot自帶的commons-logging,然后再引入log4j2的依賴,否則會(huì)導(dǎo)致jar包沖突。
<!--排除 commons‐logging--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>commons‐logging</groupId><artifactId>commons‐logging</artifactId></exclusion></exclusions> </dependency><!--引入log4j2 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
然后再引入log4j.properties文件就可以了。
### set log levels ### log4j.rootLogger = debug,stdout,D,E### 輸出到控制臺(tái) ### 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 = %d{ABSOLUTE} ===== %5p %c{ 1 }:%L - %m%n### 輸出到日志文件 ### #log4j.appender.D = org.apache.log4j.DailyRollingFileAppender #log4j.appender.D.File = logs/log.log #log4j.appender.D.Append = true #log4j.appender.D.Threshold = DEBUG ## 輸出DEBUG級(jí)別以上的日志 #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### 保存異常信息到單獨(dú)文件 ### #log4j.appender.D = org.apache.log4j.DailyRollingFileAppender #log4j.appender.D.File = logs/error.log ## 異常日志文件名 #log4j.appender.D.Append = true #log4j.appender.D.Threshold = ERROR ## 只輸出ERROR級(jí)別以上的日志!!! #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
日志的級(jí)別
日志的級(jí)別從低到高:trace(跟蹤)<debug(調(diào)試)<info(信息)<warm(警告)<error(錯(cuò)誤),設(shè)置的級(jí)別越低,顯示的日志級(jí)別的信息越多。例如如果設(shè)置的日志級(jí)別是info的話,低于info級(jí)別的trace或debug的日志都不會(huì)顯示。
Spring Boot在不對(duì)日志進(jìn)行任何設(shè)置的情況下,默認(rèn)的日志root級(jí)別是info,即輸出的是info級(jí)別及以上的日志。
用一個(gè)測試類來測試日志的輸出級(jí)別:
@RunWith(SpringRunner.class) @SpringBootTest public class SpringbootCacheApplicationTests {private static final Logger log = LoggerFactory.getLogger(SpringbootCacheApplicationTests.class);/*** 測試 日志級(jí)別:* 級(jí)別由低到高: trace < debug < info < warm < error 設(shè)置的級(jí)別越低顯示的日志信息越多。* 可以調(diào)整輸出的日志級(jí)別,只會(huì)顯示高于設(shè)置級(jí)別的日志。*/@Testpublic void testLog() {log.trace("這是trace日志。。。");log.debug("這是debug日志。。。");// spring 默認(rèn)設(shè)置的級(jí)別是info級(jí)別,沒有指定級(jí)別的情況下,會(huì)使用spring默認(rèn)的root級(jí)別(顯示的是info級(jí)別的信息)log.info("這是info日志。。。");log.warn("這是warm日志。。。");log.error("這是error日志。。。");} }
測試的結(jié)果是只會(huì)輸出info級(jí)別以上的日志信息(trace和debug不打印在控制臺(tái))。因此在開發(fā)環(huán)境中如果要打印SQL語句等debug調(diào)試信息的話,就要對(duì)日志級(jí)別進(jìn)行設(shè)置。
日志輸出信息的組成部分
1.時(shí)間日期:精確到毫秒。
2.日志級(jí)別:ERROR, WARN, INFO, DEBUG 或 TRACE。
3.分隔符:標(biāo)識(shí)實(shí)際日志的開始。
4.進(jìn)程ID。
5.線程名:需要用方括號(hào)括起來,不然可能會(huì)截?cái)嗫刂婆_(tái)的輸出。
6.Logger的名稱:通常是源代碼的類名。
7.日志主要內(nèi)容。
日志的配置
日志可以通過兩種方式配置,一種是application.properties或application.yml文件配置(Spring Boot全局配置文件);一種是Logback的xml文件配置。第一種方式需要把所有的日志配置寫在properties或者yml文件里面,配置遷移不方便,寫的感覺也有點(diǎn)亂,很繁雜,對(duì)log4j2的支持也不好。因此推薦使用的是第二種,配置遷移只要復(fù)制粘貼,然后改一下里面的配置就好了。
通過application.properties或application.yml文件配置。
這部分的內(nèi)容就不說了,實(shí)際中用得比較少(其實(shí)是懶),如果需要的話可以到Spring Boot的官方文檔中查找相關(guān)的配置:https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/html/boot-features-logging.html#_environment_properties。
通過Logback的xml文件配置。
由于日志服務(wù)一般都在ApplicationContext(應(yīng)用上下文)創(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特有的配置項(xiàng)(下面會(huì)提到)。
一般情況下都是按照默認(rèn)的命名規(guī)則去命名,并把文件放在src/main/resources目錄下面即可。但是如果你想要完全掌控日志配置,但是又不想用locagback.xml作為Logback配置的名字,就需要通過logging.config屬性去執(zhí)行自定義的名字,例如:
logging.config=classpath:logging-config.xml
雖然一般是并不需要改變配置文件的名字,但是如果你想要針對(duì)不同運(yùn)行時(shí)Profile(不同的環(huán)境,比如生產(chǎn)環(huán)境和開發(fā)環(huán)境的切換)使用不同的日志配置,這個(gè)功能就會(huì)很有用。
這里示例一個(gè)logback-spring.xml的配置文件的內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?> <!-- scan:當(dāng)此屬性設(shè)置為true時(shí),配置文件如果發(fā)生改變,將會(huì)被重新加載,默認(rèn)值為true。 scanPeriod:設(shè)置監(jiān)測配置文件是否有修改的時(shí)間間隔,如果沒有給出時(shí)間單位,默認(rèn)單位是毫秒當(dāng)scan為true時(shí),此屬性生效。默認(rèn)的時(shí)間間隔為1分鐘。 debug:當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息,實(shí)時(shí)查看logback運(yùn)行狀態(tài)。默認(rèn)值為false。 --> <configuration scan="false" scanPeriod="60 seconds" debug="false"><!-- 定義日志的根目錄 --><property name="LOG_HOME" value="/app/log" /><!-- 定義日志文件名稱 --><property name="appName" value="ll-springboot"></property><!-- ch.qos.logback.core.ConsoleAppender 表示控制臺(tái)輸出 --><appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"><!--日志輸出格式:%d表示日期時(shí)間,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度%logger{50} 表示logger名字最長50個(gè)字符,否則按照句點(diǎn)分割。 %msg:日志消息,%n是換行符--><layout class="ch.qos.logback.classic.PatternLayout"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></layout></appender><!-- 滾動(dòng)記錄文件,先將日志記錄到指定文件,當(dāng)符合某個(gè)條件時(shí),將日志記錄到其他文件 --> <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 指定日志文件的名稱 --><file>${LOG_HOME}/${appName}.log</file><!--當(dāng)發(fā)生滾動(dòng)時(shí),決定 RollingFileAppender 的行為,涉及文件移動(dòng)和重命名TimeBasedRollingPolicy: 最常用的滾動(dòng)策略,它根據(jù)時(shí)間來制定滾動(dòng)策略,既負(fù)責(zé)滾動(dòng)也負(fù)責(zé)出發(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}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern><!--可選節(jié)點(diǎn),控制保留的歸檔文件的最大數(shù)量,超出數(shù)量就刪除舊文件。假設(shè)設(shè)置每天滾動(dòng),且maxHistory是365,則只保存最近365天的文件,刪除之前的舊文件。注意,刪除舊文件是,那些為了歸檔而創(chuàng)建的目錄也會(huì)被刪除。--><MaxHistory>365</MaxHistory><!--當(dāng)日志文件超過maxFileSize指定的大小是,根據(jù)上面提到的%i進(jìn)行日志文件滾動(dòng) 注意此處配置SizeBasedTriggeringPolicy是無法實(shí)現(xiàn)按文件大小進(jìn)行滾動(dòng)的,必須配置timeBasedFileNamingAndTriggeringPolicy--><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 日志輸出格式: --><layout class="ch.qos.logback.classic.PatternLayout"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern></layout></appender><!-- logger主要用于存放日志對(duì)象,也可以定義日志類型、級(jí)別name:表示匹配的logger類型前綴,也就是包的前半部分level:要記錄的日志級(jí)別,包括 TRACE < DEBUG < INFO < WARN < ERRORadditivity:作用在于children-logger是否使用 rootLogger配置的appender進(jìn)行輸出,false:表示只用當(dāng)前l(fā)ogger的appender-ref,true:表示當(dāng)前l(fā)ogger的appender-ref和rootLogger的appender-ref都有效--><!--logger是記錄Logger對(duì)象輸出的日志級(jí)別的sercvice實(shí)現(xiàn)類引入日志對(duì)象可以查看方法的報(bào)錯(cuò)信息以及打印sql語句,public static final Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);生產(chǎn)環(huán)境:一般把level設(shè)為error,可以記錄錯(cuò)誤的日志信息,畢竟主要是要記錄錯(cuò)誤信息進(jìn)行錯(cuò)誤定位。開發(fā)環(huán)境:類中引入了logger日志對(duì)象時(shí),level級(jí)別用info,debug都可以,都有錯(cuò)誤信息輸出。--><!-- hibernate logger --><logger name="com.ll" level="info" /><!-- Spring framework logger --><logger name="org.springframework" level="debug" additivity="false"></logger><!-- root與logger是父子關(guān)系,沒有特別定義則默認(rèn)為root,任何一個(gè)類只會(huì)和一個(gè)logger對(duì)應(yīng),要么是定義的logger,要么是root,判斷的關(guān)鍵在于找到這個(gè)logger,然后判斷這個(gè)logger的appender和level。 --><!-- 一般用默認(rèn)的info就可以 --><root level="info"><!-- 控制臺(tái)輸出日志--><appender-ref ref="stdout" /><!--開發(fā)環(huán)境:不需要往文件記錄日志,可以把這個(gè)appender-ref ref="appLogAppender"注釋,上面那個(gè)往文件寫日志的appender也要注釋,不然每天都產(chǎn)生一個(gè)空文件;生產(chǎn)環(huán)境:需要往文件記錄日志,此時(shí)appender-ref ref="appLogAppender"就不能注釋了,不然沒日志記錄到文件,上面那個(gè)往文件寫日志的appender也要放開。--><appender-ref ref="appLogAppender" /></root> </configuration>
配置文件其實(shí)不需要記太多東西,只要知道在什么地方要改什么配置就行了。
日志的使用
在完成了日志系統(tǒng)的配置之后,就可以愉快地享受日志系統(tǒng)帶來的快樂了(滑稽)。
日志系統(tǒng)的使用方法就是在業(yè)務(wù)代碼中使用Logger對(duì)象調(diào)用相應(yīng)的方法完成日志的輸出。
聲明并初始化一個(gè)Logger對(duì)象。
public static final Logger logger = LoggerFactory.getLogger(日志要監(jiān)控的類.class);
調(diào)用相應(yīng)的方法輸出日志。
try {// 業(yè)務(wù)代碼 } catch(Exception e) {logger.error("你的代碼出錯(cuò)了,笨蛋。", e); }
這樣就能在程序運(yùn)行時(shí)輸出相應(yīng)的日志信息。
?
"我一個(gè)人在路上,偶爾想起你。"
轉(zhuǎn)載于:https://www.cnblogs.com/yanggb/p/10966888.html
總結(jié)
以上是生活随笔為你收集整理的spring boot中的日志入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jenkins ssl证书报错问题解决
- 下一篇: Educational Round 66