1.简介
MDC 介绍 MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。MDC 可以看成是一个与当前线程绑定的Map,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。当前线程的子线程会继承其父线程中的 MDC 的内容。当需要记录日志时,只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。对于一个 Web 应用来说,通常是在请求被处理的最开始保存这些数据。 简而言之,MDC就是日志框架提供的一个InheritableThreadLocal,项目代码中可以将键值对放入其中,然后使用指定方式取出打印即可。
原理:
MDC 在内部使用了一个线程绑定的
Map
来存储键值对。这意味着每个线程都有自己的 MDC 上下文。当一个线程开始执行某个任务时,可以在其 MDC 中设置一些键值对;例如:当请求来时把前端请求头携带traceId放在InheritableThreadLocal里,然后打印时去取就行了。
2.使用
2.1配置TraceId 过滤器
@Order(1)
@WebFilter(urlPatterns = "/*",filterName = "traceIdFilter")
public class TraceIdFilter implements Filter {
public final static String MDC_TRACE_ID = "traceId";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String traceId = httpRequest.getHeader(MDC_TRACE_ID);
if (StringUtils.isBlank(traceId)) {
traceId = IdUtil.fastSimpleUUID();;
}
MDC.put(MDC_TRACE_ID, traceId);
chain.doFilter(request, response);
}
}
Java
2.2 启动类开启
@SpringBootApplication
@ServletComponentScan //支持java web原生三大组件
public class OpenApp {
public static void main(String[] args) {
SpringApplication.run(OpenApp.class, args);
}
}
Java
2.3 配置文件配置日志输出格式
spring.application.name = order-service
#日志配置
logging.level.root=error
logging.level.com.beiyou=debug
logging.level.cn.smart=debug
#日志配置
# Console Appender
logging.pattern.console=${spring.application.name} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} --- %msg%n
# File Appender
logging.file.name=/logs/${spring.application.name}.log
logging.pattern.file=${spring.application.name} [%date] %level [%thread] [%X{traceId}] %logger{36} [%file:%line] %msg%n
logging.file.max-size = 100MB
logging.file.max-history = 7
# 注释说明:
# %d{yyyy-MM-dd HH:mm:ss.SSS}: 时间戳,格式为年-月-日 时:分:秒:毫秒
# %-5level: 日志级别,左对齐且至少占用5个字符宽度
# %clr(...): 使用颜色编码(如果支持)
# [%X{traceId}]: Mapped Diagnostic Context中的traceId,用于记录跟踪请求的唯一标识
# ${PID:-}: 当前进程ID,如果没有则显示空字符串
# ---: 分隔符
# %logger{36}: 日志器名称,最多显示36个字符
# %m: 日志消息内容
# %n: 换行符
GraphQL
附