Open jsma opened 7 months ago
We encountered this bug after updating to Django 5.0. We also run django in ASGI mode. In Django 4.x, transaction tracing worked fine, even in ASGI mode.
I have encountered this as well in Django 5.0. When I call the following within my view class
import elasticapm
elasticapm.label(obj_id='id')
I get this message: Ignored labels obj_id. No transaction currently active.
But when I downgrade to django 4.2.13 it works as expected
Created a new django 5.0.6 project.
Added in settings.py:
ELASTIC_APM = {
"SERVICE_NAME": "djangoasgi",
"SERVER_URL": "",
"API_KEY": "",
"DEBUG": True,
}
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'elasticapm.contrib.django',
]
Added in views:
from django.http import HttpResponse
import elasticapm
async def hello(request):
elasticapm.set_transaction_name("djangoasgi.hello")
elasticapm.label(is_asgi=True)
return HttpResponse("Hello")
In urls.py:
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('hello', views.hello),
]
in asgi.py:
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoasgi.settings')
from elasticapm.contrib.asgi import ASGITracingMiddleware
application = ASGITracingMiddleware(get_asgi_application())
run it via gunicorn djangoasgi.asgi:application -w 1 -k uvicorn.workers.UvicornWorker
And got
Thank you @xrmx doing that and extending your code fixed the issues I was having. I adapted your solution to use a custom middleware as I had a lot of URLs to monitor.
I have found that the config option TRANSACTION_IGNORE_URLS
didn't work with your solution though. I did some customisation to get it working with the middleware and ASGI middleware:
middleware.py
import elasticapm
from elasticapm.contrib.django.middleware import TracingMiddleware
class CustomTracingMiddleware(TracingMiddleware):
def process_request(self, request: HttpRequest):
if elasticapm.get_transaction_id():
transaction_name: str = "{} {}".format(request.method.upper(), request.path.lower()) #type: ignore
elasticapm.set_transaction_name(transaction_name) #type: ignore
return None
asgi.py
from elasticapm.contrib.asgi import ASGITracingMiddleware
class CustomASGITracingMiddleware(ASGITracingMiddleware):
def get_url(self, scope, host: str | None = None) -> Tuple[str, dict[str, str]]:
_, url_dict = super().get_url(scope, host)
path = scope.get("root_path", "") + scope.get("path", "")
return path, url_dict
application = CustomASGITracingMiddleware(get_asgi_application())
settings.py
MIDDLEWARE = [
'ehs_api.middleware.CustomTracingMiddleware',
# add others here
]
ELASTIC_APM = {
'SERVICE_NAME': 'djangoapm',
'SERVER_URL': '',
'DEBUG': True, #allows it to run in test mode
'TRANSACTION_IGNORE_URLS': [
'/__debug__/*',
],
'DJANGO_TRANSACTION_NAME_FROM_ROUTE': True,
'DJANGO_AUTOINSERT_MIDDLEWARE': False
}
(Moved from original discussion)
When running Django under ASGI, the middleware that Elastic APM injects is not tracking standard Django request transactions.
Here's my
asgi.py
:My
settings.ELASTIC_APM
:I've browsed several pages and waited for Fleet to flush but all I see are Celery tasks:
Nothing is logged as a
request
transaction type by the standard Django middleware when running under Daphne.If I switch the project back to standard WSGI/Django runserver, it logs request transactions: