如何使用弹回的MDC和SLF4J来捕获POST请求json中的唯一跟踪?

时间:2017-10-04 11:07:12

标签: logging spring-boot logback slf4j mdc

我们正在使用:

  • Spring Boot
  • SLF4J
  • 的logback
  • ELK stack

现在我们要使用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>

有人可以提供一些如何完成这项工作的帮助吗?

2 个答案:

答案 0 :(得分:1)

您可以使用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。

答案 1 :(得分: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");
        }
    }
}