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

GraphQL Async Instrumentation Support #908

Merged
merged 25 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1bdf3b1
Add GraphQL Server Sanic Instrumentation
lrafeei Mar 24, 2022
9e526d1
Co-authored-by: Timothy Pansino <[email protected]>
lrafeei Mar 24, 2022
9f8856b
Add co-authors
lrafeei Mar 24, 2022
375bda5
Comment out Copyright notice message
lrafeei Mar 24, 2022
07ec74f
Finalize Sanic testing
TimPansino Mar 28, 2022
f781423
Fix flask framework details with callable
TimPansino Mar 28, 2022
58418ee
Parametrized testing for graphql-server
TimPansino Mar 28, 2022
215538b
GraphQL Async Resolvers
TimPansino Mar 28, 2022
e7705ad
Merge branch 'main' into develop-graphql-async
TimPansino Mar 31, 2022
38e9f72
Merge branch 'main' into develop-graphql-async
TimPansino Apr 20, 2022
8cda4f7
GraphQL Proper Coro and Promise Support (#508)
TimPansino Apr 20, 2022
7c630b8
Merge branch 'main' into develop-graphql-async
TimPansino Apr 27, 2022
56cab4b
Fix graphql impl coros (#522)
TimPansino Apr 27, 2022
fd57192
Strawberry Async Updates (#521)
TimPansino May 3, 2022
ff9b1b4
Ariadne Async Testing (#523)
TimPansino May 9, 2022
a2889a6
Graphene Async Testing (#524)
TimPansino May 10, 2022
addc9e5
Merge branch 'main' into develop-graphql-async
TimPansino May 26, 2022
ec0ec2f
Merge branch 'main' into develop-graphql-async
TimPansino May 27, 2022
545fdfa
Merge branch 'main' into develop-graphql-async
TimPansino Jul 11, 2022
61d32f1
Merge branch 'main' into develop-graphql-async
TimPansino Jul 11, 2022
619026e
Merge branch 'main' into develop-graphql-async
TimPansino Oct 6, 2022
16b707b
Merge main into develop-graphql-async (#892)
TimPansino Aug 11, 2023
118b68f
Remove graphql 2 & promise support (#875)
hmstepanek Aug 23, 2023
569277c
Merge branch 'main' into develop-graphql-async
umaannamalai Aug 24, 2023
4064dca
Remove solrpy merge conflict.
umaannamalai Aug 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion newrelic/api/graphql_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def wrap_graphql_operation_trace(module, object_path, async_wrapper=None):


class GraphQLResolverTrace(TimeTrace):
def __init__(self, field_name=None, **kwargs):
def __init__(self, field_name=None, field_parent_type=None, field_return_type=None, field_path=None, **kwargs):
parent = kwargs.pop("parent", None)
source = kwargs.pop("source", None)
if kwargs:
Expand All @@ -148,6 +148,9 @@ def __init__(self, field_name=None, **kwargs):
super(GraphQLResolverTrace, self).__init__(parent=parent, source=source)

self.field_name = field_name
self.field_parent_type = field_parent_type
self.field_return_type = field_return_type
self.field_path = field_path
self._product = None

def __repr__(self):
Expand Down Expand Up @@ -175,6 +178,9 @@ def product(self):

def finalize_data(self, *args, **kwargs):
self._add_agent_attribute("graphql.field.name", self.field_name)
self._add_agent_attribute("graphql.field.parentType", self.field_parent_type)
self._add_agent_attribute("graphql.field.returnType", self.field_return_type)
self._add_agent_attribute("graphql.field.path", self.field_path)

return super(GraphQLResolverTrace, self).finalize_data(*args, **kwargs)

Expand Down
23 changes: 12 additions & 11 deletions newrelic/hooks/component_graphqlserver.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
from newrelic.api.asgi_application import wrap_asgi_application
from newrelic.api.error_trace import ErrorTrace
from newrelic.api.graphql_trace import GraphQLOperationTrace
from newrelic.api.transaction import current_transaction
from newrelic.api.transaction_name import TransactionNameWrapper
from newrelic.common.object_names import callable_name
from newrelic.common.object_wrapper import wrap_function_wrapper
from newrelic.common.package_version_utils import get_package_version
from newrelic.core.graphql_utils import graphql_statement
from newrelic.hooks.framework_graphql import (
framework_version as graphql_framework_version,
GRAPHQL_VERSION,
ignore_graphql_duplicate_exception,
)
from newrelic.hooks.framework_graphql import ignore_graphql_duplicate_exception

def framework_details():
import graphql_server
return ("GraphQLServer", getattr(graphql_server, "__version__", None))
GRAPHQL_SERVER_VERSION = get_package_version("graphql-server")
graphql_server_major_version = int(GRAPHQL_SERVER_VERSION.split(".")[0])


def bind_query(schema, params, *args, **kwargs):
return getattr(params, "query", None)
Expand All @@ -30,9 +29,8 @@ def wrap_get_response(wrapped, instance, args, kwargs):
except TypeError:
return wrapped(*args, **kwargs)

framework = framework_details()
transaction.add_framework_info(name=framework[0], version=framework[1])
transaction.add_framework_info(name="GraphQL", version=graphql_framework_version())
transaction.add_framework_info(name="GraphQLServer", version=GRAPHQL_SERVER_VERSION)
transaction.add_framework_info(name="GraphQL", version=GRAPHQL_VERSION)

if hasattr(query, "body"):
query = query.body
Expand All @@ -45,5 +43,8 @@ def wrap_get_response(wrapped, instance, args, kwargs):
with ErrorTrace(ignore=ignore_graphql_duplicate_exception):
return wrapped(*args, **kwargs)


def instrument_graphqlserver(module):
wrap_function_wrapper(module, "get_response", wrap_get_response)
if graphql_server_major_version <= 2:
return
wrap_function_wrapper(module, "get_response", wrap_get_response)
34 changes: 17 additions & 17 deletions newrelic/hooks/framework_ariadne.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,12 @@
from newrelic.api.wsgi_application import wrap_wsgi_application
from newrelic.common.object_names import callable_name
from newrelic.common.object_wrapper import wrap_function_wrapper
from newrelic.common.package_version_utils import get_package_version
from newrelic.core.graphql_utils import graphql_statement
from newrelic.hooks.framework_graphql import (
framework_version as graphql_framework_version,
)
from newrelic.hooks.framework_graphql import ignore_graphql_duplicate_exception
from newrelic.hooks.framework_graphql import GRAPHQL_VERSION, ignore_graphql_duplicate_exception


def framework_details():
import ariadne

return ("Ariadne", getattr(ariadne, "__version__", None))
ARIADNE_VERSION = get_package_version("ariadne")
ariadne_version_tuple = tuple(map(int, ARIADNE_VERSION.split(".")))


def bind_graphql(schema, data, *args, **kwargs):
Expand All @@ -49,9 +44,8 @@ def wrap_graphql_sync(wrapped, instance, args, kwargs):
except TypeError:
return wrapped(*args, **kwargs)

framework = framework_details()
transaction.add_framework_info(name=framework[0], version=framework[1]) # No version info available on ariadne
transaction.add_framework_info(name="GraphQL", version=graphql_framework_version())
transaction.add_framework_info(name="Ariadne", version=ARIADNE_VERSION)
transaction.add_framework_info(name="GraphQL", version=GRAPHQL_VERSION)

query = data["query"]
if hasattr(query, "body"):
Expand Down Expand Up @@ -83,9 +77,8 @@ async def wrap_graphql(wrapped, instance, args, kwargs):
result = await result
return result

framework = framework_details()
transaction.add_framework_info(name=framework[0], version=framework[1]) # No version info available on ariadne
transaction.add_framework_info(name="GraphQL", version=graphql_framework_version())
transaction.add_framework_info(name="Ariadne", version=ARIADNE_VERSION)
transaction.add_framework_info(name="GraphQL", version=GRAPHQL_VERSION)

query = data["query"]
if hasattr(query, "body"):
Expand All @@ -104,6 +97,9 @@ async def wrap_graphql(wrapped, instance, args, kwargs):


def instrument_ariadne_execute(module):
# v0.9.0 is the version where ariadne started using graphql-core v3
if ariadne_version_tuple < (0, 9):
return
if hasattr(module, "graphql"):
wrap_function_wrapper(module, "graphql", wrap_graphql)

Expand All @@ -112,10 +108,14 @@ def instrument_ariadne_execute(module):


def instrument_ariadne_asgi(module):
if ariadne_version_tuple < (0, 9):
return
if hasattr(module, "GraphQL"):
wrap_asgi_application(module, "GraphQL.__call__", framework=framework_details())
wrap_asgi_application(module, "GraphQL.__call__", framework=("Ariadne", ARIADNE_VERSION))


def instrument_ariadne_wsgi(module):
if ariadne_version_tuple < (0, 9):
return
if hasattr(module, "GraphQL"):
wrap_wsgi_application(module, "GraphQL.__call__", framework=framework_details())
wrap_wsgi_application(module, "GraphQL.__call__", framework=("Ariadne", ARIADNE_VERSION))
Loading