Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
59 changes: 20 additions & 39 deletions sentry_sdk/integrations/graphene.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from sentry_sdk.consts import OP
from sentry_sdk.integrations import DidNotEnable, Integration, _check_minimum_version
from sentry_sdk.scope import should_send_default_pii
from sentry_sdk.tracing_utils import has_span_streaming_enabled
from sentry_sdk.utils import (
capture_internal_exceptions,
ensure_integration_enabled,
Expand Down Expand Up @@ -154,47 +153,29 @@ def graphql_span(
)

client_options = sentry_sdk.get_client().options
is_span_streaming_enabled = has_span_streaming_enabled(client_options)

if is_span_streaming_enabled:
if sentry_sdk.traces.get_current_span() is None:
yield
return

additional_attributes = {}
if has_data_collection_enabled(client_options):
if client_options["data_collection"]["graphql"]["document"]:
additional_attributes["graphql.document"] = source
elif should_send_default_pii():
additional_attributes["graphql.document"] = source

_graphql_span = sentry_sdk.traces.start_span(
name=operation_name,
attributes={
"sentry.op": op,
"graphql.operation.name": operation_name,
"graphql.operation.type": operation_type,
**additional_attributes,
},
)
else:
_graphql_span = sentry_sdk.start_span(op=op, name=operation_name)

if has_data_collection_enabled(client_options):
if client_options["data_collection"]["graphql"]["document"]:
_graphql_span.set_data("graphql.document", source)
elif should_send_default_pii():
_graphql_span.set_data("graphql.document", source)

_graphql_span.set_data("graphql.operation.name", operation_name)
_graphql_span.set_data("graphql.operation.type", operation_type)
if sentry_sdk.traces.get_current_span() is None:
yield
return

_graphql_span.__enter__()
additional_attributes = {}
if has_data_collection_enabled(client_options):
if client_options["data_collection"]["graphql"]["document"]:
additional_attributes["graphql.document"] = source
elif should_send_default_pii():
additional_attributes["graphql.document"] = source

_graphql_span = sentry_sdk.traces.start_span(
name=operation_name,
attributes={
"sentry.op": op,
"graphql.operation.name": operation_name,
"graphql.operation.type": operation_type,
**additional_attributes,
},
)

try:
yield
finally:
if is_span_streaming_enabled:
_graphql_span.end() # type: ignore
else:
_graphql_span.__exit__(None, None, None)
_graphql_span.end() # type: ignore
148 changes: 2 additions & 146 deletions tests/integrations/graphene/test_graphene.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,107 +329,6 @@ def graphql_server_sync():
[True, False],
)
def test_graphql_span_holds_query_information(
sentry_init, capture_events, send_default_pii
):
sentry_init(
integrations=[GrapheneIntegration(), FlaskIntegration()],
traces_sample_rate=1.0,
default_integrations=False,
send_default_pii=send_default_pii,
)
events = capture_events()

schema = Schema(query=Query)

sync_app = Flask(__name__)

@sync_app.route("/graphql", methods=["POST"])
def graphql_server_sync():
data = request.get_json()
result = schema.execute(data["query"], operation_name=data.get("operationName"))
return jsonify(result.data), 200

query = {
"query": "query GreetingQuery { hello }",
"operationName": "GreetingQuery",
}
client = sync_app.test_client()
client.post("/graphql", json=query)

assert len(events) == 1

(event,) = events
assert len(event["spans"]) == 1

(span,) = event["spans"]
assert span["op"] == OP.GRAPHQL_QUERY
assert span["description"] == query["operationName"]
assert span["data"]["graphql.operation.name"] == query["operationName"]
assert span["data"]["graphql.operation.type"] == "query"

if send_default_pii is True:
assert span["data"]["graphql.document"] == query["query"]
else:
assert "graphql.document" not in span["data"]


@pytest.mark.parametrize(
"data_collection,send_default_pii,expect_document",
DATA_COLLECTION_GRAPHQL_DOCUMENTS_PARAMS,
)
def test_graphql_span_data_collection(
sentry_init, capture_events, data_collection, send_default_pii, expect_document
):
init_kwargs = {
"integrations": [GrapheneIntegration(), FlaskIntegration()],
"traces_sample_rate": 1.0,
"default_integrations": False,
"_experiments": {"data_collection": data_collection},
}
if send_default_pii is not None:
init_kwargs["send_default_pii"] = send_default_pii
sentry_init(**init_kwargs)
events = capture_events()

schema = Schema(query=Query)

sync_app = Flask(__name__)

@sync_app.route("/graphql", methods=["POST"])
def graphql_server_sync():
data = request.get_json()
result = schema.execute(data["query"], operation_name=data.get("operationName"))
return jsonify(result.data), 200

query = {
"query": "query GreetingQuery { hello }",
"operationName": "GreetingQuery",
}
client = sync_app.test_client()
client.post("/graphql", json=query)

assert len(events) == 1

(event,) = events
assert len(event["spans"]) == 1

(span,) = event["spans"]
assert span["op"] == OP.GRAPHQL_QUERY
assert span["description"] == query["operationName"]
assert span["data"]["graphql.operation.name"] == query["operationName"]
assert span["data"]["graphql.operation.type"] == "query"

if expect_document:
assert span["data"]["graphql.document"] == query["query"]
else:
assert "graphql.document" not in span["data"]


@pytest.mark.parametrize(
"send_default_pii",
[True, False],
)
def test_graphql_streamed_span_holds_query_information(
sentry_init, capture_items, send_default_pii
):
sentry_init(
Expand Down Expand Up @@ -486,7 +385,7 @@ def graphql_server_sync():
"data_collection,send_default_pii,expect_document",
DATA_COLLECTION_GRAPHQL_DOCUMENTS_PARAMS,
)
def test_graphql_streamed_span_data_collection(
def test_graphql_span_data_collection(
sentry_init, capture_items, data_collection, send_default_pii, expect_document
):
init_kwargs = {
Expand Down Expand Up @@ -542,50 +441,7 @@ def graphql_server_sync():
assert graphql_span["parent_span_id"] == flask_segment["span_id"]


def test_breadcrumbs_hold_query_information_on_error(sentry_init, capture_events):
sentry_init(
integrations=[
GrapheneIntegration(),
],
default_integrations=False,
)
events = capture_events()

schema = Schema(query=Query)

sync_app = Flask(__name__)

@sync_app.route("/graphql", methods=["POST"])
def graphql_server_sync():
data = request.get_json()
result = schema.execute(data["query"], operation_name=data.get("operationName"))
return jsonify(result.data), 200

query = {
"query": "query ErrorQuery { goodbye }",
"operationName": "ErrorQuery",
}
client = sync_app.test_client()
client.post("/graphql", json=query)

assert len(events) == 1

(event,) = events
assert len(event["breadcrumbs"]) == 1

breadcrumbs = event["breadcrumbs"]["values"]
assert len(breadcrumbs) == 1

(breadcrumb,) = breadcrumbs
assert breadcrumb["category"] == "graphql.operation"
assert breadcrumb["data"]["operation_name"] == query["operationName"]
assert breadcrumb["data"]["operation_type"] == "query"
assert breadcrumb["type"] == "default"


def test_breadcrumbs_hold_query_information_on_error_with_span_streaming(
sentry_init, capture_items
):
def test_breadcrumbs_hold_query_information_on_error(sentry_init, capture_items):
sentry_init(
integrations=[
GrapheneIntegration(),
Expand Down
Loading