【问题标题】:How to use MDC of logback and SLF4J with spring boot to capture unique tracking in the POST request json?如何在 Spring Boot 中使用 logback 的 MDC 和 SLF4J 来捕获 POST 请求 json 中的唯一跟踪?
【发布时间】:2017-10-04 11:07:12
【问题描述】:

我们正在使用:

  • 春季启动
  • Slf4J
  • 回退
  • ELK 栈

现在我们想使用 MDC 将 POST 请求 JSON 中提供的唯一跟踪号添加到给定请求的每个日志语句中。

我在谷歌上搜索了一些博客文章,这些文章对我没有多大用处。

下面是我们使用的logback.xml

<configuration>
    <property name="PROJECT_ID" value="template-api"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

谁能提供一些关于如何完成这项工作的帮助?

【问题讨论】:

    标签: logging spring-boot logback slf4j mdc


    【解决方案1】:

    抱歉,没有足够的代表来写评论。这是基于@glytching 答案的更正确、更完整的代码:

    @Component
    public class MDCFilter extends OncePerRequestFilter {
    
        @Autowired
        private TrackingnumberGenerator trackGen;
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            MDC.put("trackingNumber", trackGen.getTrackingNumber());
            try {
                filterChain.doFilter(request, response);
            } finally {
                MDC.remove("trackingNumber");
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用 Logback 的 Mapped Diagnotic Context 将唯一的跟踪号传播到每条日志消息。

      这有两个部分:

      • 将您的唯一跟踪号推送到 MDC,例如MDC.put("uniqueTrackingNumber", the_unique_tracking_number);

      • 在您的日志语句中包含 MDC 条目。您可以通过在日志记录模式中指定它来做到这一点。因此,如果您将唯一跟踪号存储在名为 uniqueTrackingNumber 的 MDC 条目中,那么您可以通过定义如下布局将其包含在发出的日志事件中:

      <layout class="ch.qos.logback.classic.PatternLayout">
          <Pattern>
              %d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{uniqueTrackingNumber}] %-5level %logger{36} - %msg%n
          </Pattern>
      </layout>
      

      更多详情in the docs

      我认为“唯一跟踪号”的范围仅限于请求(或通过您的应用程序的单个“流”)?如果是这样,那么您将需要确定一些节流点,您可以在其中推动 MDC 值。在 Spring Boot 世界中,这可能是Filter。可能是这样的:

      @Component 
      public static class UniqueTrackingNumberFilter extends OncePerRequestFilter() {
      
          @Override
          protected abstract void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                          throws ServletException, IOException {
              // presumably this is extracted from the request (or defaulted, if not supplied)
              int uniqueTrackingNumber = ;
              MDC.put("uniqueTrackingNumber", uniqueTrackingNumber);
          }
      }
      

      或者,您可以扩展 Logback 的 MDCInsertingServletFilter 以从请求中提取您想要的任何内容并将其推送到 MDC。

      【讨论】:

      • 您还需要从 MDC 中清除 uniqueTrackingNumber 吗?
      • 是的,看看 MDCInsertingServletFilter.doFilter() 中的 finally 块就是一个例子。
      • 使用 %mdc 打印 MDC 中存在的多个值,而不必知道每个键
      猜你喜欢
      • 2018-04-24
      • 2023-04-04
      • 1970-01-01
      • 2020-02-18
      • 2018-11-08
      • 1970-01-01
      • 2016-02-02
      • 2014-10-08
      • 2019-01-15
      相关资源
      最近更新 更多