For unary and client streaming calls, you can access to the response message
by looking at the return of the continuation before you return from your
interceptor.
Here's a slight modification of the example UnaryServerHandler method in
ServerLoggerInterceptor.cs [0] that highlights where you can look at the
response message:
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
LogCall<TRequest, TResponse>(MethodType.Unary, context);
try
{
TResponse response = await continuation(request, context);
// you have access to the response message here
return response;
}
catch (Exception ex)
{
// Note: The gRPC framework also logs exceptions thrown by handlers to .NET Core logging.
_logger.LogError(ex, $"Error thrown by {context.Method}.");
throw;
}
}
For server streaming and duplex calls, your interceptor can pass its own
implementation of IServerStreamWriter to the continuation. Then, it will be
able to see the calls to WriteAsync to be able to inspect the messages. It
will also have to forward those on to the original IServerStreamWriter
implementation. For example (warning: email code, not tested):
public class ObservingServerStreamWriter<TResponse> : IServerStreamWriter<TResponse>
{
private readonly IServerStreamWriter<TResponse> _inner;
public ObservingServerStreamWriter(IServerStreamingWriter<IServerStreamWriter> inner)
{
_inner = inner;
// capture whatever other state you need here
}
public WriteOptions? WriteOptions
{
get { return _inner.WriteOptions }
set { _inner.WriteOptions = value; }
}
public Task WriteAsync<TResponse>(T message)
{
// you can observe message here
return _inner.WriteAsync(message);
}
}
--
Christopher Warrington
Microsoft Corp, but not on the gRPC team
[0]:
https://github.com/grpc/grpc-dotnet/blob/207e8066f3ed2f6c656e565c07c746e282f54ff4/examples/Interceptor/Server/ServerLoggerInterceptor.cs#L33-L51