Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grpclib support #2976

Open
DeoLeung opened this issue Apr 13, 2024 · 3 comments
Open

grpclib support #2976

DeoLeung opened this issue Apr 13, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@DeoLeung
Copy link

Problem Statement

I use grpclib as my gprc server implementation, sentry has a grpcio integration , but no grpclib

Solution Brainstorm

add grpclib support

@DeoLeung DeoLeung added the enhancement New feature or request label Apr 13, 2024
@szokeasaurusrex
Copy link
Member

Hi @DeoLeung, thank you for the suggestion!

We will place this issue on our backlog, but it might take us some time to get around to implementing a grpclib integration. However, we gladly accept PRs if you would like to contribute!

@bettdouglas
Copy link

Hi @szokeasaurusrex
I'd also be interesting in having this implemented.
How does one go about capturing the trace/monitor a specific run?

From https://grpclib.readthedocs.io/en/latest/events.html,

Given a server

from grpclib.events import (RecvRequest, SendInitialMetadata, SendMessage,
                            SendTrailingMetadata, listen)


def setup_server_logger(server: Server):
    logger = logging.getLogger('ChatServiceLogger')
    async def recv_request(event: RecvRequest):
        # Dispatches after request was received from the client
        # event.metadata['request-id'] = str(uuid.uuid4())
        logger.info(f'---------\nRecevied RequestID: {event.metadata.get('request-id')}\nMethodName:{event.method_name}\nMetadata: {str(list(event.metadata.keys()))}\nUser-Agent:{event.user_agent}\n---------\n\n')

    async def send_message(event: SendMessage):
        # Dispatches before sending message to the client
        logger.info(f'---------\nSending Response : {type(event.message)}\n---------\n\n')

    async def send_trailing_metadata(event: SendTrailingMetadata):
        # Dispatches before sending trailers with trailing metadata to the client
        logger.info(f'---------\nClosing RequestID: {event.metadata.get('request-id')}\nMetadata: {str(list(event.metadata.keys()))}\nStatus:{event.status}\nStatusMessage:{event.status_message}\nStatusDetails:{event.status_details}\n---------\n\n')

    async def send_initial_metadata(event: SendInitialMetadata):
        # Dispatches before sending headers with initial metadata to the client
        event.metadata['request-id'] = str(uuid.uuid4())
        logger.info(f'---------\nSendingInitialMetadata: {str(event.metadata)}')



    listen(server, RecvRequest, recv_request)
    listen(server,SendMessage,send_message)
    listen(server,SendTrailingMetadata,send_trailing_metadata)
    listen(server,SendInitialMetadata,send_initial_metadata)


if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    async def main():
        for _ in ('databases','test'):
            logging.getLogger(_).setLevel(logging.CRITICAL)

        database_url = db.create_postgres_conn_string()
        database = await db.get_database(conn_string=database_url)
        await db.create_tables(database)

        server = Server([ChatService(loop=loop, db=database)])
        setup_server_logger(server=server)


        port = int(os.environ.get("PORT", "50051"))
        await server.start("0.0.0.0", port)
        print(f"Server running on {port}")

        await server.wait_closed()

    loop.run_until_complete(main())

How would one go about implementing tracing the request from start to completion?

@sl0thentr0py
Copy link
Member

sl0thentr0py commented Apr 24, 2024

@bettdouglas i'm not sure if those events will suffice but I haven't read the source of the library in detail.
For instance, RecvRequest will trigger on receive, but you also need another event to signal that the processing of the request has completed.


IF you also have that event, then you can basically

  • use sentry_sdk.start_transaction on request start and save that transaction somewhere and call transaction.finish() once the request ends
  • use sentry_sdk.start_span in other events to record spans within that transaction

However, since the other event doesn't seem to be available, the best way might just be to monkeypatch request_handler and use the with sentry_sdk.start_transaction context manager like we do in most other integrations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: No status
Development

No branches or pull requests

4 participants