Skip to content

Commit

Permalink
Fix wrong transaction names in Django 4.0+ (#1571)
Browse files Browse the repository at this point in the history
* Resolve view name through view_class

* Add a test for Django class-based view

* update changelog

Co-authored-by: Benjamin Wohlwend <beni@elastic.co>
  • Loading branch information
dhalenok and beniwohli authored Jun 13, 2022
1 parent f9a4236 commit fbfeabb
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ endif::[]
* Fix return for `opentelemetry.Span.is_recording()` {pull}1530[#1530]
* Fix error logging for bad SERVICE_NAME config {pull}1546[#1546]
* Do not instrument old versions of Tornado > 6.0 due to incompatibility {pull}1566[#1566]
* Fix transaction names for class based views in Django 4.0+ {pull}1571[#1571]
* Fix a problem with our logging handler failing to report internal errors in its emitter {pull}1568[#1568]
[[release-notes-6.x]]
Expand Down
4 changes: 3 additions & 1 deletion elasticapm/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ def get_name_from_func(func: FunctionType) -> str:

module = func.__module__

if hasattr(func, "__name__"):
if hasattr(func, "view_class"):
view_name = func.view_class.__name__
elif hasattr(func, "__name__"):
view_name = func.__name__
else: # Fall back if there's no __name__
view_name = func.__class__.__name__
Expand Down
9 changes: 9 additions & 0 deletions tests/contrib/django/django_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1662,3 +1662,12 @@ def test_default_app_config_present_by_version():
assert default_app_config_is_defined
else:
assert not default_app_config_is_defined


def test_transaction_name_from_class_based_view(client, django_elasticapm_client):
with override_settings(
**middleware_setting(django.VERSION, ["elasticapm.contrib.django.middleware.TracingMiddleware"])
):
client.get(reverse("elasticapm-class-based"))
transaction = django_elasticapm_client.events[TRANSACTION][0]
assert transaction["name"] == "GET tests.contrib.django.testapp.views.ClassBasedView"
1 change: 1 addition & 0 deletions tests/contrib/django/testapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def handler500(request):
re_path(r"^trigger-500-log-request$", views.logging_request_exc, name="elasticapm-log-request-exc"),
re_path(r"^streaming$", views.streaming_view, name="elasticapm-streaming-view"),
re_path(r"^name-override$", views.override_transaction_name_view, name="elasticapm-name-override"),
re_path(r"^class-based$", views.ClassBasedView.as_view(), name="elasticapm-class-based"),
)


Expand Down
6 changes: 6 additions & 0 deletions tests/contrib/django/testapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from django.contrib.auth.models import User
from django.http import HttpResponse, StreamingHttpResponse
from django.shortcuts import get_object_or_404, render
from django.views import View

import elasticapm

Expand Down Expand Up @@ -141,3 +142,8 @@ def override_transaction_name_view(request):
elasticapm.set_transaction_name("foo")
elasticapm.set_transaction_result("okydoky")
return HttpResponse()


class ClassBasedView(View):
def get(self, request):
return HttpResponse()

0 comments on commit fbfeabb

Please sign in to comment.