-
Notifications
You must be signed in to change notification settings - Fork 457
feat(graphql): add graphql-core integration #3878
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
Conversation
6426cf6
to
70b9fab
Compare
e31212a
to
245664d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job and thank you for all of the comments and the in-depth description!
245664d
to
b19bac4
Compare
f2cfd3c
to
b19bac4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
Just an aside: this change has both a declarative and an imperative flavour. If the idea of using the internal wrapping
module really flies, perhaps all the imperative boilerplate could be factored out in some higher-level abstraction around wrap
/unwrap
and leave just the declarative part in integration sources.
1e8dea9
to
e70fe4a
Compare
799b309
to
06e60f8
Compare
06e60f8
to
b65d9c1
Compare
b65d9c1
to
341b184
Compare
9c9b0e3
to
dab208e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Mostly nits and one openish question to the team:
@DataDog/apm-python should this integration be named "graphql" or "graphql-core". The package/pypi name for this integration is "graphql-core" but it is used by most/all graphql libraries.
31c7cb5
to
1d4b48b
Compare
releasenotes/notes/add-graphql-core-support-fd20dcbebfcaa8c7.yaml
Outdated
Show resolved
Hide resolved
1d4b48b
to
26a50e4
Compare
26a50e4
to
3964841
Compare
releasenotes/notes/add-graphql-core-support-fd20dcbebfcaa8c7.yaml
Outdated
Show resolved
Hide resolved
1388e8e
to
0d65d09
Compare
Co-authored-by: Kyle Verhoog <[email protected]> Update ddtrace/contrib/graphql/__init__.py Co-authored-by: Kyle Verhoog <[email protected]> Update ddtrace/contrib/graphql/patch.py Co-authored-by: Brett Langdon <[email protected]> Update ddtrace/contrib/graphql/patch.py Co-authored-by: Brett Langdon <[email protected]> Update ddtrace/contrib/graphql/patch.py Co-authored-by: Brett Langdon <[email protected]>
0d65d09
to
272829e
Compare
Codecov Report
@@ Coverage Diff @@
## 1.x #3878 +/- ##
==========================================
+ Coverage 79.48% 79.59% +0.11%
==========================================
Files 714 717 +3
Lines 55787 56199 +412
==========================================
+ Hits 44344 44734 +390
- Misses 11443 11465 +22
📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more |
Graphql Integration
Overview
This integration supports graphql-core 3 and graphql-core 2. It provides instrumentation for executing graphql queries using
graphql.graphql()
,graphql.graphql_sync()
,graphql.execute()
, andgraphql.subscribe()
. This integration also wraps the execution ofgraphql.parse()
andgraphql.validate()
in a span.Supports
All libraries which use
graphql-core>=2.0
to execute queries are supported:graphene>=2.0
strawberry>=0.16.0
ariadne>=0.9.0
Implementation Details
The graphql-core integration provides support for parsing, building, validating, and executing graphql schemas. It also provides additional insight into resolving GraphQLFields. This integration uses bytecode instrumentation to add tracing to graphql operations listed below.
When graphql.graphql() or graphql.graphql_sync (in
graphql-core>=3
) is called the following trace is produced:converts the body of an incoming graphql request into a graphql document
ensures a graphql schema is syntactically correct and can be executed in a given context
executes a valid graphql schema and returns a response
Graphql queries can be complex and often resolve multiple Graphql fields in single request. Instrumenting resolvers provides insight on the execution of individual graphql fields and can highlight bottlenecks in fetching specific types of data. However for some applications this can produce large traces.
Note: If a GraphqlError is raised while parsing or validating a graphql query then
graphql.execute
will not be called and instrumented. For this reason we add the graphql source string to thegraphql.query
span AND thegraphql.execute
span.Disabling
graphql.resolve
Graphql queries can be complex and can resolve a large number of graphql fields in one request. Many of the resolvers could provide little to no insight into the execution of the request (ex. if the default resolver is called). To simplify the flamegraph produced by the graphql integration users can set
DD_TRACE_GRAPHQL_PATCH_RESOLVERS=False
to disable resolver instrumentation.Future Work
Add Span Tags
Add span tags to maintain feature parity with the .NET and javascript tracer.
ddtrace-js graphql integration: https://github.com/DataDog/dd-trace-js/tree/c9f82be2b256b2894d894e2eb49c331852b1262b/packages/datadog-plugin-graphql/src
Instrument Promises
In
graphql-core>=2,<3
, graphql.execute() can return a promise if thegraphql.execute()
is called withreturn_promise=True
. This promise will execute the graphql query asynchronously. To fix this we need to start thegraphql.execute
span when the promise is fulfilled and NOT when the promise is created.POC: 52ebd46
Refactor patching
#3878 (comment)
Testing strategy
Validate that the traces in the graphql snapshot tests produce meaningful data.
Ensure patch, execute, validate, and query operation are patched everywhere they are imported. Ex.
graphql.execute()
,graphql.execution.execute()
,graphql.execution.execute.execute()
orgraphql.graphql.execute()
should produce the same instrumentation.Relevant issue(s)
Resolves #925.
Reviewer Checklist
changelog/no-changelog
label added.