Skip to content

feat(tracing): GraphQL and Apollo Integrations #3953

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

Merged
merged 15 commits into from
Jun 10, 2022

Conversation

onurtemizkan
Copy link
Collaborator

@onurtemizkan onurtemizkan commented Sep 2, 2021

Summary:

This PR introduces basic tracing functionality for server-side GraphQL query resolutions.
My original intent was to implement a single generic integration for GraphQL but trying to patch resolvers inside graphql-js ended up being very painful (if not impossible) as most of the resolver-level execution logic is strictly unexposed and there seem to be no instances that store resolvers we can monkey-patch.

So I ended up implementing two integrations for both GraphQL and Apollo.

  • GraphQL integration has very basic functionality and simply works as the parent node for all resolvers in the execution tree when used with Apollo. Without Apollo, it's just a simple span for the whole GQL execution process. But may still be useful.

  • Apollo integration works on the resolver level, supports nested resolutions, and treats DB operations as children.

I think there is a lot of room for improvement for both integrations. But wanted to get opinions and reviews before investing more time in them.

Resolves: #3774

@github-actions
Copy link
Contributor

github-actions bot commented Sep 2, 2021

size-limit report

Path Size
@sentry/browser - CDN Bundle (gzipped) 22.49 KB (+0.02% 🔺)
@sentry/browser - Webpack 23.37 KB (0%)
@sentry/react - Webpack 23.4 KB (0%)
@sentry/browser + @sentry/tracing - CDN Bundle (gzipped) 29.96 KB (+0.13% 🔺)

@onurtemizkan onurtemizkan marked this pull request as ready for review September 3, 2021 13:02
@kamilogorek kamilogorek marked this pull request as draft September 14, 2021 14:48
@kamilogorek kamilogorek marked this pull request as ready for review September 14, 2021 14:49
@kamilogorek kamilogorek changed the title [WIP] feat(tracing): GraphQL and Apollo Integrations feat(tracing): GraphQL and Apollo Integrations Sep 14, 2021
@thinkocapo
Copy link

Hi @onurtemizkan I worked with these developers on these blog articles, this one used a Resolver in his approach too
https://blog.sentry.io/2021/08/31/guest-post-performance-monitoring-in-graphql

and this used didEncounterErrors for error monitoring
https://blog.sentry.io/2020/07/22/handling-graphql-errors-using-sentry

@onurtemizkan
Copy link
Collaborator Author

Hi @thinkocapo, yeah I guess that's the sensible way to trace GraphQL transactions. Just if we could track GraphQL resolvers without relying on Apollo (as resolver is a core GraphQL concept), our plugin would be available for a wider range of projects. But still, this works, and most projects are using Apollo anyways, so we should be fine for now.

@github-actions
Copy link
Contributor

This pull request has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@andreialecu
Copy link
Contributor

Hi @onurtemizkan I worked with these developers on these blog articles, this one used a Resolver in his approach too blog.sentry.io/2021/08/31/guest-post-performance-monitoring-in-graphql

and this used didEncounterErrors for error monitoring blog.sentry.io/2020/07/22/handling-graphql-errors-using-sentry

The approach in the first blog post doesn't work properly when batching is involved, or when a request contains multiple queries.

Here's a more detailed report of what I mean: https://forum.sentry.io/t/transactions-with-graphql/13702

To clarify, it completely breaks down with https://www.apollographql.com/docs/react/api/link/apollo-link-batch-http/

I'm hoping the approach in this PR works better in this regard.

Is there anything missing here?

@rhcarvalho
Copy link
Contributor

Hi @onurtemizkan! Could you please help me summarize the current status for this PR?

Are we settled on the current approach?
Any drawbacks to be documented?
Any work pending?
Ready for a pass of code reviews?
What are the most important decisions and assumptions that were made that reviewers should be aware of?

Thanks!

@onurtemizkan
Copy link
Collaborator Author

Hi @rhcarvalho. At this stage, it would be wonderful to get some reviews about the approach taken.

