zoukankan      html  css  js  c++  java
  • 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 的实现分析

  • 相关阅读:
    jQuery ajax传多个参数
    PHP 上传图片和安全处理
    PHP CI框架email类发送邮件
    2016-4-7
    jquery 轮播图
    CI控制器的继承问题
    2016-4-1
    2016-3-31 总结
    php内置函数call_user_func()
    discuz-目录
  • 原文地址:https://www.cnblogs.com/idea-persistence/p/13745625.html
Copyright © 2011-2022 走看看