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

gRPC integration and aio interceptors #2369

Merged
merged 63 commits into from Nov 8, 2023

Conversation

fdellekart
Copy link
Contributor

This PR builds on the changes pushed to #2055 . The commits from there were squashed and reworded to adhere to standards described in the contributing guidelines.

Overall, the following functionality was added:

  • Client and server interceptors to instrument gRPC calls.
  • A gRPC integration to monkeypatch the gRPC functions used for channels and servers.

What's still missing:

  • unary_stream interceptor for the client, I didn't yet get to looking into that into detail.

ali.sorouramini and others added 11 commits August 6, 2023 16:55
…de channels

The integration monkeypatches the functions used to create channels on the
client side so the channel does not have to be explicitly intercepted by users.
Also previous logic was limited to interceptors being a list,
however, it is typed as a general sequence in grpc package.
Opened an issue in grpc repo to ask if this is inteded behaviour
If it should be changed one day the the .add method of the metadata
object would avoid reconstructing the whole client call details.

Link to issue:
grpc/grpc#34298
sentry_sdk/integrations/grpc/aio/client.py Outdated Show resolved Hide resolved
sentry_sdk/integrations/grpc/aio/client.py Outdated Show resolved Hide resolved
sentry_sdk/integrations/grpc/__init__.py Outdated Show resolved Hide resolved
sentry_sdk/integrations/grpc/aio/__init__.py Show resolved Hide resolved
@antonpirker antonpirker self-assigned this Sep 18, 2023
@fdellekart
Copy link
Contributor Author

fdellekart commented Sep 22, 2023

I made the changes you suggested @alisoam , thx for raising 👍 😄

Started writing the unary-stream client interceptor for async also, however, I would need some clarification on this topic. I am not extremely familiar with those functionalities and would rather first coordinate.

Is the behavior implemented in the sync version for unary-stream the desired one? It creates one span when the request is incoming which ends as soon as the UnaryStreamCall object obtained from the continuation is returned. However, this is only half the story, because AFAIU later the client will iterate over that object to obtain the individual messages from the server.

So I think the solution could be to return a custom UnaryStreamCall object which wraps also the read method of the underlying object into a span. Due to my atm quite limited understanding of the internals of this, this is mostly guesswork, however.

If there's somebody here who can give me a bit more of an insight I can add it to this PR, else I'd suggest opening a follow up issue for the other types of calls (stream-unary and stream-stream were not touched yet at all) 👍 😉

@antonpirker
Copy link
Member

Hey! I am looking at this now. One first thing, could you fix the type errors in the failed check CI / Lint Sources? (You can run the linting locally with ./scripts/runtox.sh linters. At least I hope this works in your local environment)

@antonpirker
Copy link
Member

@fdellekart About your question about the "sync version for unary-stream" behavior. I am really not deep into grpc. But I guess for the first version this behavior should be OK. We can always release an update to the integration to improve things. For now I would say we try to bring this out the door.

@antonpirker
Copy link
Member

antonpirker commented Sep 27, 2023

I am trying to test this and I have a example script resembling this: https://stackoverflow.com/a/63020695/300572

And I get this error:

grpc.aio._call.AioRpcError: <AioRpcError of RPC that terminated with:
        status = StatusCode.UNKNOWN
        details = "Unexpected <class 'TypeError'>: object HelloReply can't be used in 'await' expression"
        debug_error_string = "UNKNOWN:Error received from peer  {created_time:"2023-09-27T16:03:03.322818+02:00", grpc_status:2, grpc_message:"Unexpected <class \'TypeError\'>: object HelloReply can\'t be used in \'await\' expression"}"

Can you tell me what I am doing wrong @fdellekart ?

@antonpirker
Copy link
Member

antonpirker commented Sep 28, 2023

One question @fdellekart or @alisoam

Previously users had to set the interceptors by hand (see https://docs.sentry.io/platforms/python/configuration/integrations/grpc/) and with this update this is done automatically, if the GRPCIntegration is added.

If people add now the new GRPCIntegration and forget to remove the "adding interceptors by hand", will this be a problem? Will then be two interceptors do the same thing? Can we make this somehow backwards compatible?

Of if there is already the Sentry interceptor present, do not add it again (when calling grpc.intercept_channel() and in the new _wrap_*() functions)?

@fdellekart
Copy link
Contributor Author

Thank you for the clarifications, I already fixed the linters and added the async interceptor for unary-stream, will add some more tests and then push everything in the upcoming days.

Regarding the error described above, I started the greeter service and client from the official gRPC examples with the integration and I unfortunately can't reproduce your error. What script are you using as the server? As you are getting a response I assume the issue is there somewhere.

Good point regarding the backwards compatibility, I will add some logic to only add the interceptor when not yet present 👍

@fdellekart
Copy link
Contributor Author

@antonpirker I now fixed the described issues and also added tests to avoid that the integration breaks functionality of currently unsupported RPC types.

The other RPC types apart from unary-unary and unary-stream are now only implemented so that the integration works with them, but there is not yet any tracing supported, whilst the second one is only supported on the client side. I think for now that's enough and from my side, this is good to go to not let this PR grow bigger than it must be.

As soon as I get to it I will open a follow-up PR to implement tracing and error handling for the other RPC types if nobody else does so before me 👍 😃

AFAIU I cannot trigger the test and linters pipelines myself, so let me know if there's anything I can still help with after those have run 👍

@fdellekart
Copy link
Contributor Author

Also on the last commit I pushed I found a bug in the sync version of the gRPC unary stream client interceptor. It's getting stuck when trying to add the status code to the span. No clue if this worked with older gRPC versions because it was not tested yet.

On reply to that: There's an issue open in grpc on that topic already, for now we can't have the status code on the streaming response because of it.

@antonpirker
Copy link
Member

Thanks for the update!
I fixed some smaller linting issues.
I will probably look at this tomorrow, because I am in the middle of something right now.

@antonpirker
Copy link
Member

Sorry for not yet looking at this. I am finishing up something else and then I will look at this. Hopefully this week.

@antonpirker
Copy link
Member

Hey @fdellekart

Sorry, was caught up with other stuff, but I try to push this over the finish line until tomorrow.

@antonpirker
Copy link
Member

I made a change, to have nicer transaction names in the async server intercepter. @fdellekart can you have a look at the commit: 7be1306 and tell me if having this _find_name not a static method but a normal method can cause any problems?

@antonpirker
Copy link
Member

Also updated the docs: getsentry/sentry-docs#8434

@fdellekart
Copy link
Contributor Author

I made a change, to have nicer transaction names in the async server intercepter. @fdellekart can you have a look at the commit: 7be1306 and tell me if having this _find_name not a static method but a normal method can cause any problems?

Shouldn't be a problem 👍

@antonpirker
Copy link
Member

antonpirker commented Nov 8, 2023

Nice! So now everything is ready. We on our end just need to fix the problem with the aws tests (they use github secrects and PRs from outside our organization can not access them)

As soon as we have this figured out we can merge and it will be available in the next release (which will be this or next week)!

Copy link
Member

@antonpirker antonpirker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks very good now! 💯

@antonpirker antonpirker merged commit 76af9d2 into getsentry:master Nov 8, 2023
312 of 314 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants