先看下MDC是什么

Mapped Diagnostic Context,用于打LOG时跟踪一个“会话“、一个”事务“。举例,有一个web controller,在同一时间可能收到来自多个客户端的请求,如果一个请求发生了错误,我们要跟踪这个请求从controller开始一步步都执行到了哪些代码、有哪些log的输出。这时我们可以看log文件,但是log文件是多个请求同时记录的,基本无法分辨哪行是哪个请求产生的,虽然我们可以看线程,但线程可能被复用,也是很难分辨出,这时MDC就派上用场了。

我们可以加一个web filter,在请求进来时,把”标识“放到MDC context中,比如:put( ip, 8.8.8.8), put(username, 'yang'),在filter结束时把context再清掉,即可在整个请求处理过程中,都可以打印出ip, username这些数据,就可以方便的用于日志跟踪。

在SpringBoot中怎么用

1. 写一个LogInterceptor,用于统一处理MDC:

  1.  
    @Component
  2.  
    public class LogInterceptor implements HandlerInterceptor {
  3.  
     
  4.  
    private final static String REQUEST_ID = "requestId";
  5.  
    private static final Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);
  6.  
     
  7.  
    @Override
  8.  
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
  9.  
    String xForwardedForHeader = httpServletRequest.getHeader("X-Forwarded-For");
  10.  
    String remoteIp = httpServletRequest.getRemoteAddr();
  11.  
    String uuid = UUID.randomUUID().toString();
  12.  
    LOGGER.info("put requestId ({}) to logger", uuid);
  13.  
    LOGGER.info("request id:{}, client ip:{}, X-Forwarded-For:{}", uuid, remoteIp, xForwardedForHeader);
  14.  
    MDC.put(REQUEST_ID, uuid);
  15.  
    return true;
  16.  
    }
  17.  
     
  18.  
    @Override
  19.  
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
  20.  
    String uuid = MDC.get(REQUEST_ID);
  21.  
    LOGGER.info("remove requestId ({}) from logger", uuid);
  22.  
    MDC.remove(REQUEST_ID);
  23.  
    }
  24.  
     
  25.  
    @Override
  26.  
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
  27.  
     
  28.  
    }
  29.  
    }
关键代码在于:MDC.put(REQUEST_ID, uuid);

2. 注册一下这个Interceptor,写一个WebMvcConfigurer类:

  1.  
    @Configuration
  2.  
    public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
  3.  
    @Autowired
  4.  
    private LogInterceptor logInterceptor;
  5.  
     
  6.  
    @Override
  7.  
    public void addInterceptors(InterceptorRegistry registry) {
  8.  
    registry.addInterceptor(logInterceptor);
  9.  
    super.addInterceptors(registry);
  10.  
    }
  11.  
    }
3. 放一个logback.xml到src/main/resources/目录中,用于配置logback的参数,如没有,请新建一个
  1.  
    <configuration scan="true" scanPeriod="30 seconds" debug="true">
  2.  
     
  3.  
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  4.  
    <target>System.out</target>
  5.  
    <encoder>
  6.  
    <pattern>[%date{ISO8601}] [%-5level] - [%thread] [%X{requestId}] [%logger] [%X{akkaSource}] - %msg %rootException %n
  7.  
    </pattern>
  8.  
     
  9.  
    </encoder>
  10.  
    </appender>
  11.  
     
  12.  
     
  13.  
     
  14.  
    <root level="INFO">
  15.  
    <appender-ref ref="STDOUT"/>
  16.  
    </root>
  17.  
     
  18.  
    </configuration>

注意这个<pattern/>中配置了输出 requestId

4. 最后看下效果,下面加粗的即为requestId
[2017-12-14 16:08:45,677] [INFO ] - [http-nio-8080-exec-1] [a08f86cd-6743-48ce-816a-f5ee61b802b8] 

