Open jsma opened 10 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: