slf4j中MDC是什么鬼

  slf4j除了trace、debug、info、warn、error这几个日志接口外,还可以配合MDC将数据写入日志。换句话说MDC也是用来记录日志的,但它的使用方式与使用日志接口不同。

  在使用日志接口时我们一般这么做

Logger LOG = LoggerFactory.getLogger("LOGNAME_OR_CLASS");
if(LOG.isDebugEnabled()) {
  LOG.debug("log debug");
}

  MDC从使用方式上有些不同,我对它的理解是MDC可以将一个处理线程中你想体现在日志文件中的数据统一管理起来,根据你的日志文件配置决定是否输出。

  比如以下但不限于以下场景可以考虑使用MDC来达到目的

  1. 我们想在日志中体现请求用户IP地址
  2. 用户使用http客户端的user-agent
  3. 记录一次处理线程的日志跟踪编号(这个编号目的是为了查询日志方便,结合grep命令能根据跟踪编号将本次的处理日志全部输出)

MDC的使用

  org.slf4j.MDC我个人会用AOP或Filter或Interceptor这类工具配合使用,获得你希望输出到日志的变量并调用MDC.put(String key, String val),比如下面代码片段第5行:

  @Around(value = "execution(* com.xx.xx.facade.impl.*.*(..))", argNames="pjp")
public Object validator(ProceedingJoinPoint pjp) throws Throwable {
try {
String traceId = TraceUtils.begin();
MDC.put("mdc_trace_id", traceId);
Object obj = pjp.proceed(args);
return obj;
} catch(Throwable e) {
//TODO 处理错误
} finally {
TraceUtils.endTrace();
}
}

  代码通过AOP记录了每次请求的traceId并使用变量"mdc_trace_id"记录,在日志配置文件里需要设置变量才能将"mdc_trace_id"输出到日志文件中。我以logback配置文件为例,看日志第10行%X{mdc_trace_id}:

  <appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${CATALINA_BASE}/logs/all.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${CATALINA_BASE}/logs/all.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - traceId:[%X{mdc_trace_id}] - %msg%n</pattern>
</encoder>
</appender>

MDC带来的好处

  1. 如果你的系统已经上线,突然有一天老板说我们增加一些用户数据到日志里分析一下。如果没有MDC我猜此时此刻你应该处于雪崩状态。MDC恰到好处的让你能够实现在日志上突如其来的一些需求
  2. 如果你是个代码洁癖,封装了公司LOG的操作,并且将处理线程跟踪日志号也封装了进去,但只有使用了你封装日志工具的部分才能打印跟踪日志号,其他部分(比如hibernate、mybatis、httpclient等等)日志都不会体现跟踪号。当然我们可以通过linux命令来绕过这些困扰。
  3. 使代码简洁、日志风格统一

最新文章

  1. memcache分布式 [一致性hash算法] 的php实现
  2. HDU1116 Play on Words(有向图欧拉通路)
  3. 基于ViewPager的一些酷炫切换效果
  4. Django安装以及介绍
  5. Centos7-yum部署配置LNMP+php-fgm,一台机器上部署
  6. vue props命名最好直接使用kebab-case (短横线隔开式) 命名
  7. BZOJ2151种树——模拟费用流+链表+堆
  8. java 偏向锁、轻量级锁及重量级锁synchronized原理
  9. Web App 和 Native App,哪个是趋势?
  10. Struts 2 初步入门(二)
  11. mysql权限管理命令示例
  12. matlab 获取网卡MAC地址
  13. PTA 大炮打蚊子&#160;&#160;&#160;(15分)
  14. [CEOI2017]Building Bridges
  15. ubuntu安装ssh服务记录
  16. 撩课-Web大前端每天5道面试题-Day16
  17. 【转】web测试技术经典案例(基础、全面)
  18. Fedora 中的容器技术:systemd-nspawn
  19. 【算法拾遗(java描写叙述)】--- 插入排序(直接插入排序、希尔排序)
  20. 【BZOJ 2120】【国家集训队 2011】【数颜色】(莫队)

热门文章

  1. .NET基础拾遗(5)多线程开发基础
  2. ABP文档 - SignalR 集成
  3. 深入研究Visual studio 2017 RC新特性
  4. 独立开发 一个社交 APP 的架构分享 (已实现)
  5. redis成长之路——(一)
  6. 海康网络摄像机YV12转换为BGR,由opencv Mat显示 (转)
  7. PHP设计模式(五)建造者模式(Builder For PHP)
  8. BPM配置故事之案例7-公式计算
  9. 笔记:Memory Notification: Library Cache Object loaded into SGA
  10. php安装threads多线程扩展