如何使用Spring Boot中的logback和SLF4J的MDC来捕获POST请求JSON中的唯一跟踪?

11
我们正在使用:
  • Spring Boot
  • Slf4J
  • Logback
  • 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>

请问有人能提供一些关于如何完成这个任务的帮助吗?

2个回答

9

抱歉,由于声望不够,我无法发表评论。这是根据@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");
        }
    }
}

9
您可以使用Logback的Mapped Diagnostic Context(映射诊断上下文)将唯一的跟踪号传播到每个日志消息中。
这包括两个部分:
1. 将您的唯一跟踪号推入MDC,例如:MDC.put("uniqueTrackingNumber", the_unique_tracking_number); 2. 在日志语句中包含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>

更多细节请查看文档

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

@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
您还需要清除MDC中的uniqueTrackingNumber吗? - ThomasRS
是的,请查看MDCInsertingServletFilter.doFilter()中的finally块,以获取该示例。 - glytching
4
使用 %mdc 命令,无需了解每个键的名称即可打印 MDC 中存在的多个值。 - codester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接