springboot 下 logback + MDC的使用

背景

在项目中, 通过一个 orderId 字段来 贯穿 订单的一个执行过程。 通过 这个 orderId 可以解决 90%的问题排查效率问题,也不需要去 去定义 在 分布式系统中的一个 业务 id。 在刚开始时,业务简单,都是在 log.info 中 人工去写:

存在两个问题:

1、随着代码量越来越多,需要不断重复的在 日志中 写上 orderid,心累,同时 作为程序员,应该很 清楚 DRY 原则,

2、不同的人书写的 格式可能 大不相同,,且容易 遗漏。

3、项目会 调用 一个sdk 的三方 应用,目前是没有进行链路绑定的,这个目前还没有特别的好的方案, 但对 sdk的调用 用AOP做了 包装,输出 request和response, 可以 通过 MDC 同 orderId 绑定,方便 异常排查

springboot + MDC 实现 链路追踪

1、项目中实践

logback配置文件修改

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<!--    定义路径 -->
    <property name="LOG_PATH" value="logs"/>


    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%d] [%level] [orderId:%X{orderId}] [uuid:%X{uuid}] [%X{xRequestId}] %logger - %m%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">

        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

写了工具类

public class MdcUtil {

     public static final String ORDER_ID = "orderId";
     public static final String UUID = "uuid";

    public static void setOrderId(String value) {
        put(ORDER_ID, value);
    }
    public static void setUUid(String value) {
        put(UUID, value);
    }

    public static String getOrderId() {
        return MDC.get(ORDER_ID);
    }
  
    public static void put(String key, Object value) {
        if (key != null) {
            MDC.put(key, value.toString());
        }
    }

    public static void clear() {
        MDC.clear();
    }

}

在 代码中 目前没有统一用filter 或者Intercepter 进行处理,在请求中,目前 并没有统一,所以现在的方案是 针对每个 请求入口进行 侵入式操作。

MdcUtil.setOrderId(orderId);
MdcUtil.clear();

这样对 sdk 进行aop处理的过程中,就能 绑定 orderId 日志输出了。

2、注意点

1、实现的原理 其实比较简单,通过与 Thread 绑定, 所以在进行 线程切换后,需要 处理。

并且 不要 忘了进行 clear,否则在大量请求的情况下 容易造成 ThreadLocal 的 内存溢出。

2、目前只是对关键的执行过程进行了处理。 后面可以对所有的请求 通过 一个 全局的tranceId进行 绑定,贯穿请求的生命周期

3、原理

见参考文档。

4、思考

1、目前的编码方案,仅仅解决了 一些 代码的重复书写, 对 三方 调用进行aop 操作与 traceId 线程维度的关联

2、针对没有 业务标示的 请求, 目前没有操作。 需要 在请求入口进行 traceId的生成,或者前端请求传入,做成更通用的模版。 可以参考 sleuth,SkyWalking 这些开源的框架

参考:

SpringBoot项目中通过MDC和自定义Filter操作traceId实现日志链路追踪

SpringBoot+MDC实现全链路调用日志跟踪

Spring boot 全局参数传递和追踪

Slf4j MDC 使用和 基于 Logback 的实现分析

posted @ 2020-09-28 16:51  小烽  阅读(2168)  评论(0编辑  收藏  举报