Skip to content
Draft
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
185 changes: 61 additions & 124 deletions sentry_sdk/integrations/django/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
from sentry_sdk.scope import add_global_event_processor, should_send_default_pii
from sentry_sdk.serializer import add_global_repr_processor, add_repr_sequence_type
from sentry_sdk.traces import StreamedSpan
from sentry_sdk.tracing import SOURCE_FOR_STYLE, TransactionSource
from sentry_sdk.tracing_utils import (
add_query_source,
has_span_streaming_enabled,
record_sql_queries,
)
from sentry_sdk.utils import (
Expand Down Expand Up @@ -73,7 +71,6 @@
from sentry_sdk._types import Event, EventProcessor, Hint, NotImplementedType
from sentry_sdk.integrations.wsgi import _ScopedResponse
from sentry_sdk.traces import StreamedSpan
from sentry_sdk.tracing import Span


TRANSACTION_STYLE_VALUES = ("function_name", "url")
Expand Down Expand Up @@ -326,27 +323,21 @@ def sentry_patched_drf_authenticate(self: "Request") -> "Any":
integration = client.get_integration(DjangoIntegration)
# Nothing to time if there are no authenticators configured
# for this view.
if integration is None or not getattr(self, "authenticators", None):
if (
integration is None
or not getattr(self, "authenticators", None)
or sentry_sdk.traces.get_current_span() is None
):
return old_drf_authenticate(self)

if has_span_streaming_enabled(client.options):
if sentry_sdk.traces.get_current_span() is None:
return old_drf_authenticate(self)
with sentry_sdk.traces.start_span(
name="authenticate",
attributes={
"sentry.op": OP.VIEW_AUTHENTICATE,
"sentry.origin": DjangoIntegration.origin,
},
):
return old_drf_authenticate(self)
else:
with sentry_sdk.start_span(
op=OP.VIEW_AUTHENTICATE,
name="authenticate",
origin=DjangoIntegration.origin,
):
return old_drf_authenticate(self)
with sentry_sdk.traces.start_span(
name="authenticate",
attributes={
"sentry.op": OP.VIEW_AUTHENTICATE,
"sentry.origin": DjangoIntegration.origin,
},
):
return old_drf_authenticate(self)

Request._authenticate = sentry_patched_drf_authenticate

Expand Down Expand Up @@ -489,13 +480,11 @@ def _after_get_response(request: "WSGIRequest") -> None:
scope = sentry_sdk.get_current_scope()
_attempt_resolve_again(request, scope, integration.transaction_style)

span_streaming = has_span_streaming_enabled(client.options)
if span_streaming:
if has_data_collection_enabled(client.options):
if client.options["data_collection"]["user_info"]:
_get_user_from_request_and_set_on_scope(request)
elif should_send_default_pii():
if has_data_collection_enabled(client.options):
if client.options["data_collection"]["user_info"]:
_get_user_from_request_and_set_on_scope(request)
elif should_send_default_pii():
_get_user_from_request_and_set_on_scope(request)


def _patch_get_response() -> None:
Expand Down Expand Up @@ -670,11 +659,6 @@ def execute(
_set_db_data(span, self)
result = real_execute(self, sql, params)

if isinstance(span, StreamedSpan):
with capture_internal_exceptions():
add_query_source(span)

if not isinstance(span, StreamedSpan):
with capture_internal_exceptions():
add_query_source(span)

Expand All @@ -696,11 +680,6 @@ def executemany(

result = real_executemany(self, sql, param_list)

if isinstance(span, StreamedSpan):
with capture_internal_exceptions():
add_query_source(span)

if not isinstance(span, StreamedSpan):
with capture_internal_exceptions():
add_query_source(span)

Expand All @@ -711,83 +690,55 @@ def connect(self: "BaseDatabaseWrapper") -> None:
with capture_internal_exceptions():
sentry_sdk.add_breadcrumb(message="connect", category="query")

span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
if span_streaming:
if sentry_sdk.traces.get_current_span() is None:
return real_connect(self)
with sentry_sdk.traces.start_span(
name="connect",
attributes={
"sentry.op": OP.DB,
"sentry.origin": DjangoIntegration.origin_db,
},
) as span:
_set_db_data(span, self)
return real_connect(self)
else:
with sentry_sdk.start_span(
op=OP.DB,
name="connect",
origin=DjangoIntegration.origin_db,
) as span:
_set_db_data(span, self)
return real_connect(self)
if sentry_sdk.traces.get_current_span() is None:
return real_connect(self)
with sentry_sdk.traces.start_span(
name="connect",
attributes={
"sentry.op": OP.DB,
"sentry.origin": DjangoIntegration.origin_db,
},
) as span:
_set_db_data(span, self)
return real_connect(self)

def _commit(self: "BaseDatabaseWrapper") -> None:
integration = sentry_sdk.get_client().get_integration(DjangoIntegration)

if integration is None or not integration.db_transaction_spans:
return real_commit(self)

span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
if span_streaming:
if sentry_sdk.traces.get_current_span() is None:
return real_commit(self)
with sentry_sdk.traces.start_span(
name=SPANNAME.DB_COMMIT,
attributes={
"sentry.op": OP.DB,
"sentry.origin": DjangoIntegration.origin_db,
},
) as span:
_set_db_data(span, self, SPANNAME.DB_COMMIT)
return real_commit(self)
else:
with sentry_sdk.start_span(
op=OP.DB,
name=SPANNAME.DB_COMMIT,
origin=DjangoIntegration.origin_db,
) as span:
_set_db_data(span, self, SPANNAME.DB_COMMIT)
return real_commit(self)
if sentry_sdk.traces.get_current_span() is None:
return real_commit(self)

with sentry_sdk.traces.start_span(
name=SPANNAME.DB_COMMIT,
attributes={
"sentry.op": OP.DB,
"sentry.origin": DjangoIntegration.origin_db,
},
) as span:
_set_db_data(span, self, SPANNAME.DB_COMMIT)
return real_commit(self)

def _rollback(self: "BaseDatabaseWrapper") -> None:
integration = sentry_sdk.get_client().get_integration(DjangoIntegration)

if integration is None or not integration.db_transaction_spans:
return real_rollback(self)

span_streaming = has_span_streaming_enabled(sentry_sdk.get_client().options)
if span_streaming:
if sentry_sdk.traces.get_current_span() is None:
return real_rollback(self)
with sentry_sdk.traces.start_span(
name=SPANNAME.DB_ROLLBACK,
attributes={
"sentry.op": OP.DB,
"sentry.origin": DjangoIntegration.origin_db,
},
) as span:
_set_db_data(span, self, SPANNAME.DB_ROLLBACK)
return real_rollback(self)
else:
with sentry_sdk.start_span(
op=OP.DB,
name=SPANNAME.DB_ROLLBACK,
origin=DjangoIntegration.origin_db,
) as span:
_set_db_data(span, self, SPANNAME.DB_ROLLBACK)
return real_rollback(self)
if sentry_sdk.traces.get_current_span() is None:
return real_rollback(self)

with sentry_sdk.traces.start_span(
name=SPANNAME.DB_ROLLBACK,
attributes={
"sentry.op": OP.DB,
"sentry.origin": DjangoIntegration.origin_db,
},
) as span:
_set_db_data(span, self, SPANNAME.DB_ROLLBACK)
return real_rollback(self)

CursorWrapper.execute = execute
CursorWrapper.executemany = executemany
Expand All @@ -798,22 +749,16 @@ def _rollback(self: "BaseDatabaseWrapper") -> None:


def _set_db_data(
span: "Union[Span, StreamedSpan]",
span: "StreamedSpan",
cursor_or_db: "Any",
db_operation: "Optional[str]" = None,
) -> None:
db = cursor_or_db.db if hasattr(cursor_or_db, "db") else cursor_or_db
vendor = db.vendor
if isinstance(span, StreamedSpan):
span.set_attribute(SPANDATA.DB_SYSTEM_NAME, vendor)

if db_operation is not None:
span.set_attribute(SPANDATA.DB_OPERATION_NAME, db_operation)
else:
span.set_data(SPANDATA.DB_SYSTEM, vendor)
span.set_attribute(SPANDATA.DB_SYSTEM_NAME, vendor)

if db_operation is not None:
span.set_data(SPANDATA.DB_OPERATION, db_operation)
if db_operation is not None:
span.set_attribute(SPANDATA.DB_OPERATION_NAME, db_operation)

# Some custom backends override `__getattr__`, making it look like `cursor_or_db`
# actually has a `connection` and the `connection` has a `get_dsn_parameters`
Expand Down Expand Up @@ -846,28 +791,20 @@ def _set_db_data(

db_name = connection_params.get("dbname") or connection_params.get("database")

if isinstance(span, StreamedSpan):
if db_name is not None:
span.set_attribute(SPANDATA.DB_NAMESPACE, db_name)

set_on_span = span.set_attribute
else:
if db_name is not None:
span.set_data(SPANDATA.DB_NAME, db_name)

set_on_span = span.set_data
if db_name is not None:
span.set_attribute(SPANDATA.DB_NAMESPACE, db_name)

server_address = connection_params.get("host")
if server_address is not None:
set_on_span(SPANDATA.SERVER_ADDRESS, server_address)
span.set_attribute(SPANDATA.SERVER_ADDRESS, server_address)

server_port = connection_params.get("port")
if server_port is not None:
set_on_span(SPANDATA.SERVER_PORT, str(server_port))
span.set_attribute(SPANDATA.SERVER_PORT, str(server_port))

server_socket_address = connection_params.get("unix_socket")
if server_socket_address is not None:
set_on_span(SPANDATA.SERVER_SOCKET_ADDRESS, server_socket_address)
span.set_attribute(SPANDATA.SERVER_SOCKET_ADDRESS, server_socket_address)


def add_template_context_repr_sequence() -> None:
Expand Down
44 changes: 15 additions & 29 deletions sentry_sdk/integrations/django/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
from sentry_sdk.scope import should_send_default_pii
from sentry_sdk.traces import StreamedSpan
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 @@ -175,39 +174,26 @@ async def sentry_wrapped_callback(
request: "Any", *args: "Any", **kwargs: "Any"
) -> "Any":
client = sentry_sdk.get_client()
span_streaming = has_span_streaming_enabled(client.options)
current_scope = sentry_sdk.get_current_scope()
if span_streaming:
current_span = current_scope.streamed_span
if type(current_span) is StreamedSpan:
segment = current_span._segment
segment._update_active_thread()
else:
if current_scope.transaction is not None:
current_scope.transaction.update_active_thread()
current_span = sentry_sdk.traces.get_current_span()
if type(current_span) is StreamedSpan:
segment = current_span._segment
segment._update_active_thread()

integration = client.get_integration(DjangoIntegration)
if not integration or not integration.middleware_spans:
return await callback(request, *args, **kwargs)

if span_streaming:
if sentry_sdk.traces.get_current_span() is None:
return await callback(request, *args, **kwargs)
with sentry_sdk.traces.start_span(
name=request.resolver_match.view_name,
attributes={
"sentry.op": OP.VIEW_RENDER,
"sentry.origin": DjangoIntegration.origin,
},
):
return await callback(request, *args, **kwargs)
else:
with sentry_sdk.start_span(
op=OP.VIEW_RENDER,
name=request.resolver_match.view_name,
origin=DjangoIntegration.origin,
):
return await callback(request, *args, **kwargs)
if current_span is None:
return await callback(request, *args, **kwargs)

with sentry_sdk.traces.start_span(
name=request.resolver_match.view_name,
attributes={
"sentry.op": OP.VIEW_RENDER,
"sentry.origin": DjangoIntegration.origin,
},
):
return await callback(request, *args, **kwargs)

return sentry_wrapped_callback

Expand Down
Loading
Loading