From 517a669efbe4e2230aa652773fd506ccfe610c08 Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Wed, 23 Dec 2020 23:01:40 +0100 Subject: [PATCH 1/9] integration.django: monkeypatch response rendering (performance span) --- sentry_sdk/integrations/django/__init__.py | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index 008dc386bb..a0356883bd 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -5,6 +5,7 @@ import threading import weakref +from sentry_sdk import _functools from sentry_sdk._types import MYPY from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.scope import add_global_event_processor @@ -201,6 +202,7 @@ def _django_queryset_repr(value, hint): _patch_channels() patch_django_middlewares() patch_views() + patch_templates() _DRF_PATCHED = False @@ -357,6 +359,44 @@ def sentry_patched_get_response(self, request): patch_get_response_async(BaseHandler, _before_get_response) +def patch_templates(): + # type: () -> None + import django.shortcuts + from django.template.response import SimpleTemplateResponse + + real_render = django.shortcuts.render + real_rendered_content = SimpleTemplateResponse.rendered_content + + @_functools.wraps(real_render) + def render(request, template_name, context=None, *args, **kwargs): + hub = Hub.current + if hub.get_integration(DjangoIntegration) is None: + return real_render(request, template_name, context, *args, **kwargs) + + with hub.start_span(op="render", description=template_name) as span: + span.set_data("context", context) + return real_render( + request, + template_name, + context=None, + *args, + **kwargs + ) + + @property + def rendered_content(self): + hub = Hub.current + if hub.get_integration(DjangoIntegration) is None: + return real_rendered_content.fget(self) + + with hub.start_span(op="render", description=self.template_name) as span: + span.set_data("context", self.context_data) + return real_rendered_content.fget(self) + + django.shortcuts.render = render + SimpleTemplateResponse.rendered_content = rendered_content + + def _make_event_processor(weak_request, integration): # type: (Callable[[], WSGIRequest], DjangoIntegration) -> EventProcessor def event_processor(event, hint): From 3403adfeffdb49888da131a53fb02dac07e4c471 Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Thu, 24 Dec 2020 00:33:12 +0100 Subject: [PATCH 2/9] integration.django: test response template rendering monkeypatch. --- sentry_sdk/integrations/django/__init__.py | 4 +- .../django/myapp/templates/user_name.html | 1 + tests/integrations/django/myapp/urls.py | 2 + tests/integrations/django/myapp/views.py | 11 ++++++ tests/integrations/django/test_basic.py | 37 +++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/integrations/django/myapp/templates/user_name.html diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index a0356883bd..67a526677a 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -373,7 +373,7 @@ def render(request, template_name, context=None, *args, **kwargs): if hub.get_integration(DjangoIntegration) is None: return real_render(request, template_name, context, *args, **kwargs) - with hub.start_span(op="render", description=template_name) as span: + with hub.start_span(op="django.render", description=template_name) as span: span.set_data("context", context) return real_render( request, @@ -389,7 +389,7 @@ def rendered_content(self): if hub.get_integration(DjangoIntegration) is None: return real_rendered_content.fget(self) - with hub.start_span(op="render", description=self.template_name) as span: + with hub.start_span(op="django.render", description=self.template_name) as span: span.set_data("context", self.context_data) return real_rendered_content.fget(self) diff --git a/tests/integrations/django/myapp/templates/user_name.html b/tests/integrations/django/myapp/templates/user_name.html new file mode 100644 index 0000000000..13831bfd24 --- /dev/null +++ b/tests/integrations/django/myapp/templates/user_name.html @@ -0,0 +1 @@ +{{ request.user }}: {{ user_age }} \ No newline at end of file diff --git a/tests/integrations/django/myapp/urls.py b/tests/integrations/django/myapp/urls.py index 5131d8674f..9427499dcf 100644 --- a/tests/integrations/django/myapp/urls.py +++ b/tests/integrations/django/myapp/urls.py @@ -45,6 +45,8 @@ def path(path, *args, **kwargs): ), path("post-echo", views.post_echo, name="post_echo"), path("template-exc", views.template_exc, name="template_exc"), + path("template-test", views.template_test, name="template_test"), + path("template-test2", views.template_test2, name="template_test2"), path( "permission-denied-exc", views.permission_denied_exc, diff --git a/tests/integrations/django/myapp/views.py b/tests/integrations/django/myapp/views.py index 1c78837ee4..b6d9766d3a 100644 --- a/tests/integrations/django/myapp/views.py +++ b/tests/integrations/django/myapp/views.py @@ -4,6 +4,7 @@ from django.core.exceptions import PermissionDenied from django.http import HttpResponse, HttpResponseNotFound, HttpResponseServerError from django.shortcuts import render +from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views.generic import ListView @@ -114,6 +115,16 @@ def template_exc(request, *args, **kwargs): return render(request, "error.html") +@csrf_exempt +def template_test(request, *args, **kwargs): + return render(request, "user_name.html", {"user_age": 20}) + + +@csrf_exempt +def template_test2(request, *args, **kwargs): + return TemplateResponse(request, "user_name.html", {"user_age": 25}) + + @csrf_exempt def permission_denied_exc(*args, **kwargs): raise PermissionDenied("bye") diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index c42ab3d9e4..d8035eab93 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -2,6 +2,7 @@ import pytest import json +import warnings from werkzeug.test import Client from django import VERSION as DJANGO_VERSION @@ -518,6 +519,42 @@ def test_does_not_capture_403(sentry_init, client, capture_events, endpoint): assert not events +def test_render_spans(sentry_init, client, capture_events, render_span_tree): + sentry_init( + integrations=[DjangoIntegration()], + traces_sample_rate=1.0, + ) + + events = capture_events() + _content, status, _headers = client.get(reverse("template_test")) + transaction = events[0] + assert(render_span_tree(transaction) == """\ +- op="http.server": description=null + - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" + - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" + - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.__call__" + - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" + - op="django.middleware": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" + - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" + - op="django.view": description="template_test" + - op="django.render": description="user_name.html"\ +""") + events = capture_events() + _content, status, _headers = client.get(reverse("template_test2")) + transaction = events[0] + assert(render_span_tree(transaction) == """\ +- op="http.server": description=null + - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" + - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" + - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.__call__" + - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" + - op="django.middleware": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" + - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" + - op="django.view": description="template_test2" + - op="django.render": description="user_name.html"\ +""") + + def test_middleware_spans(sentry_init, client, capture_events, render_span_tree): sentry_init( integrations=[DjangoIntegration()], From 03bd0fa3598035cf0599c399dd2d88d45cc69da7 Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Thu, 24 Dec 2020 00:39:02 +0100 Subject: [PATCH 3/9] fix: remove unused import --- tests/integrations/django/test_basic.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index d8035eab93..a7308c00b6 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -2,7 +2,6 @@ import pytest import json -import warnings from werkzeug.test import Client from django import VERSION as DJANGO_VERSION From f2bf9c77510e437a097e4e9b8e9336f2d6938f13 Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Thu, 24 Dec 2020 06:44:01 +0100 Subject: [PATCH 4/9] integration.django: test simplification, not longer testing middlewares in redering test. --- tests/integrations/django/test_basic.py | 36 ++++++------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index a7308c00b6..e017fd2748 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -524,34 +524,14 @@ def test_render_spans(sentry_init, client, capture_events, render_span_tree): traces_sample_rate=1.0, ) - events = capture_events() - _content, status, _headers = client.get(reverse("template_test")) - transaction = events[0] - assert(render_span_tree(transaction) == """\ -- op="http.server": description=null - - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" - - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.__call__" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="django.view": description="template_test" - - op="django.render": description="user_name.html"\ -""") - events = capture_events() - _content, status, _headers = client.get(reverse("template_test2")) - transaction = events[0] - assert(render_span_tree(transaction) == """\ -- op="http.server": description=null - - op="django.middleware": description="django.contrib.sessions.middleware.SessionMiddleware.__call__" - - op="django.middleware": description="django.contrib.auth.middleware.AuthenticationMiddleware.__call__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.__call__" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestMiddleware.__call__" - - op="django.middleware": description="tests.integrations.django.myapp.settings.TestFunctionMiddleware.__call__" - - op="django.middleware": description="django.middleware.csrf.CsrfViewMiddleware.process_view" - - op="django.view": description="template_test2" - - op="django.render": description="user_name.html"\ -""") + for url in (reverse("template_test"), reverse("template_test2")): + events = capture_events() + _content, status, _headers = client.get(url) + transaction = events[0] + assert( + '- op="django.render": description="user_name.html"' + in render_span_tree(transaction) + ) def test_middleware_spans(sentry_init, client, capture_events, render_span_tree): From 75aeba22e4054efeb9005b4ac091451e1fa68797 Mon Sep 17 00:00:00 2001 From: Narbonne Date: Mon, 28 Dec 2020 11:36:17 +0100 Subject: [PATCH 5/9] line break before EOF & rerun travis. --- tests/integrations/django/myapp/templates/user_name.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integrations/django/myapp/templates/user_name.html b/tests/integrations/django/myapp/templates/user_name.html index 13831bfd24..970107349f 100644 --- a/tests/integrations/django/myapp/templates/user_name.html +++ b/tests/integrations/django/myapp/templates/user_name.html @@ -1 +1 @@ -{{ request.user }}: {{ user_age }} \ No newline at end of file +{{ request.user }}: {{ user_age }} From d420674a3bb30b0b5b036d41ff3951ccf540e4ea Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Mon, 28 Dec 2020 14:51:01 +0100 Subject: [PATCH 6/9] black suggestion + fix named vars copy/paste --- sentry_sdk/integrations/django/__init__.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index 67a526677a..98a6387b79 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -375,13 +375,7 @@ def render(request, template_name, context=None, *args, **kwargs): with hub.start_span(op="django.render", description=template_name) as span: span.set_data("context", context) - return real_render( - request, - template_name, - context=None, - *args, - **kwargs - ) + return real_render(request, template_name, context, *args, **kwargs) @property def rendered_content(self): From faf5e4e9c9bc7b4ce8b94fbc428c34f67e20a7d6 Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Fri, 8 Jan 2021 19:58:58 +0100 Subject: [PATCH 7/9] integrations.django: http rendering monkey patch: fix linting, move template patch to templates file, update template rendering op --- sentry_sdk/integrations/django/__init__.py | 38 +++------------------ sentry_sdk/integrations/django/templates.py | 38 +++++++++++++++++++++ tests/integrations/django/test_basic.py | 7 ++-- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index 98a6387b79..3ef21a55ca 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -5,7 +5,6 @@ import threading import weakref -from sentry_sdk import _functools from sentry_sdk._types import MYPY from sentry_sdk.hub import Hub, _should_send_default_pii from sentry_sdk.scope import add_global_event_processor @@ -38,7 +37,10 @@ from sentry_sdk.integrations.django.transactions import LEGACY_RESOLVER -from sentry_sdk.integrations.django.templates import get_template_frame_from_exception +from sentry_sdk.integrations.django.templates import ( + get_template_frame_from_exception, + patch_templates, +) from sentry_sdk.integrations.django.middleware import patch_django_middlewares from sentry_sdk.integrations.django.views import patch_views @@ -359,38 +361,6 @@ def sentry_patched_get_response(self, request): patch_get_response_async(BaseHandler, _before_get_response) -def patch_templates(): - # type: () -> None - import django.shortcuts - from django.template.response import SimpleTemplateResponse - - real_render = django.shortcuts.render - real_rendered_content = SimpleTemplateResponse.rendered_content - - @_functools.wraps(real_render) - def render(request, template_name, context=None, *args, **kwargs): - hub = Hub.current - if hub.get_integration(DjangoIntegration) is None: - return real_render(request, template_name, context, *args, **kwargs) - - with hub.start_span(op="django.render", description=template_name) as span: - span.set_data("context", context) - return real_render(request, template_name, context, *args, **kwargs) - - @property - def rendered_content(self): - hub = Hub.current - if hub.get_integration(DjangoIntegration) is None: - return real_rendered_content.fget(self) - - with hub.start_span(op="django.render", description=self.template_name) as span: - span.set_data("context", self.context_data) - return real_rendered_content.fget(self) - - django.shortcuts.render = render - SimpleTemplateResponse.rendered_content = rendered_content - - def _make_event_processor(weak_request, integration): # type: (Callable[[], WSGIRequest], DjangoIntegration) -> EventProcessor def event_processor(event, hint): diff --git a/sentry_sdk/integrations/django/templates.py b/sentry_sdk/integrations/django/templates.py index 2285644909..08a5f35c8f 100644 --- a/sentry_sdk/integrations/django/templates.py +++ b/sentry_sdk/integrations/django/templates.py @@ -1,5 +1,6 @@ from django.template import TemplateSyntaxError +from sentry_sdk import _functools, Hub from sentry_sdk._types import MYPY if MYPY: @@ -40,6 +41,43 @@ def get_template_frame_from_exception(exc_value): return None +def patch_templates(): + # type: () -> None + import django.shortcuts + from django.template.response import SimpleTemplateResponse + from sentry_sdk.integrations.django import DjangoIntegration + + real_render = django.shortcuts.render + real_rendered_content = SimpleTemplateResponse.rendered_content + + @_functools.wraps(real_render) + def render(request, template_name, context=None, *args, **kwargs): + hub = Hub.current + if hub.get_integration(DjangoIntegration) is None: + return real_render(request, template_name, context, *args, **kwargs) + + with hub.start_span( + op="django.template.render", description=template_name + ) as span: + span.set_data("context", context) + return real_render(request, template_name, context, *args, **kwargs) + + @property + def rendered_content(self): + hub = Hub.current + if hub.get_integration(DjangoIntegration) is None: + return real_rendered_content.fget(self) + + with hub.start_span( + op="django.template.render", description=self.template_name + ) as span: + span.set_data("context", self.context_data) + return real_rendered_content.fget(self) + + django.shortcuts.render = render + SimpleTemplateResponse.rendered_content = rendered_content + + def _get_template_frame_from_debug(debug): # type: (Dict[str, Any]) -> Dict[str, Any] if debug is None: diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index e017fd2748..58abd4520a 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -520,16 +520,15 @@ def test_does_not_capture_403(sentry_init, client, capture_events, endpoint): def test_render_spans(sentry_init, client, capture_events, render_span_tree): sentry_init( - integrations=[DjangoIntegration()], - traces_sample_rate=1.0, + integrations=[DjangoIntegration()], traces_sample_rate=1.0, ) for url in (reverse("template_test"), reverse("template_test2")): events = capture_events() _content, status, _headers = client.get(url) transaction = events[0] - assert( - '- op="django.render": description="user_name.html"' + assert ( + '- op="django.template.render": description="user_name.html"' in render_span_tree(transaction) ) From db2d87e503b0178a7d56bdedb00db19ac6ddc9d8 Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Fri, 8 Jan 2021 21:36:47 +0100 Subject: [PATCH 8/9] integrations.django: http rendering monkey patch: disable dj1.6 shortcut.render monkeypatch, lint fixes --- sentry_sdk/integrations/django/templates.py | 38 +++++++++++++-------- tests/integrations/django/test_basic.py | 8 +++-- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/sentry_sdk/integrations/django/templates.py b/sentry_sdk/integrations/django/templates.py index 08a5f35c8f..3f805f36c2 100644 --- a/sentry_sdk/integrations/django/templates.py +++ b/sentry_sdk/integrations/django/templates.py @@ -1,4 +1,5 @@ from django.template import TemplateSyntaxError +from django import VERSION as DJANGO_VERSION from sentry_sdk import _functools, Hub from sentry_sdk._types import MYPY @@ -43,39 +44,46 @@ def get_template_frame_from_exception(exc_value): def patch_templates(): # type: () -> None - import django.shortcuts from django.template.response import SimpleTemplateResponse from sentry_sdk.integrations.django import DjangoIntegration - real_render = django.shortcuts.render real_rendered_content = SimpleTemplateResponse.rendered_content - @_functools.wraps(real_render) - def render(request, template_name, context=None, *args, **kwargs): + @property # type: ignore + def rendered_content(self): + # type: (SimpleTemplateResponse) -> str hub = Hub.current if hub.get_integration(DjangoIntegration) is None: - return real_render(request, template_name, context, *args, **kwargs) + return real_rendered_content.fget(self) with hub.start_span( - op="django.template.render", description=template_name + op="django.template.render", description=self.template_name ) as span: - span.set_data("context", context) - return real_render(request, template_name, context, *args, **kwargs) + span.set_data("context", self.context_data) + return real_rendered_content.fget(self) - @property - def rendered_content(self): + SimpleTemplateResponse.rendered_content = rendered_content + + if DJANGO_VERSION < (1, 7): + return + import django.shortcuts + + real_render = django.shortcuts.render + + @_functools.wraps(real_render) + def render(request, template_name, context=None, *args, **kwargs): + # type: (django.http.HttpRequest, str, Optional[Dict[str, Any]], *Any, **Any) -> django.http.HttpResponse hub = Hub.current if hub.get_integration(DjangoIntegration) is None: - return real_rendered_content.fget(self) + return real_render(request, template_name, context, *args, **kwargs) with hub.start_span( - op="django.template.render", description=self.template_name + op="django.template.render", description=template_name ) as span: - span.set_data("context", self.context_data) - return real_rendered_content.fget(self) + span.set_data("context", context) + return real_render(request, template_name, context, *args, **kwargs) django.shortcuts.render = render - SimpleTemplateResponse.rendered_content = rendered_content def _get_template_frame_from_debug(debug): diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index 58abd4520a..e094d23a72 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -520,10 +520,14 @@ def test_does_not_capture_403(sentry_init, client, capture_events, endpoint): def test_render_spans(sentry_init, client, capture_events, render_span_tree): sentry_init( - integrations=[DjangoIntegration()], traces_sample_rate=1.0, + integrations=[DjangoIntegration()], + traces_sample_rate=1.0, ) + views_urls = [reverse("template_test2")] + if DJANGO_VERSION >= (1, 7): + views_urls.append(reverse("template_test")) - for url in (reverse("template_test"), reverse("template_test2")): + for url in views_urls: events = capture_events() _content, status, _headers = client.get(url) transaction = events[0] From 501e2d2971b00c90336870d4b5ef627e0a90f948 Mon Sep 17 00:00:00 2001 From: Christophe Narbonne Date: Thu, 11 Mar 2021 23:13:41 +0100 Subject: [PATCH 9/9] django templates performance: handle lists and tuples `template_name` in auto spans monkey patch. --- sentry_sdk/integrations/django/templates.py | 14 ++++++++++++-- tests/integrations/django/myapp/views.py | 2 +- tests/integrations/django/test_basic.py | 15 ++++++++------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/sentry_sdk/integrations/django/templates.py b/sentry_sdk/integrations/django/templates.py index 3f805f36c2..51d3a2b3b0 100644 --- a/sentry_sdk/integrations/django/templates.py +++ b/sentry_sdk/integrations/django/templates.py @@ -42,6 +42,14 @@ def get_template_frame_from_exception(exc_value): return None +def _get_template_name_description(template_name): + if isinstance(template_name, (list, tuple)): + if template_name: + return "[%s, ...]".format(template_name[0]) + else: + return template_name + + def patch_templates(): # type: () -> None from django.template.response import SimpleTemplateResponse @@ -57,7 +65,8 @@ def rendered_content(self): return real_rendered_content.fget(self) with hub.start_span( - op="django.template.render", description=self.template_name + op="django.template.render", + description=_get_template_name_description(self.template_name), ) as span: span.set_data("context", self.context_data) return real_rendered_content.fget(self) @@ -78,7 +87,8 @@ def render(request, template_name, context=None, *args, **kwargs): return real_render(request, template_name, context, *args, **kwargs) with hub.start_span( - op="django.template.render", description=template_name + op="django.template.render", + description=_get_template_name_description(template_name), ) as span: span.set_data("context", context) return real_render(request, template_name, context, *args, **kwargs) diff --git a/tests/integrations/django/myapp/views.py b/tests/integrations/django/myapp/views.py index b6d9766d3a..29a4859b5d 100644 --- a/tests/integrations/django/myapp/views.py +++ b/tests/integrations/django/myapp/views.py @@ -122,7 +122,7 @@ def template_test(request, *args, **kwargs): @csrf_exempt def template_test2(request, *args, **kwargs): - return TemplateResponse(request, "user_name.html", {"user_age": 25}) + return TemplateResponse(request, ("user_name.html", "another_template.html"), {"user_age": 25}) @csrf_exempt diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index e094d23a72..7cbbeaae87 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -523,18 +523,19 @@ def test_render_spans(sentry_init, client, capture_events, render_span_tree): integrations=[DjangoIntegration()], traces_sample_rate=1.0, ) - views_urls = [reverse("template_test2")] + views_tests = [ + (reverse("template_test2"), '- op="django.template.render": description="[user_name.html, ...]"'), + ] if DJANGO_VERSION >= (1, 7): - views_urls.append(reverse("template_test")) + views_tests.append( + (reverse("template_test"), '- op="django.template.render": description="user_name.html"'), + ) - for url in views_urls: + for url, expected_line in views_tests: events = capture_events() _content, status, _headers = client.get(url) transaction = events[0] - assert ( - '- op="django.template.render": description="user_name.html"' - in render_span_tree(transaction) - ) + assert expected_line in render_span_tree(transaction) def test_middleware_spans(sentry_init, client, capture_events, render_span_tree):