Log4j2簡(jiǎn)介
日志框架slf4j胜蛉、j.u.l挠进、log4j色乾、logback、log4j2的比較?和?log4j2配置文件詳解领突,請(qǐng)參考上篇文章《Log4j2使用詳解》
Log4j2實(shí)例
下面我們通過實(shí)例來看看Log4j2在Spring Boot中的應(yīng)用
1暖璧、引入log4j2依賴
Spring Boot默認(rèn)使用LogBack,如果我們要使用Log4j2攘须,需要從spring-boot-starter-web中去掉spring-boot-starter-logging依賴漆撞,同時(shí)顯式聲明使用Log4j2的依賴jar包,具體如下:
<dependency>
? ? <groupId>org.springframework.boot</groupId>
? ? <artifactId>spring-boot-starter-web</artifactId>
? ? <exclusions>
? ? ? ? <!-- 去掉默認(rèn)配置 -->
? ? ? ? <exclusion>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? ? ? <artifactId>spring-boot-starter-logging</artifactId>
? ? ? ? ? ? </exclusion>
? ? </exclusions>
</dependency>
<!-- 引入log4j2依賴 -->
<dependency>
? ? <groupId>org.springframework.boot</groupId>
? ? <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
2于宙、創(chuàng)建并配置log4j2-spring.xml
在src/main/resources文件夾下創(chuàng)建log4j2-spring.xml文件浮驳,并寫入如下內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
? ? <properties>
? ? ? ? <property name="logBase">~/</property>
? ? </properties>
? ? <Appenders>
? ? ? ? <Console name="Console" target="SYSTEM_OUT">
? ? ? ? ? ? <PatternLayout charset="UTF-8" pattern="[%d] [%-5p] [%t] [%c] - %m%n"/>
? ? ? ? </Console>
? ? ? ? <RollingFile name="RollingFile" fileName="${logBase}/logs/access.log" filePattern="${logBase}/logs/access.%d{yyyy-MM-dd}.log">
? ? ? ? ? ? <PatternLayout pattern="[%d] [%-5p] [%t] [%c] - %m%n"/>
? ? ? ? ? ? <TimeBasedTriggeringPolicy/>
? ? ? ? </RollingFile>
? ? ? ? <RollingFile name="ErrorFile" fileName="${logBase}/logs/error.log" filePattern="${logBase}/logs/error.%d{yyyy-MM-dd}.log">
? ? ? ? ? ? <Filters>
? ? ? ? ? ? ? ? <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
? ? ? ? ? ? </Filters>
? ? ? ? ? ? <PatternLayout pattern="[%d] [error] [%t] [%c] - %m%n"/>
? ? ? ? ? ? <TimeBasedTriggeringPolicy/>
? ? ? ? </RollingFile>
? ? </Appenders>
? ? <Loggers>
? ? ? ? <Root level="trace">
? ? ? ? ? ? <AppenderRef ref="Console"/>
? ? ? ? ? ? <AppenderRef ref="RollingFile"/>
? ? ? ? ? ? <AppenderRef ref="ErrorFile"/>
? ? ? ? </Root>
? ? </Loggers>
</configuration>
各節(jié)點(diǎn)的詳細(xì)說明,詳見《Log4j2使用詳解》
logBase請(qǐng)根據(jù)項(xiàng)目的實(shí)際日志目錄修改
3捞魁、打印日志
一般情況下至会,我們使用LoggerFactory去獲取Logger對(duì)象,在BlogController中我們加入如下內(nèi)容:
private final static Logger logger = LoggerFactory.getLogger(BlogController.class);
@GetMapping(value = "log")
public String printLog() {
? ? logger.trace("trace log");
? ? logger.debug("debug log");
? ? logger.info("info log");
? ? logger.warn("warn log");
? ? logger.error("error log");
? ? return "print log ok";
}
調(diào)用接口谱俭,可以看到控制臺(tái)和日志目錄下的logs/access.log文件中從trace log到error log都依次打印出來奉件,而error.log中打印出了error log。
如果把log4j2-spring.xml文件中的<Root level="trace”>修改為<Root level="info”>昆著,則日志從info級(jí)別開始打印县貌,trace和debug日志不會(huì)打印。
多環(huán)境配置日志文件
Spring Boot默認(rèn)加載log4j2-spring.xml文件凑懂,如果我們想像application.yml配置文件一樣煤痕,不同的環(huán)境配置不同的log4j2文件,比如本地環(huán)境需要在控制臺(tái)打印出來接谨,測(cè)試環(huán)境和線上的日志目錄不同等摆碉,這時(shí)候我們也可以根據(jù)環(huán)境的不同配置不同的日志文件。
1脓豪、創(chuàng)建log4j2-dev.xml巷帝、log4j2-test.xml和log4j2-prod.xml
log4j2-dev.xml:把log4j2-spring.xml文件內(nèi)容copy到log4j2-dev.xml中
log4j2-test.xml:去掉控制臺(tái)打印、修改logBase變量扫夜、修改root的日志level
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
? ? <properties>
? ? ? ? <property name="logBase">~/test/</property>
? ? </properties>
? ? <Appenders>
? ? ? ? <RollingFile name="RollingFile" fileName="${logBase}/logs/access.log" filePattern="${logBase}/logs/access.%d{yyyy-MM-dd}.log">
? ? ? ? ? ? <PatternLayout pattern="[%d] [%-5p] [%t] [%c] - %m%n"/>
? ? ? ? ? ? <TimeBasedTriggeringPolicy/>
? ? ? ? </RollingFile>
? ? ? ? <RollingFile name="ErrorFile" fileName="${logBase}/logs/error.log" filePattern="${logBase}/logs/error.%d{yyyy-MM-dd}.log">
? ? ? ? ? ? <Filters>
? ? ? ? ? ? ? ? <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
? ? ? ? ? ? </Filters>
? ? ? ? ? ? <PatternLayout pattern="[%d] [error] [%t] [%c] - %m%n"/>
? ? ? ? ? ? <TimeBasedTriggeringPolicy/>
? ? ? ? </RollingFile>
? ? </Appenders>
? ? <Loggers>
? ? ? ? <Root level="info">
? ? ? ? ? ? <AppenderRef ref="RollingFile"/>
? ? ? ? ? ? <AppenderRef ref="ErrorFile"/>
? ? ? ? </Root>
? ? </Loggers>
</configuration>
log4j2-prod.xml:修改logBase變量為~/prod/楞泼,其他同log4j2-test.xml
2、刪除log4j2-spring.xml
3笤闯、多環(huán)境配置日志文件
application-dev.yml增加配置節(jié)點(diǎn):
logging:
? config: classpath:log4j2-dev.xml
application-test.yml增加配置節(jié)點(diǎn):
logging:
? config: classpath:log4j2-test.xml
application-prod.yml增加配置節(jié)點(diǎn):
logging:
? config: classpath:log4j2-prod.xml
4现拒、修改環(huán)境變量,查看日志打印結(jié)果
IDEA中通過修改Active profiles來切換dev望侈、test和prod環(huán)境,可以看到不同的環(huán)境打印出的日志
使用traceId跟蹤請(qǐng)求全流程日志
線上我們一般采用多機(jī)部署勋桶,用kibana收集日志脱衙,但是在并發(fā)大的時(shí)候侥猬,使用日志定位問題比較麻煩,很難篩選出指定請(qǐng)求的全部相關(guān)日志捐韩。因此我們可以對(duì)日志打印做一個(gè)改造退唠,使用traceId跟蹤請(qǐng)求的全部路徑。
1荤胁、MDC簡(jiǎn)介
MDC:Mapped Diagnostic Context瞧预,映射調(diào)試上下文,它是 log4j 和 logback 提供的一種方便在多線程條件下記錄日志的功能仅政。MDC 中包含的內(nèi)容可以被同一線程中執(zhí)行的代碼所訪問垢油。當(dāng)前線程的子線程會(huì)繼承其父線程中的 MDC 的內(nèi)容。當(dāng)需要記錄日志時(shí)圆丹,只需要從 MDC 中獲取所需的信息即可滩愁。
2、創(chuàng)建AccessInterceptor
在com.tn666.demo目錄下創(chuàng)建interceptor文件夾辫封,在此文件夾下創(chuàng)建AccessInterceptor類文件:
public class AccessInterceptor implements HandlerInterceptor {
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
? ? ? ? String traceId = UUID.randomUUID().toString();
? ? ? ? MDC.put("traceId", traceId);
? ? ? ? return true;
? ? }
}
preHandle方法會(huì)在Controller處理之前進(jìn)行調(diào)用硝枉,我們?cè)谡?qǐng)求開始時(shí),向MDC中寫入了一個(gè)traceId倦微,這里主要說一下traceId的記錄妻味,更多攔截器的內(nèi)容,后續(xù)的文章中會(huì)詳細(xì)介紹
3欣福、創(chuàng)建MvcConfiguration
在com.tn666.demo.configuration文件夾下創(chuàng)建MvcConfiguration類文件:
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
? ? @Override
? ? public void addInterceptors(InterceptorRegistry registry) {
? ? ? ? registry.addInterceptor(new AccessInterceptor());
? ? }
}
4责球、讀取traceId
在 log4j 和 logback 的取值方式為:
%X{traceId}
在日志文件的PatternLayout中加入traceId的讀戎冈堋:
<PatternLayout pattern="[%d] [%X{traceId}] [%-5p] [%t] [%c] - %m%n"/>
5鸦致、日志打印
訪問接口,可以看到traceId的打印
從打印出的日志可以看出瓤漏,這是兩次http請(qǐng)求凿将,有兩個(gè)traceId
6校套、下游服務(wù)使用相同traceId
查找問題時(shí),有時(shí)候我們希望把一次請(qǐng)求串起來牧抵,包括調(diào)用第三方服務(wù)笛匙,這時(shí)候我們可以采用如下方法:
1)改造http調(diào)用工具
在發(fā)送http請(qǐng)求時(shí),自動(dòng)將traceId添加到header中
2)下游服務(wù)的攔截器修改
下游服務(wù)的攔截器犀变,首先從header中獲取traceId妹孙,寫入MDC中,若header中沒有traceId获枝,再使用UUID
文章中的示例代碼蠢正,可以在https://github.com/tunan66666/spring-boot-demo上查看
若您覺得還可以,請(qǐng)幫忙點(diǎn)個(gè)“贊”省店,謝謝