0

问题

当请求进入服务器时,我想询问标头并查看是否有特定标头,如果是,我想获取该标头值并将其添加到 SLF4Js MDC,如果它不存在,我将生成我的拥有(见下面的代码)。

问题

我是第一次使用 Micronaut (v2.5.5),使用 Spring Boot 已经有一段时间了。使用 Spring Boot,我能够添加一个Filter方法,该方法会将请求 ID 添加到 SLF4Js MDC 上下文中,以便在记录元素时将其包含在日志消息中。

例子

2021-07-01 19:12:57.104 LogLevel=INFO rid=3568b2d7-d8f1-4d7d-9e8d-49f2be727255, 1 --- [nio-8080-exec-8] .....

这在 Micronaut 中失败了,我认为是因为请求可以在线程之间传递,并且 MDC 是特定于线程的。

例子

2021/01/07 18:50:05.021 信息 [qtp1561347421-43] ccdex.css.controllers.MyEndpoint rid= - .....

Micronaut 中是否有任何机制来支持此功能而无需切换到 Jaeger 等...?如果是这样,那是什么?

这是我尝试过的代码,它不起作用

@Slf4j
@Filter("/v1.0/**")
public class RequestId extends OncePerRequestHttpServerFilter {
    public static final String X_REQUEST_ID = "X-REQUEST-ID";
    public static final String RID = "rid";

    @Override
    protected Publisher<MutableHttpResponse<?>> doFilterOnce(HttpRequest<?> request, ServerFilterChain chain) {
        // Was a request ID passed in, if so grab it
        String requestID = request.getHeaders().get(X_REQUEST_ID);
        if (null == requestID) {
            // no create it
            requestID = UUID.randomUUID().toString();
        }
        log.info("Storing RID in MDC and request: " + requestID);
        MDC.put(RID, requestID);
    }

我确实尝试将rid放在请求对象中(传递到doFilter),然后在我的控制器中使用它,例如

@Controller(value = "v1.0/")
public class XmlEndpoint {
    @Post(uri = "request")
    public MyResponse request(@NonNull @Body(value = "MyRequest") MyRequest request) {
        Optional<HttpRequest<Object>> optionalReq = ServerRequestContext.currentRequest();
            if (optionalReq.isPresent()) {
                HttpRequest<Object> curRequest = optionalReq.get();
                // Get the request ID from the request
                MDC.put(RequestId.RID, (String) curRequest.getAttribute(X_REQUEST_ID).orElse(UNKNOWN_RID));
            }
....
    }
}

在这种情况下,日志消息包含 RID,但这似乎有点令人费解。

我进行了搜索,看到了我的想法,但是有几个相关的问题;答案没有多大意义(Micronaut 新手,对不起),或者似乎没有一个解决方案来显示需要做什么。

提前致谢

4

0 回答 0