The summary of this approach:

  • The original request about tracing functionality [Apollo tracing integration package? #3774] was about tracing resolvers that may or may not contain database operations.

  • To generalize it, since resolver is a GraphQL concept, and Apollo itself uses graphql-js internally to execute provided resolvers, I tried to monkey-patch/wrap those resolvers or their wrappers to create a single GraphQL integration. But, it was not possible because the implementation of graphql-js isn't exposed, and I couldn't find an alternative way around it.

  • But it exposes the whole execution process which is the parent of all parallel/serial resolvers. It is actually a quite rough information. Still, it feels worthwhile to track. (Please correct me if I'm wrong).

  • After all, to track resolvers, Apollo's constructSchema appeared to be the most relevant and approachable method to access them and their hierarchy (the resolvers object still contain the parent/child relationship in a tree structure, when passed as an argument to constructSchema).

  • These two integrations work together when used with an Apollo server project, where the GraphQL span is the container and resolvers are children (grand-times-x children). Resolvers also can be parents of db operations from any of our database tracing instrumentations.

I'll be happy to put more work on this PR to refine/test more, after getting reviews, but this implementation has the basic functionality and is working in the current state.

@kamilogorek kamilogorek removed their request for review March 2, 2022 20:34
@onurtemizkan onurtemizkan force-pushed the onur/graphql-tracing-integration branch from 69c89f9 to 94074fc Compare April 14, 2022 07:38
@onurtemizkan onurtemizkan changed the base branch from master to 7.x April 14, 2022 07:38
@github-actions
Copy link
Contributor

github-actions bot commented Apr 14, 2022

size-limit report 📦

Path Size
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.43 KB (added)
@sentry/browser - ES5 CDN Bundle (minified) 60.2 KB (added)
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 18.24 KB (added)
@sentry/browser - ES6 CDN Bundle (minified) 53.82 KB (added)
@sentry/browser - Webpack (gzipped + minified) 19.99 KB (added)
@sentry/browser - Webpack (minified) 65.19 KB (added)
@sentry/react - Webpack (gzipped + minified) 20.02 KB (added)
@sentry/nextjs Client - Webpack (gzipped + minified) 43.95 KB (added)
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 25.56 KB (added)
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 24.11 KB (added)

@onurtemizkan onurtemizkan force-pushed the onur/graphql-tracing-integration branch 2 times, most recently from 311dc78 to c634e2c Compare April 14, 2022 16:01
Comment on lines 241 to 257
apollo() {
const integration = dynamicRequire(module, './integrations/apollo') as {
Apollo: IntegrationClass<Integration>;
};
return new integration.Apollo();
},
graphql() {
const integration = dynamicRequire(module, './integrations/graphql') as {
GraphQL: IntegrationClass<Integration>;
};
return new integration.GraphQL();
},
Copy link
Member

Choose a reason for hiding this comment

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

tbh I'd rather make these opt-in rather than auto-enabled.

Any possible way we can integration test this? We can do it in the PR moving forward as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@AbhiPrasad, updated and added the tests. 👍 Docs are coming up.

Copy link
Member

Choose a reason for hiding this comment

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

Can we make sure these are not auto-enabled?

@AbhiPrasad
Copy link
Member

We'll also need docs for this!

@onurtemizkan onurtemizkan force-pushed the onur/graphql-tracing-integration branch 4 times, most recently from beed667 to 4dcc09e Compare April 21, 2022 18:19
@@ -0,0 +1,33 @@
import { assertSentryTransaction, getEnvelopeRequest, runServer, conditionalTest } from '../../../utils';

conditionalTest({ min: 12 })(() => {
Copy link
Member

Choose a reason for hiding this comment

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

not supported by node 10?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Cool, can we leave a comment above the test linking to the package.json?

@onurtemizkan onurtemizkan force-pushed the onur/graphql-tracing-integration branch from 44e8e46 to f520528 Compare June 9, 2022 16:04
@onurtemizkan onurtemizkan changed the base branch from 7.x to master June 9, 2022 16:05
@onurtemizkan onurtemizkan force-pushed the onur/graphql-tracing-integration branch from f520528 to 117a868 Compare June 9, 2022 16:23
@lforst
Copy link
Contributor

lforst commented Jun 10, 2022

Thanks for this @onurtemizkan! Let's not forget to merge getsentry/sentry-docs#5089 when this is released.

@lforst lforst merged commit cafd6cb into master Jun 10, 2022
@lforst lforst deleted the onur/graphql-tracing-integration branch June 10, 2022 09:20
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.

Apollo tracing integration package?
7 participants