You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus访问日志未显示MDC内容:如何调整过滤器与日志顺序?

问题解决:Quarkus访问日志先记录MDC再清除的执行顺序调整

问题原因

Quarkus的访问日志记录时机晚于JAX-RS ContainerResponseFilter 的执行时机。你在ContainerResponseFilter中清除MDC后,访问日志才开始记录,导致访问日志无法获取到MDC内容。

解决方案

方案一:利用RequestScoped Bean的销毁时机清除MDC

创建一个请求作用域的Bean,在其销毁阶段(整个请求处理完成后,包括访问日志记录)清除MDC。

  1. 移除原LoggingFilter中ContainerResponseFilter的实现,仅保留请求过滤器设置MDC:
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.ext.Provider;
import org.jboss.logging.MDC;

@Provider
public class LoggingFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) {
        MDC.put("test", "testValue");
    }
}
  1. 创建请求作用域的MDC清理Bean:
import javax.enterprise.context.RequestScoped;
import javax.annotation.PreDestroy;
import org.jboss.logging.MDC;

@RequestScoped
public class MdcCleanupBean {

    @PreDestroy
    void cleanupMdc() {
        MDC.clear();
    }
}

请求处理流程变为:

  • 请求进入 → LoggingFilter设置MDC → 资源方法执行 → JAX-RS处理响应 → 发送响应给客户端 → Quarkus记录访问日志(此时MDC未被清除) → 请求作用域Bean销毁 → 清除MDC

方案二:使用Quarkus HttpServerFilter设置最高优先级

创建一个优先级最低(数值最大)的HttpServerFilter,确保在所有请求处理逻辑(包括访问日志记录)完成后再清除MDC。

  1. 保留原LoggingFilter的请求过滤器部分(仅设置MDC):
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.ext.Provider;
import org.jboss.logging.MDC;

@Provider
public class LoggingFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) {
        MDC.put("test", "testValue");
    }
}
  1. 创建HttpServerFilter用于清理MDC:
import io.quarkus.http.runtime.filter.HttpServerFilter;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import org.jboss.logging.MDC;

@HttpServerFilter(priority = Integer.MAX_VALUE)
public class MdcCleanupFilter implements io.quarkus.http.runtime.filter.Filter {

    @Override
    public void doFilter(HttpServerRequest request, HttpServerResponse response, Chain chain) throws Exception {
        try {
            chain.doFilter(request, response); // 执行所有后续请求处理(包括访问日志)
        } finally {
            MDC.clear(); // 所有处理完成后清除MDC
        }
    }
}

priority = Integer.MAX_VALUE 确保该过滤器是最后执行的,try-finally 保证无论请求是否异常,MDC都会被清除。

验证效果

调整后,访问日志的输出会包含MDC内容:

{"timestamp":"2023-11-24T16:06:08.434+03:00","sequence":1995,"loggerClassName":"org.jboss.logging.Logger","loggerName":"io.quarkus.http.access-log","level":"INFO","message":"127.0.0.1 - - 24/Nov/2023:16:06:08 +0300 \"GET /hello-resteasy HTTP/1.1\" 200 14","threadName":"executor-thread-0","threadId":85,"mdc":{"test":"testValue"},"ndc":"","hostName":"hj9xgjxrql","processName":"code-with-quarkus-dev.jar","processId":12056}

内容的提问来源于stack exchange,提问作者C. Bilgin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:09:52