I'm attempting to add instrumentation to our gRPC service implementations using a ServerInterceptor, namely failure rates on a per-method basis. To do this, I'm using a SimpleForwardingServerCall, overriding the close method and then checking the status to see if the call succeeded.
When an unchecked exception is thrown from a service implementation:
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
throw new RuntimeException("BOOM!");
}
and given an interceptCall method that looks something like this:
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
MethodDescriptor<ReqT, RespT> method,
ServerCall<RespT> call,
final Metadata requestHeaders,
ServerCallHandler<ReqT, RespT> next) {
return next.startCall(method, new SimpleForwardingServerCall<RespT>(call) {
@Override
public void close(Status status, Metadata trailers) {
logger.info("ERROR ENCOUNTERED"); // <-- never see this
super.close(status, trailers);
}
}, requestHeaders);
}
the close method is never called, so there isn't an opportunity to log the failure.
The exception seems to bubble up to the Executor instead:
Mar 15, 2016 12:26:59 PM io.grpc.internal.SerializingExecutor$TaskRunner run
SEVERE: Exception while executing runnable io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$2@3e694e4a
java.lang.RuntimeException: BOOM!
at io.grpc.examples.helloworld.HelloWorldServer$GreeterImpl.sayHello(HelloWorldServer.java:98)
at io.grpc.examples.helloworld.GreeterGrpc$MethodHandlers.invoke(GreeterGrpc.java:161)
at io.grpc.stub.ServerCalls$1$1.onHalfClose(ServerCalls.java:147)
at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.halfClosed(ServerCallImpl.java:255)
at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$2.runInContext(ServerImpl.java:458)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:54)
at io.grpc.internal.SerializingExecutor$TaskRunner.run(SerializingExecutor.java:154)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
I've also tried returning a ForwardingServerCallListener from interceptCall and the onComplete callback is invoked, but it doesn't have enough information for me to determine if the call was a failure.
Is there another API I can take a look at that will allow me to capture these failures?
I'm attempting to add instrumentation to our gRPC service implementations using a
ServerInterceptor, namely failure rates on a per-method basis. To do this, I'm using aSimpleForwardingServerCall, overriding theclosemethod and then checking the status to see if the call succeeded.When an unchecked exception is thrown from a service implementation:
and given an
interceptCallmethod that looks something like this:the
closemethod is never called, so there isn't an opportunity to log the failure.The exception seems to bubble up to the Executor instead:
I've also tried returning a
ForwardingServerCallListenerfrominterceptCalland theonCompletecallback is invoked, but it doesn't have enough information for me to determine if the call was a failure.Is there another API I can take a look at that will allow me to capture these failures?