使用MDC实现日志链路跟踪

目录
  • 1.原理
  • 2.实现
  • 3.过滤器
  • 4.logback.xml
  • 5.返回体
  • 6.效果日志

前言:

在微服务环境中,我们经常使用Skywalking、CAT等去实现整体请求链路的追踪,但是这个整体运维成本高,架构复杂,我们来使用MDC通过Log来实现一个轻量级的会话事务跟踪功能。

1.原理

MDC org.sl4j.MDC其实内部就是ThreadLocal,MDC提供了put/get/clear等几个核心接口,用于操作ThreadLocal中的数据;ThreadLocal中的K-V,可以在logback.xml中声明,最终将会打印在日志中。

// java代码
MDC.put("userId","laker");  

// logback.xml
%X{userId}

例如:

<property name="pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level [%X{userId}] %logger{20} - %msg%n"/>

2.实现

整体流程如下:

  • 用户登录系统,我们日志中记录userId:laker
  • 用户发起请求,一个请求中可能实际产生多个http请求,这里可以前端生成一个requestId
  • 在返回体中,返回requestId
  • 研发运维人员,可以根据 userIdrequestId去日志中捞请求链路。

3.过滤器

@Order(value = Ordered.HIGHEST_PRECEDENCE + 100)
@Component
@WebFilter(filterName = "MDCFilter", urlPatterns = "/*")
public class MDCFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        try {
            MDC.put("userId", "laker");
            MDC.put("requestId", IdUtil.fastUUID());
        } catch (Exception e) {
            //
        }

        try {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } finally {
            MDC.clear();
        }
    }
}

4.logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_HOME" value="logs"/>
    <property name="encoding" value="UTF-8"/>

    <appender name="DEFAULT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/test.log</file>
        <Append>true</Append>
        <prudent>false</prudent>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50} %line - %m%n</pattern>
        </encoder>
        <!-- 按天回滚 daily -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--归档日志文件名-->
            <FileNamePattern>${LOG_HOME}/test.log.%d{yyyy-MM-dd}</FileNamePattern>
            <!-- 最多保存15天历史文件 -->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 日志输出格式 -->
    <property name="log.pattern"
              value="%d{HH:mm:ss.SSS} [%thread] %-5level [%X{userId}|%X{requestId}] %logger{20} - [%method,%line] - %msg%n"/>

    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50} %line - %m%n</pattern>
        </encoder>
    </appender>

    <logger name="com.test.demo" level="DEBUG">
        <appender-ref ref="DEFAULT"/>
    </logger>
    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="DEFAULT"/>
        <appender-ref ref="console"/>
    </root>
</configuration>

5.返回体

public class Response<T> {
    @ApiModelProperty(notes = "响应码,非200 即为异常", example = "200")
    private final int code;
    @ApiModelProperty(notes = "响应消息", example = "提交成功")
    private final String msg;
    @ApiModelProperty(notes = "响应数据")
    private final T data;
    @ApiModelProperty(notes = "请求id")
    private final String requestId;

    public Response(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
        this.requestId = MDC.get("requestId");
    }

6.效果日志

响应:

{
    code: 200,
    msg: "",
    requestId: "74a269a8-3cb4-417e-853c-b968b77cce23"
}

日志:

18:37:15.997 [http-nio-8080-exec-1] INFO  [laker|90717490-5ef4-4e46-bc2c-605952fc3803] c.l.m.c.InfoController - [v2Map,17] - null
18:37:38.980 [http-nio-8080-exec-2] INFO  [laker|82bde351-f86e-466f-97a0-c857a0c4c1c9] c.l.m.c.InfoController - [v2Map,17] - null
18:37:39.992 [http-nio-8080-exec-3] INFO  [laker|74a269a8-3cb4-417e-853c-b968b77cce23] c.l.m

到此这篇关于使用MDC实现日志链路跟踪的文章就介绍到这了,更多相关MDC实现日志链路跟踪内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot 项目添加 MDC 日志链路追踪的执行流程

    目录 1. 线程池配置 2. 拦截器配置 3. 日志文件配置 4. 使用方法示例 4.1. 异步使用 4.2. 定时任务 日志链路追踪的意思就是将一个标志跨线程进行传递,在一般的小项目中也就是在你新起一个线程的时候,或者使用线程池执行任务的时候会用到,比如追踪一个用户请求的完整执行流程. 这里用到MDC和ThreadLocal,分别由下面的包提供: java.lang.ThreadLocal org.slf4j.MDC 直接上代码: 1. 线程池配置 如果你直接通过手动新建线程来执行异步任务,想

  • 使用MDC实现日志链路跟踪

    目录 1.原理 2.实现 3.过滤器 4.logback.xml 5.返回体 6.效果日志 前言: 在微服务环境中,我们经常使用Skywalking.CAT等去实现整体请求链路的追踪,但是这个整体运维成本高,架构复杂,我们来使用MDC通过Log来实现一个轻量级的会话事务跟踪功能. 1.原理 MDC org.sl4j.MDC其实内部就是ThreadLocal,MDC提供了put/get/clear等几个核心接口,用于操作ThreadLocal中的数据:ThreadLocal中的K-V,可以在log

