MDC的介绍及使用

1、MDC是什么?

MDC是(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 支持的一种方便在多线程条件下记录追踪日志的功能。通常打印出的日志会有线程号等信息来标志当前日志属于哪个线程,然而由于线程是可以重复使用的,所以并不能很清晰的确认一个请求的日志范围。处理这种情况一般有两种处理方式:

1)手动生成一个唯一序列号打印在日志中;

2)使用日志控件提供的MDC功能,生成一个唯一序列标记一个线程的日志;

两种方法的区别在于:

方法一只能标记一条日志,线程内其他日志需要人肉去筛选;

方法二标记整个线程的所有日志,方便grep命令查询;

对比可见,使用MDC功能更好。

2、MDC的原理

MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。当前线程的子线程会继承其父线程中的 MDC 的内容。当需要记录日志时,只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。对于一个 Web 应用来说,通常是在请求被处理的最开始保存这些数据。

 

@RunWith(SpringRunner.class)

@SpringBootTest(classes=CreditAppApplication.class)

publicclassMDCTest{

 

@Test

publicvoidmdcTest1(){

MDC.put("first","thefirst1");

 

Loggerlogger=LoggerFactory.getLogger(MDCTest.class);

MDC.put("last","thelast1");

 

logger.info("checkenclosed.");

logger.debug("themostbeautifultwowordsinenglish.");

 

MDC.put("first","thefirst2");

MDC.put("last","thelast2");

 

logger.info("iamnotacrook.");

logger.info("AttributedtotheformerUSpresident.17Nov1973.");

}

}

 

logback的配置:

3、MDC的使用

@Component

@Order(Ordered.HIGHEST_PRECEDENCE)

publicclassGlobalLogTagConfigextendsOncePerRequestFilter{

privatestaticfinalStringGLOBAL_LOG_TAG="GLOG_TAG";

 

privatestaticStringgenerateSeqNo(){

returnUUID.randomUUID().toString().replace("-","").substring(0,12);

}

 

@Override

protectedvoiddoFilterInternal(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse,FilterChainfilterChain)throwsServletException,IOException{

try{

StringseqNo;

if(httpServletRequest!=null){

seqNo=httpServletRequest.getHeader(GLOBAL_LOG_TAG);

 

if(StringUtils.isEmpty(seqNo)){

seqNo=generateSeqNo();

}

}else{

seqNo=generateSeqNo();

}

MDC.put(GLOBAL_LOG_TAG,seqNo);

filterChain.doFilter(httpServletRequest,httpServletResponse);

}finally{

MDC.remove(GLOBAL_LOG_TAG);

}

}

}

注意:

OncePerRequestFilter的作用是为了让每个请求只经过这个过滤器一次(因为web container的不同,有些过滤器可能被多次执行)

 

logback配置:

 

 

 

 

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值