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

Graphene-Django introspection fix #656

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 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 <TimPansino@users.noreply.github.com>
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
5b3693e
Catch GraphiQL reload to introspection
lrafeei Oct 10, 2022
34209bc
Instrument graphene_django framework
lrafeei Oct 18, 2022
6dfbc02
Add tests in .tox file
lrafeei Oct 18, 2022
1bf2071
Temporarily remove graphene_django tests from tox.ini
lrafeei Oct 19, 2022
5b67b3a
Add initial test setup for graphene-django
lrafeei Oct 23, 2022
7c2c396
Initial test commit for graphene-django
lrafeei Nov 1, 2022
8aa9de8
Imported graphene tests into graphene-django tests
lrafeei Nov 2, 2022
1b52d49
Fix testing/account for existing GraphQLOperationTrace creation
lrafeei Nov 3, 2022
9288e44
Change framework to component
lrafeei Nov 3, 2022
5ffd1af
Add django ASGI testing
TimPansino Nov 4, 2022
ba20f03
[Mega-Linter] Apply linters fixes
TimPansino Nov 4, 2022
6ade93e
Trigger tests
hmstepanek Nov 7, 2022
8502160
Add comment to explain import exception
lrafeei Nov 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion newrelic/api/graphql_trace.py
Expand Up @@ -134,7 +134,7 @@ def wrap_graphql_operation_trace(module, object_path):


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 @@ -143,6 +143,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 @@ -170,6 +173,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
4 changes: 4 additions & 0 deletions newrelic/config.py
Expand Up @@ -2210,6 +2210,10 @@ def _process_module_builtin_defaults():
"instrument_graphene_types_schema",
)

_process_module_definition(
"graphene_django.views", "newrelic.hooks.component_graphenedjango", "instrument_graphene_django_views"
)

_process_module_definition(
"graphql.graphql",
"newrelic.hooks.framework_graphql",
Expand Down
65 changes: 65 additions & 0 deletions newrelic/hooks/component_graphenedjango.py
@@ -0,0 +1,65 @@
# Copyright 2010 New Relic, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from newrelic.api.error_trace import ErrorTrace
from newrelic.api.graphql_trace import GraphQLOperationTrace
from newrelic.api.transaction import current_transaction
from newrelic.common.object_names import callable_name
from newrelic.common.object_wrapper import wrap_function_wrapper
from newrelic.core.graphql_utils import graphql_statement
from newrelic.hooks.framework_graphene import (
framework_details as graphene_framework_details,
)
from newrelic.hooks.framework_graphql import (
framework_version as graphql_framework_version,
)
from newrelic.hooks.framework_graphql import ignore_graphql_duplicate_exception


def bind_execute_graphql_request(request, data, query, variables, operation_name, show_graphiql=False):
return query


def wrap_execute_graphql_request(wrapped, instance, args, kwargs):
transaction = current_transaction()

if not transaction:
return wrapped(*args, **kwargs)

try:
query = bind_execute_graphql_request(*args, **kwargs)
except TypeError:
query = None

framework = graphene_framework_details()
transaction.add_framework_info(name=framework[0], version=framework[1])
transaction.add_framework_info(name="GraphQL", version=graphql_framework_version())

if hasattr(query, "body"):
query = query.body

transaction.set_transaction_name(callable_name(wrapped), "GraphQL", priority=10)

with GraphQLOperationTrace(source=wrapped) as trace:
trace.product = "Graphene"
if query:
trace.statement = graphql_statement(query)

with ErrorTrace(ignore=ignore_graphql_duplicate_exception):
return wrapped(*args, **kwargs)


def instrument_graphene_django_views(module):
if hasattr(module, "GraphQLView"):
wrap_function_wrapper(module, "GraphQLView.execute_graphql_request", wrap_execute_graphql_request)
14 changes: 11 additions & 3 deletions newrelic/hooks/framework_ariadne.py
Expand Up @@ -29,9 +29,17 @@


def framework_details():
import ariadne

return ("Ariadne", getattr(ariadne, "__version__", None))
try:
import ariadne
version = ariadne.__version__
except Exception:
try:
import pkg_resources
version = pkg_resources.get_distribution("ariadne").version
except Exception:
version = None

return ("Ariadne", version)


def bind_graphql(schema, data, *args, **kwargs):
Expand Down