簡體   English   中英

Spring Boot 過濾器沒有過濾我所有的日志

[英]Spring Boot Filter not filtering all my logs

我在 Spring Boot 應用程序中設置了一個過濾器來向 MDC 添加一些信息:

@Component
public class LogFilter implements Filter {

    @Override
    public void init(FilterConfig var1) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        try {
            MDC.put("tag", "Some information);
            chain.doFilter(request, response);
        } finally {
            MDC.clear();
        }
    }
    @Override
    public void destroy() { }
}

這對於我的大多數應用程序來說都很好,但是對於生成線程的某些操作,此過濾器不會接收這些消息。

例如,在下面的塊中,回調方法發生在一個單獨的線程中,所以第一個log.info調用被我的LogFilter ,但我的回調中的log.infolog.error不是。

private void publishMessage(String message) {
    log.info("Message received. Sending to Kafka topic");
    CompletableFuture<ListenableFuture<SendResult<String, String>>> future = CompletableFuture.supplyAsync(() -> kafkaTemplate.send("myTopic", message));

    try {
        future.get().addCallback(new ListenableFutureCallback<SendResult<String, String>>() {

            @Override
            public void onSuccess(SendResult<String, String> result) {
                log.info("Kafka topic " + myTopic + " published to successfully");
            }

            @Override
            public void onFailure(Throwable ex) {
                log.error("Kafka error: " + ex.getMessage());
            }
        });
        } catch (Exception e) {
            log.error("Kafka has failed you for the last time");
        }
    }

一般來說,似乎沒有在http-nio-8080-exec-X線程之一中發生的任何日志事件都會繞過LogFilter 我究竟做錯了什么?

我嘗試過但沒有奏效的事情:

  1. LogFilter延長GenericFilterBean ,使用@Bean代替@Component ,然后注冊這個bean與FilterRegistrationBean在我的主應用程序類
  2. 使用@WebFilter(urlPatterns = {"/*"}, description = "MDC Filter")和/或@ServletComponentScan

MDC 上下文僅適用於當前正在運行的線程,但您的回調將在不同的線程中調用。

處理它的一種方法是實現ListenableFutureCallback

private static class MyListenableFutureCallback
              implements ListenableFutureCallback<SendResult<String, String>> {

            private Map<String,String> contextMap = MDC.getCopyOfContextMap();

            @Override
            public void onSuccess(SendResult<String, String> result) {
                MDC.setContextMap(contextMap); //add MDC context here
                log.info("Kafka topic " + myTopic + " published to successfully");
            }

            @Override
            public void onFailure(Throwable ex) {
                MDC.setContextMap(contextMap); //add MDC context here
                log.error("Kafka error: " + ex.getMessage());
            }
    }

最后:

future.get().addCallback(new MyListenableFutureCallback()).

這里描述了一種更一致的方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM