设置MDC以使用ServerInterceptor登录grpc-java的正确方法是什么?

时间:2019-05-31 14:08:18

标签: java grpc grpc-java

我想使用log4j2中的ThreadContext来设置MDC上下文键,例如request-iduser-id,以在日志中跟踪请求信息以进行调试。

我写了一个MdcInterceptor,它执行以下操作:

public class MdcInterceptor implements ServerInterceptor {

    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers,
                                                                 ServerCallHandler<ReqT, RespT> next) {
        ThreadContext.put("rid", generateId());
        return next.startCall(call, headers);
    }
}

不幸的是,由于似乎可能从具有不同ThreadContext的Server executor的不同线程中调用了不同的回调,因此无法正常工作。

我在这里https://github.com/grpc/grpc-java/issues/1949#issuecomment-226884288找到了一些解决方案,该解决方案指出ThreadContext应该在SimpleForwardingServerCallListener中的每个回调中设置。

事实是,就我而言,应尽可能在UserInfoInterceptor之后调用的不同MdcInterceptor中添加一些附加信息(某些身份验证用户信息需要令牌验证等)。我应该如何正确地将此信息添加到请求范围的ThreadContext

发布的解决方案是唯一可能的变体吗?我在SimpleForwardingServerCallListener中的每个超级调用周围进行try-finally块似乎有点奇怪,更不用说我应该在每个回调中设置一次上下文了。

1 个答案:

答案 0 :(得分:0)

您可以使用io.grpc.Context,它处理RPC特定信息到回调中的传播。在调用ClientCall.Listener(和StreamObserver)上的任何事件之前,gRPC库将安装正确的上下文。曾荫权(Ray Tsang)对如何使用API​​进行了good example的介绍。