Jim*_* M. 9 slf4j mdc spring-boot grpc grpc-java
我有一个 Spring-Boot 应用程序,我也在其中启动了 gRPC 服务器/服务。servlet 和 gRPC 代码都将请求发送到一个公共对象来处理请求。当请求进来时,我想更新日志以显示唯一的“ID”,以便我可以通过系统跟踪请求。
在 Spring 方面,我设置了一个“过滤器”,它更新日志记录 MDC 以向日志请求添加一些数据(请参阅此示例)。这工作正常
在 gRPC 方面,我创建了一个“ServerInterceptor”并将其添加到服务中,而拦截器被调用,更新 MDC 的代码不会粘住,因此当请求通过 gRPC 服务时,我没有打印出 ID日志。我意识到这与我在一个线程中拦截调用并且它在另一个线程中由 gRPC 调度这一事实有关,我似乎无法弄清楚如何在执行工作的线程中拦截调用或添加 MDC 信息,以便将其正确传播到执行工作的线程。
我做了很多搜索,很惊讶没有找到这个问题/答案,我只能假设我的查询技巧缺乏:(
我对 gRPC 相当陌生,这是我正在编写的第一个拦截器。我已经尝试以几种不同的方式添加拦截器(通过 ServerInterceptors.intercept、BindableService instance.intercept)。
我看过LogNet 的 Spring Boot gRPC Starter,但我不确定这是否能解决问题。
这是我在拦截器类中添加的代码
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> call, final Metadata headers, final ServerCallHandler<ReqT, RespT> next) {
try {
final String mdcData = String.format("[requestID=%s]",
UUID.randomUUID().toString());
MDC.put(MDC_DATA_KEY, mdcData);
return next.startCall(call, headers);
} finally {
MDC.clear();
}
}
Run Code Online (Sandbox Code Playgroud)
当请求通过 RESTful API 传入时,我会看到这样的日志输出
2019-04-09 10:19:16.331 [requestID=380e28db-c8da-4e35-a097-4b8c90c006f4] INFO 87100 --- [nio-8080-exec-1] c.c.es.xxx: processing request step 1
2019-04-09 10:19:16.800 [requestID=380e28db-c8da-4e35-a097-4b8c90c006f4] INFO 87100 --- [nio-8080-exec-1] c.c.es.xxx: processing request step 2
2019-04-09 10:19:16.803 [requestID=380e28db-c8da-4e35-a097-4b8c90c006f4] INFO 87100 --- [nio-8080-exec-1] c.c.es.xxx: Processing request step 3
...
Run Code Online (Sandbox Code Playgroud)
当请求通过 gRPC 服务时,我希望得到类似的输出。
谢谢
由于没有人回复,我不断尝试并为我的interceptCall函数提出了以下解决方案。我不是 100% 确定这为什么有效,但它适用于我的用例。
private class LogInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> call,
final Metadata headers,
final ServerCallHandler<ReqT, RespT> next) {
Context context = Context.current();
final String requestId = UUID.randomUUID().toString();
return Contexts.interceptCall(context, call, headers, new ServerCallHandler<ReqT, RespT>() {
@Override
public ServerCall.Listener<ReqT> startCall(ServerCall<ReqT, RespT> call, Metadata headers) {
return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(next.startCall(call, headers)) {
/**
* The actual service call happens during onHalfClose().
*/
@Override
public void onHalfClose() {
try (final CloseableThreadContext.Instance ctc = CloseableThreadContext.put("requestID",
UUID.randomUUID().toString())) {
super.onHalfClose();
}
}
};
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
在我的 application.properties 中,我添加了以下内容(我已经有了)
logging.pattern.level=[%X] %-5level
'%X' 告诉日志系统打印所有CloseableThreadContext键/值。
希望这可以帮助别人。
| 归档时间: |
|
| 查看次数: |
2104 次 |
| 最近记录: |