Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inspect clients that are connected to a GRPC server

To provide better debugging information for my GRPC server/client setup, I am trying to find an API for grpc.server that allows me to inspect what clients are connected to the server.

The most promising question I have found is question, which gives a starting point on how to do this in Java GRPC. However, the Java API doesn't exist in the Python GRPC implementation.

So far, I keep track of unique peers using the context.peer() method in a grpc.ServicerContext. If a peer hasn't sent a request in a while (a timeout I set to 2 seconds) I assume the client has disconnected.

I've started looking at the python-grpc source code but I haven't made any headway.

If anyone knows of a similar API in python I could use, that would be appreciated! Even an internal API would be sufficient for these debugging needs.

like image 808
pmelanson Avatar asked Jul 27 '19 03:07

pmelanson


3 Answers

I found some more documentation and examples of channelz, other people have been suggesting it and it seems like what you want.

Here's a pull request that gives an example of channelz being used. It only uses the GetServer channelz API, so you'll have to adapt it.

And here's a unit test that uses channelz, which tests APIs that are probably relevant GetTopChannels API.

like image 104
trainer-blue Avatar answered Oct 09 '22 12:10

trainer-blue


There isn't a native API for this, but you have all of the pieces you need. Here's a modified version of the helloworld example from the repo.

class PeerSet(object):
    def __init__(self):
        self._peers_lock = threading.RLock()
        self._peers = {}

    def connect(self, peer):
        print("Peer {} connecting".format(peer))
        with self._peers_lock:
            if peer not in self._peers:
                self._peers[peer] = 1
            else:
                self._peers[peer] += 1

    def disconnect(self, peer):
        print("Peer {} disconnecting".format(peer))
        with self._peers_lock:
            if peer not in self._peers:
                raise RuntimeError("Tried to disconnect peer '{}' but it was never connected.".format(peer))
            self._peers[peer] -= 1
            if self._peers[peer] == 0:
                del self._peers[peer]

    def peers(self):
        with self._peers_lock:
            return self._peers.keys()


class Greeter(helloworld_pb2_grpc.GreeterServicer):

    def __init__(self):
        self._peer_set = PeerSet()

    def _record_peer(self, context):
        def _unregister_peer():
            self._peer_set.disconnect(context.peer())
        context.add_callback(_unregister_peer)
        self._peer_set.connect(context.peer())

    def SayHello(self, request, context):
        self._record_peer(context)
        for i in range(10):
            print("[thread {}] Peers: {}".format(threading.currentThread().ident, self._peer_set.peers()))
            time.sleep(1)
        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)

This will get you output like the following:

[thread 139905506195200] Peers: [u'ipv6:[::1]:57940', u'ipv6:[::1]:57930', u'ipv6:[::1]:57926', u'ipv6:[::1]:57920', u'ipv6:[::1]:57934']

As Ding commented above, channelz may also be a good fit for you.

like image 1
Richard Belleville Avatar answered Oct 09 '22 11:10

Richard Belleville


There is one tool grpcdebug, it could inspect clients that are connected to a GRPC server.

grpcdebug is a command line interface focusing on simplifying the debugging process of gRPC applications. grpcdebug fetches the internal states of the gRPC library from the application via gRPC protocol and provide a human-friendly UX to browse them. Currently, it supports Channelz/Health Checking/CSDS (aka. admin services)

grpcdebug is an gRPC service admin CLI

Usage:
  grpcdebug <target address> [flags] <command>

Available Commands:
  channelz    Display gRPC states in human readable way.
  health      Check health status of the target service (default "").
  help        Help about any command
  xds         Fetch xDS related information.
like image 1
zangw Avatar answered Oct 09 '22 10:10

zangw