8000 Add span for Django SimpleTemplateResponse rendering (#1818) · Tarty/sentry-python@dfb04f5 · GitHub
[go: up one dir, main page]

Skip to content

Commit dfb04f5

Browse files
authored
Add span for Django SimpleTemplateResponse rendering (getsentry#1818)
1 parent 1578832 commit dfb04f5

File tree

5 files changed

+39
-0
lines changed

5 files changed

+39
-0
lines changed

sentry_sdk/consts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class OP:
7171
SUBPROCESS_COMMUNICATE = "subprocess.communicate"
7272
TEMPLATE_RENDER = "template.render"
7373
VIEW_RENDER = "view.render"
74+
VIEW_RESPONSE_RENDER = "view.response.render"
7475
WEBSOCKET_SERVER = "websocket.server"
7576

7677

sentry_sdk/integrations/django/views.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,19 @@ def patch_views():
2323
# type: () -> None
2424

2525
from django.core.handlers.base import BaseHandler
26+
from django.template.response import SimpleTemplateResponse
2627
from sentry_sdk.integrations.django import DjangoIntegration
2728

2829
old_make_view_atomic = BaseHandler.make_view_atomic
30+
old_render = SimpleTemplateResponse.render
31+
32+
def sentry_patched_render(self):
33+
# type: (SimpleTemplateResponse) -> Any
34+
hub = Hub.current
35+
with hub.start_span(
36+
op=OP.VIEW_RESPONSE_RENDER, description="serialize response"
37+
):
38+
return old_render(self)
2939

3040
@_functools.wraps(old_make_view_atomic)
3141
def sentry_patched_make_view_atomic(self, *args, **kwargs):
@@ -54,6 +64,7 @@ def sentry_patched_make_view_atomic(self, *args, **kwargs):
5464

5565
return sentry_wrapped_callback
5666

67+
SimpleTemplateResponse.render = sentry_patched_render
5768
BaseHandler.make_view_atomic = sentry_patched_make_view_atomic
5869

5970

tests/integrations/django/myapp/urls.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ def path(path, *args, **kwargs):
8080
)
8181
)
8282
urlpatterns.append(path("rest-hello", views.rest_hello, name="rest_hello"))
83+
urlpatterns.append(
84+
path("rest-json-response", views.rest_json_response, name="rest_json_response")
85+
)
8386
urlpatterns.append(
8487
path(
8588
"rest-permission-denied-exc",

tests/integrations/django/myapp/views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
try:
1313
from rest_framework.decorators import api_view
14+
from rest_framework.response import Response
1415

1516
@api_view(["POST"])
1617
def rest_framework_exc(request):
@@ -29,6 +30,10 @@ def rest_hello(request):
2930
def rest_permission_denied_exc(request):
3031
raise PermissionDenied("bye")
3132

33+
@api_view(["GET"])
34+
def rest_json_response(request):
35+
return Response(dict(ok=True))
36+
3237
except ImportError:
3338
pass
3439

tests/integrations/django/test_basic.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,25 @@ def test_sql_dict_query_params(sentry_init, capture_events):
300300
assert crumb["data"]["db.params"] == {"my_foo": 10}
301301

302302

303+
@pytest.mark.forked
304+
@pytest_mark_django_db_decorator()
305+
def test_response_trace(sentry_init, client, capture_events, render_span_tree):
306+
pytest.importorskip("rest_framework")
307+
sentry_init(
308+
integrations=[DjangoIntegration()],
309+
traces_sample_rate=1.0,
310+
)
311+
312+
events = capture_events()
313+
content, status, headers = client.get(reverse("rest_json_response"))
314+
assert status == "200 OK"
315+
316+
assert (
317+
'- op="view.response.render": description="serialize response"'
318+
in render_span_tree(events[0])
319+
)
320+
321+
303322
@pytest.mark.parametrize(
304323
"query",
305324
[

0 commit comments

Comments
 (0)
0