SpringBoot日志框架如何使用
不管是開發(fā)過程中調(diào)試還是線上問題的定位追蹤,日志都發(fā)揮著及其重要的作用。平時(shí),我們會(huì)用System.out.println()
打印一些信息到控制臺(tái),我們可以使用該語句輸出日志,但是System.out
會(huì)增加資源的消耗,所以最好使用日志框架打印日志信息。
Java中的日志框架有JCL、Jboss-logging、slf4j、logback、log4j、log4j2等等,其中JCL、Jboss-logging、slf4j屬于日志門面(日志的抽象),logback、log4j、log4j2是日志框架的具體實(shí)現(xiàn)。阿里巴巴開發(fā)規(guī)范強(qiáng)制要求使用日志的門面而不要直接使用日志系統(tǒng)的API。
【強(qiáng)制】應(yīng)用中不可直接使用日志系統(tǒng)(Log4j、Logback)中的 API,而應(yīng)依賴使用日志框架(SLF4J、JCL--Jakarta Commons Logging)中的 API,使用門面模式的日志框架,有利于維護(hù)和各個(gè)類的日志處理方式統(tǒng)一。
日志門面不是日志解決方案,它只服務(wù)于各種各樣的日志系統(tǒng),這就允許最終用戶在部署應(yīng)用時(shí)可以隨意使用其所希望的日志系統(tǒng)。也就是說如果開始使用slf4j+logback記錄日志,則項(xiàng)目會(huì)按logback的風(fēng)格打印日志,后期如果我們想更改為log4j風(fēng)格的輸出,則只需將logback替換為log4j即可,不需改變項(xiàng)目中的任何代碼。
slf4j+logback也是SpringBoot中默認(rèn)整合的日志框架。
如何使用
public class LoggerService { private static final Logger logger = LoggerFactory.getLogger(LoggerService.class); public void printLog() { logger.trace("trace日志……"); logger.debug("debug日志……"); logger.info("info日志……"); logger.warn("warn日志……"); logger.error("error日志……"); } }
使用LoggerFactory
生成Logger
對(duì)象,然后調(diào)用Logger
對(duì)象的相應(yīng)日志級(jí)別的方法打印即可。另外,在輸出日志時(shí),字符串的拼接要使用占位符替換不要使用append等方法。
【強(qiáng)制】在日志輸出時(shí),字符串變量之間的拼接使用占位符的方式。說明:因?yàn)?String 字符串的拼接會(huì)使用 StringBuilder 的 append()方式,有一定的性能損耗。使用占位符僅是替換動(dòng)作,可以有效提升性能。正例:logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);
上述代碼的運(yùn)行效果:
2020-12-28 13:32:40.751 INFO 16016 --- [nio-8080-exec-2] c.c.e.e.service.LoggerService : info日志…… 2020-12-28 13:32:40.751 WARN 16016 --- [nio-8080-exec-2] c.c.e.e.service.LoggerService : warn日志…… 2020-12-28 13:32:40.751 ERROR 16016 --- [nio-8080-exec-2] c.c.e.e.service.LoggerService : error日志……
從運(yùn)行效果可以看出,SpringBoot默認(rèn)的日志級(jí)別(trace < debug < info < warn < error)是info。
指定配置
SpringBoot日志的默認(rèn)配置在org\springframework\boot\spring-boot\2.4.1\spring-boot-2.4.1.jar!\org\springframework\boot\logging\logback\defaults.xml
文件中,內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- Default logback configuration provided for import --> <included> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <property name="CONSOLE_LOG_CHARSET" value="${CONSOLE_LOG_CHARSET:-default}"/> <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <property name="FILE_LOG_CHARSET" value="${FILE_LOG_CHARSET:-default}"/> <logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/> <logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/> <logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/> <logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/> <logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/> <logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/> <logger name="org.hibernate.validator.internal.util.Version" level="WARN"/> <logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/> </included>
里面定義了默認(rèn)的日志輸出格式, org\springframework\boot\spring-boot\2.4.1\spring-boot-2.4.1.jar!\org\springframework\boot\logging\logback\base.xml
文件中定義了日志默認(rèn)級(jí)別。如果想要使用自定義的配置,在類路徑下放上日志框架自己對(duì)應(yīng)的配置文件即可,如logback對(duì)應(yīng)logback-spring.xml或logback.xml,log4j2對(duì)應(yīng)log4j2-spring.xml或log4j2.xml,這樣Springboot便不在使用默認(rèn)配置。
SpringBoot 官方建議在日志配置中使用 -spring 的配置方式(例如,使用 logback-spring.xml 而不是 logback.xml)。如果使用標(biāo)準(zhǔn)配置位置,Spring 無法完全控制日志初始化。
另外官方文檔中有明確提到,JUL(ava Util Logging) 在 FATJAR 場(chǎng)景下存在一些已知的類加載問題,所以要盡量避免在 FATJAR 場(chǎng)景下使用 JUL。
使用這種命名方式日志框架就不會(huì)直接加載日志的配置,而改由SpringBoot加載,同時(shí)使用SpringBoot的高級(jí)Profile功能指定某段配置只在某個(gè)環(huán)境下生效。
<springProfile name="dev"> <!-- 激活dev下的配置 --> </springProfile> <springProfile name="!production"> <!-- 激活非production下的配置 --> </springProfile>
示例
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <!-- 該輸出格式只在dev下生效 --> <springProfile name="dev"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern> </springProfile> </layout> </appender>
logback配置詳解
logback完整配置如下
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!-- 日志文件的地址,windows和Linux下都要寫絕對(duì)地址 --> <property name="LOG_HOME" value="/home" /> <!-- 日志輸出格式:%d表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度,%msg:日志消息,%n是換行符 --> <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" /> <!--控制臺(tái)輸出 --> <appender name="CONSOLE_OUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!-- 輸出格式,直接引用上面定義的property --> <pattern>${LOG_PATTERN}</pattern> </encoder> </appender> <!--文件輸出, 每天生成日志文件 --> <appender name="FILE_OUT" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件名--> <FileNamePattern>${LOG_HOME}/XXX.log.%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天數(shù),15天是阿里巴巴開發(fā)規(guī)范中的最低要求--> <MaxHistory>15</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--輸出格式,同上--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!-- myibatis日志配置 --> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <!-- 日志輸出級(jí)別 --> <root level="DEBUG"> <appender-ref ref="CONSOLE_OUT" /> <appender-ref ref="FILE_OUT"/> </root> </configuration>
更換日志框架
SpringBoot中的日志實(shí)現(xiàn)默認(rèn)是logback,假如我們要更換其他日志實(shí)現(xiàn),假如要更換為L(zhǎng)og4j2,該怎么做呢?
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!-- 移除原實(shí)現(xiàn) --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- 引入新實(shí)現(xiàn) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
總結(jié)一下就是分為兩步:
移除原日志的實(shí)現(xiàn),根據(jù)新使用的日志實(shí)現(xiàn)不同需移除的項(xiàng)目也有所不同,如要使用log4j則需移除以下依賴。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>logback-classic</artifactId> <groupId>ch.qos.logback</groupId> </exclusion> <exclusion> <artifactId>log4j-over-slf4j</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency>
引入新實(shí)現(xiàn)的依賴。
log4j需引入,這是一個(gè)適配層的包,其自動(dòng)依賴了log4j。
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency>
log4j2需引入。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
以上就是SpringBoot日志框架如何使用的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot日志框架的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于Maven parent.relativePath說明
Maven中的relativePath用于指定父項(xiàng)目pom.xml的相對(duì)路徑,默認(rèn)值為../pom.xml,這個(gè)配置幫助Maven在構(gòu)建時(shí)定位父模塊的位置,確保模塊間的依賴關(guān)系正確,relativePath可以指向本地或遠(yuǎn)程倉(cāng)庫中的父項(xiàng)目,如果不需要尋找父項(xiàng)目,可以將其設(shè)置為空2024-09-09Java連接Sql數(shù)據(jù)庫經(jīng)常用到的操作
這篇文章主要介紹了Java連接Sql數(shù)據(jù)庫經(jīng)常用到的操作的相關(guān)資料,需要的朋友可以參考下2016-02-02java實(shí)現(xiàn)二維碼生成的幾個(gè)方法(推薦)
本篇文章主要介紹了java實(shí)現(xiàn)二維碼生成的幾個(gè)方法(推薦),具有一定的參考價(jià)值,有興趣的可以了解一下。2016-12-12java中TCP實(shí)現(xiàn)回顯服務(wù)器及客戶端
本文主要介紹了java中TCP實(shí)現(xiàn)回顯服務(wù)器及客戶端,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02PowerJob的DesignateServer工作流程源碼解讀
這篇文章主要介紹了PowerJob的DesignateServer工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Java設(shè)計(jì)模式之觀察者模式(Observer模式)介紹
這篇文章主要介紹了Java設(shè)計(jì)模式之觀察者模式(Observer模式)介紹,Java深入到一定程度,就不可避免的碰到設(shè)計(jì)模式(design pattern)這一概念,了解設(shè)計(jì)模式,將使自己對(duì)java中的接口或抽象類應(yīng)用有更深的理解,需要的朋友可以參考下2015-03-03