title: Intercepting/Logging requests and Responses in GRPC
body: <p>I'm developing a chat app using GRPC in which the server receives information from the client and sends it back out to all the clients connected to it. For this, I've used <em>Saturnism's</em> <a href="https://github.com/saturnism/grpc-java-demos/tree/master/chat-example" rel="noreferrer">chat-example</a> as a reference. I've replicated the code, the code compiles and runs but the server supposedly never receives any requests from client. </p>
  
  <p>My question is:</p>
  
  <ol>
  <li>Is there a way to enable verbos server side and client side logging in GRPC to see what requests and responses are going in and out &amp; what might be failing?</li>
  <li>I'm using the following code for server and client. What might be missing/wrong in the following code that's resulting in no communication between client and server.</li>
  </ol>
  
  <p><strong>WingokuServer.java</strong></p>
  
  <pre><code>public class WingokuServer {
      public static void main(String[] args) throws IOException, InterruptedException {
          Server server = ServerBuilder.forPort(8091)
                  .intercept(recordRequestHeadersInterceptor())
                  .addService(new WingokuServiceImpl())
                  .build();
  
          System.out.println("Starting server...");
          server.start();
          System.out.println("Server started!");
          server.awaitTermination();
      }
  </code></pre>
  
  <p><strong>WingokuServerSideServiceImplementation:</strong></p>
  
  <pre><code>public class WingokuServiceImpl extends WingokuServiceGrpc.WingokuServiceImplBase {
      private static Set&lt;StreamObserver&lt;Response&gt;&gt; observers =
              Collections.newSetFromMap(new ConcurrentHashMap&lt;&gt;());
  
      public WingokuServiceImpl() {
          System.out.println("WingokuServiceImp");
      }
  
      @Override
      public StreamObserver&lt;Request&gt; messages(StreamObserver&lt;Response&gt; responseObserver) {
          System.out.println("messages");
          observers.add(responseObserver);
          return new StreamObserver&lt;Request&gt;() {
              @Override
              public void onNext(Request request) {
                  System.out.println("Server onNext: ");
                  System.out.println("request from client is: "+ request.getRequestMessage());
                  Response response = Response.newBuilder().setResponseMessage("new Message From server at time: "+ System.nanoTime()).build();
                  for (StreamObserver&lt;Response&gt; observer : observers) {
                      observer.onNext(response);
                  }
              }
  
              @Override
              public void onError(Throwable throwable) {
                  System.out.println("Server onError: ");
                  throwable.printStackTrace();
              }
  
              @Override
              public void onCompleted() {
                  observers.remove(responseObserver);
                  System.out.println("Server onCompleted ");
              }
          };
      }
  }
  </code></pre>
  
  <p><strong>WingokuClient:</strong></p>
  
  <pre><code>public class WingokuClient {
      public static void main(String[] args) {
          ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8091).usePlaintext(true).build();
          WingokuServiceGrpc.WingokuServiceStub asyncStub = WingokuServiceGrpc.newStub(channel);
          StreamObserver&lt;Request&gt; requestStreamObserver = asyncStub.messages(new StreamObserver&lt;Response&gt;() {
              @Override
              public void onNext(Response response) {
                  System.out.println("Client onNext");
                  System.out.println("REsponse from server is: "+ response.getResponseMessage());
              }
  
              @Override
              public void onError(Throwable throwable) {
                  System.out.println("Client onError");
                  throwable.printStackTrace();
              }
  
              @Override
              public void onCompleted() {
                  System.out.println("Client OnComplete");
              }
          });
  
          requestStreamObserver.onNext(Request.newBuilder().setRequestMessage("Message From Client").build());
          requestStreamObserver.onCompleted();
          channel.shutdown();
          System.out.println("exiting client");
      }
  }
  </code></pre>
  
  <p><strong>Edit:</strong></p>
  
  <p>There is nothing wrong with the code. It works. I just needed to add awaitTermination to the client's channel because without it just closes the connection between client and server instantly, probably even before the requests go out of the client onto the network. That's why the server never received any requests.</p>
  
  <p>However my question for enabling verbose logging and/or adding some sort of interceptor to the server side still remains unanswered. So I'm looking forward to getting some pointers from experts here.</p>