在SpringBoot项目中添加logback的MDC的更多相关文章

  1. 在SpringBoot项目中添加SpringMVC拦截器

    1.认识拦截器 SpringMVC的拦截器(Interceptor)不是Filer,同样可以实现请求的预处理.后处理.使用拦截器仅需要两个步骤 实现拦截器 注册拦截器 1.1实现拦截器 实现拦截器可以 ...

  2. 在SpringBoot中添加Logback日志处理

    前言 SpringBoot项目中在官方文档中说明,默认已经依赖了一些日志框架.而其中推荐使用的就是Logback,所以这一次我将在我的模版中加入Logback日志的配置,说明一下,SpringBoot ...

  3. SpringBoot12 QueryDSL01之QueryDSL介绍、springBoot项目中集成QueryDSL

    1 QueryDSL介绍 1.1 背景 QueryDSL的诞生解决了HQL查询类型安全方面的缺陷:HQL查询的扩展需要用字符串拼接的方式进行,这往往会导致代码的阅读困难:通过字符串对域类型和属性的不安 ...

  4. JAVA项目中引用Logback的方法

    一.简介 本文主要讲JAVA项目中引入Logback的方法. 二.解决 1.引入依赖. <!--Begin LogBack Log--> <!-- https://mvnreposi ...

  5. 五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链

    买买买结算系统 一年一度的双十一购物狂欢节就要到了,又到剁手党们开始表演的时刻了.当我们把种草很久的商品放入购物车以后,点击"结算"按钮时,就来到了买买买必不可少的结算页面了.让我 ...

  6. SpringBoot项目中遇到的BUG

    1.启动项目的时候报错 1.Error starting ApplicationContext. To display the auto-configuration report re-run you ...

  7. springboot项目中接口入参的简单校验

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  8. Spring-Boot项目中配置redis注解缓存

    Spring-Boot项目中配置redis注解缓存 在pom中添加redis缓存支持依赖 <dependency> <groupId>org.springframework.b ...

  9. Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作

    Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作 1>. 创建一个控制台程序2>. 添加一个 ADO.NET实体数据模型,选择对应的数据库与表(Studen ...

随机推荐

  1. oracle学习笔记(一) oracle 体系结构简单介绍以及创建表空间和用户

    体系结构 oracle数据服务器由oracle数据库和实例组成 实例由后台进程和内存结构组成 内存结构由共享池,数据缓冲区,日志缓存区 Oracle数据库是通过表空间来存储物理表的,一个数据库实例可以 ...

  2. 折腾Java设计模式之备忘录模式

    原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...

  3. Java基础小知识笔记

    1. Integer转进制的一个类2. toBinaryString,toOctalString,toHexString.(转为二进制,八进制,十六进制的方法)3. 如果·数据的大小没有超过byte/ ...

  4. js中console使用2

    接着上一篇js中console使用1,本片继续介绍js中console的用法 测试代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 ...

  5. JavaScript篇 深入理解JavaScript函数

    JavaScript中的函数 1. 函数的定义 两种定义形式: 通过函数定义表达式来定义 通过函数声明语句来定义 函数声明语句定义一个函数 //计算阶乘的递归函数 function factorial ...

  6. jsp内置对象-session对象

    一.session概述 隐含对象session是javax.servlet.http.HttpSession接口实现类的对象,用于保存用户的状态信息. 在web开发中,服务器为每个用户浏览器创建一个会 ...

  7. Odoo 强大的开源微信模块 oejia_wx

    详见:http://oejia.net/blog/2018/10/24/oejia_wx_v054.html oejia_wx Odoo 的微信模块,提供了对微信公众号.企业号(企业微信)及小程序的接 ...

  8. 如何简单的构建Android?

    原文链接:https://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/   过去的几个月中,在Tuenti上与同行例 ...

  9. 随笔:关于去年的WordPress建站的回忆

    2018-02-26    建站 2018-02-28    选择主题Clearision 2018-03-01    学习插入视频.修改主题 <iframe src="//playe ...

  10. 借书证信息管理系统,C语言实现

    自己实现的如有缺漏欢迎提出 /* 原创文章 转载请附上原链接: https://www.cnblogs.com/jiujue/p/10325628.html   */ 设计内容: 设计一个排序和查找系 ...