  • 微服务分布式架构实现日志链路跟踪的方法

    Logback 背景 Logback是由log4j创始人设计的另一个开源日志组件,官方网站:http://logback.qos.ch.它当前分为下面下个模块: logback-core:其它两个模块的基础模块 logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能 普通debug日志

  • 详解spring cloud分布式日志链路跟踪

    首先要明白一点,为什么要使用链路跟踪? 当我们微服务之间调用的时候可能会出错,但是我们不知道是哪个服务的问题,这时候就可以通过日志链路跟踪发现哪个服务出错. 它还有一个好处:当我们在企业中,可能每个人都负责一个服务,我们可以通过日志来检查自己所负责的服务不会出错,当调用其它服务时,这时候出现错误,那么就可以判定出不是自己的服务出错,从而也可以发现责任不是自己的. 基于微服务之间的调用开始,如果看不懂的小伙伴,请先参考我上篇博客:spring cloud中微服务之间的调用以及eureka的自我保护

  • 详解spring cloud分布式整合zipkin的链路跟踪

    为什么使用zipkin? 上篇主要写了:spring cloud分布式日志链路跟踪 从上篇中可以看出服务之间的调用,假设现在有十几台服务,那么在查找日志的时候比较繁琐.复杂,而且在查看调用的时候也会像蜘蛛网一样,量太大. 这时候zipkin可以把链路调用整个过程给升级起来,只需要到一个地方去查找,就可以知道哪一步出错. zipkin也分为服务器和客户端,服务器就是zipkin,微服务就是客户端. 首先,建立服务器zipkin 在此服务build.gradle加上zipkin的依赖: compil

  • SpringCloud分布式链路跟踪的方法

    注:作者使用IDEA + Gradle 注:需要有一定的java SpringBoot and SSM+Springcloud基础 程序测试错误追责 我举个例子,我现在要做一个电商项目,项目里面有一个购买模块,那我这边可能要执行一个代码,比如减库存之类的东西,那我两个服务不就是要相互调用嘛,我自身是一个服务,我现在要调用减库存这个服务: 你调用它,你知道它一定能执行成功吗?肯定是不一定: 比如说,我现在要执行一个减库存的代码,我调用这个方法会进行库存的一个更改,这个库存减少成功还好,万一要是失败

  • Spring Cloud 整合Apache-SkyWalking实现链路跟踪的方法

    什么是SkyWalking 查看官网https://skywalking.apache.org/ 分布式系统的应用程序性能监视工具,专为微服务.云原生架构和基于容器(Docker.K8s.Mesos)架构而设计. 安装 进入下载页面https://skywalking.apache.org/zh/downloads/ 这里用的是ElasticSearch 7版本,所以你需要安装完成ElasticSearch 7,不再赘述. 解压后,可以修改启动端口 apache-skywalking-apm-b

  • ASP.NET Core整合Zipkin链路跟踪的实现方法

    前言     在日常使用ASP.NET Core的开发或学习中,如果有需要使用链路跟踪系统,大多数情况下会优先选择SkyAPM.我们之前也说过SkyAPM设计确实比较优秀,巧妙的利用DiagnosticSource诊断跟踪日志,可以做到对项目无入侵方式的集成.其实还有一款比较优秀的链路跟踪系统,也可以支持ASP.NET Core,叫Zipkin.它相对于SkyWalking来说相对轻量级,使用相对来说比较偏原生的方式,而且支持Http的形式查询和提交链路数据.因为我们总是希望能拥有多一种的解决方

  • Dubbo实现分布式日志链路追踪

    技术场景 在日常的开发.测试或运维的过程中,经常存在这样的场景,开发人员在代码中使用日志工具(log4j.slf4j)记录日志,比如请求ID.IP等,方便在线上快速.精准的定位问题,通过完整的日志链路清晰的进行信息定位. 一般的项目都是分层的.分布式的,在众多的日志信息中,如何区分哪些日志信息是同一请求发出来的,详细的实现如下. 技术框架 项目框架:Spring boot 分布式协调:Zookeeper.Dubbo 日志工具:Sf4j 构建工具:Maven 开发工具:IDEA 项目框架 mdc-

  • 使用log4j MDC实现日志追踪

    目录 log4j MDC实现日志追踪 1.新建线程处理类 ThreadContext 2.添加工具类TraceUtil 3.添加ContextFilter 4.在webConfiguriation注册filter 5.修改log4j日志配置文件,设置日志traceId log4j2实现日志跟踪 日志跟踪 我们可以通过过滤器实现以上的功能 log4j MDC实现日志追踪 MDC 中包含的可以被同一线程中执行的代码所访问内容.当前线程的子线程会继承其父线程中的 MDC 的内容.记录日志时,只需要从

随机推荐