持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
MDC介绍
MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j、logback 提供的一种方便在多线程条件下记录日志的功能。 MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。
MDC常用方法
-
clear() :移除所有MDC日志。
-
get (String key) :获取当前线程MDC中指定key的值。
-
getContext() :获取当前线程的MDC。
-
put(String key, Object o) :往当前线程的MDC中存入指定的键值对。
-
remove(String key) :删除当前线程MDC中指定的键值对。
MDC应用场景
-
记录用户 IP 地址、请求 URL、统计耗时等等,MDC 基本都能支撑;
-
用于记录用户的请求到响应整个过程,快速定位生产问题。
-
可借助 MDC 去实现链路跟踪。
MDC的使用
记录日志使用时,可在拦截器或者过滤器使用。
这里以SpringBoot中使用为例。
以下为过滤器的部分代码:
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
// 根据自己的需要,保存相应信息,如用户信息、用户IP
MDC.put("traceId", request.getHeader("user"));
filterChain.doFilter(request, response);
} catch (Exception e) {
throw e;
} finally {
//清理ThreadLocal
MDC.clear();
}
}
application.yml配置文件,配置日志文件
logging:
config: classpath:logback.xml
logback.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<contextName>MDCLog</contextName>
<!--定义日志文件的存储地址 -->
<property name="LOG_HOME" value="logs"/>
<!--定义日志的输出格式 -->
<property name="PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%X{traceId}][%X{username}] [%thread] %logger{30}:%line - %msg%n"/>
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<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="%d{yyyy-MM-dd HH:mm:ss.SSS} %yellow([%X{traceId}][%X{username}]) %highlight(%-5level) %magenta(%logger{30}:%-3L) - %m%n"/>
<!-- console日志格式 精简版 -->
<property name="CONSOLE_LOG_PATTERN_SIMPLE"
value="%d{HH:mm:ss.SSS} %highlight(%-5level) %magenta(%logger{20}:%-3L) - %m%n"/>
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!--encoder 默认配置为PatternLayoutEncoder-->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>180</maxHistory>
<totalSizeCap>40GB</totalSizeCap>
</rollingPolicy>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<appender name="AsyncRollingFile" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="RollingFile"/>
<includeCallerData>true</includeCallerData>
</appender>
<!-- 输出到控制台和文件,可定义更多的 Appender -->
<root level="INFO">
<appender-ref ref="Console"/>
<appender-ref ref="AsyncRollingFile"/>
</root>
<!-- 下面配置一些第三方包的日志过滤级别,用于避免刷屏 -->
<logger name="org.mybatis" level="INFO"/>
<logger name="org.springframework" level="WARN"/>
<logger name="org.apache" level="WARN"/>
<!-- 系统包名 -->
<logger name="com.project.example" level="DEBUG"/>
<!--如果需要打印SQL,可以把下面的级别设置为DEBUG -->
<logger name="com.project.example.dao" level="DEBUG"/>
</configuration>