Repository: DataDog/dd-trace-py

Issue:
Django patching not properly capturing function middleware names
### Which version of dd-trace-py are you using?

0.53.2

### Which version of pip are you using?

21.2.3

### Which version of the libraries are you using?

```
aa-stripe==0.11.0
aiohttp==3.7.4.post0
amqp==2.6.1
anyio==3.3.0
appdirs==1.4.4
appnope==0.1.2
argon2-cffi==20.1.0
async-timeout==3.0.1
attrs==21.2.0
awscli==1.20.11
Babel==2.9.1
backcall==0.2.0
bcrypt==3.2.0
beautifulsoup4==4.10.0
billiard==3.6.4.0
black==21.9b0
bleach==4.1.0
boto3==1.18.44
botocore==1.21.44
braintree==4.12.0
cachetools==4.2.2
cairocffi==1.2.0
CairoSVG==2.5.2
celery==4.4.2
certifi==2021.5.30
cffi==1.14.6
chardet==4.0.0
charset-normalizer==2.0.4
click==8.0.1
colorama==0.4.3
ConfigArgParse==1.5.2
convertdate==2.3.2
coreapi==2.3.3
coreschema==0.0.4
coverage==5.5
cryptography==3.4.8
cssselect==1.1.0
cssselect2==0.4.1
cssutils==2.3.0
curlify==2.2.1
datadog==0.42.0
ddtrace==0.53.2
debugpy==1.4.3
decorator==5.1.0
deepdiff==5.5.0
defusedxml==0.7.1
Django==2.2.24
django-admin-rangefilter==0.8.1
django-appconf==1.0.4
django-better-admin-arrayfield==1.4.2
django-celery-email==3.0.0
django-crispy-forms==1.12.0
django-extensions==3.1.3
django-filter==2.4.0
django-formtools==2.3
django-health-check==3.16.4
django-html-sanitizer==0.1.5
django-ipware==4.0.0
django-jet==1.0.8
django-localflavor==3.1
django-migration-linter==3.0.1
django-picklefield==3.0.1
django-push-notifications==1.4.1
django-redis==5.0.0
django-related-admin==1.0.1
django-rest-swagger==2.2.0
django-rosetta==0.9.7
django-safedelete==0.3.5
django-sendgrid-v5==0.8.1
django-ses==2.2.1
django-storages==1.11.1
django-websocket-redis==0.6.0
djangorestframework==3.12.4
djangorestframework-dataclasses==0.10
docutils==0.17.1
drf-tweaks==0.9.6
easypost==5.1.3
elasticsearch==6.8.2
entrypoints==0.3
execnet==1.9.0
facebook-business==12.0.0
factory-boy==3.2.0
Faker==8.13.2
fakeredis==1.6.1
fdadb==0.1.1
flake8==3.9.2
Flask==1.1.2
Flask-BasicAuth==0.2.0
Flask-Cors==3.0.10
flower==0.9.7
flup6==1.1.1
freezegun==1.1.0
frogress==0.9.1
future==0.18.2
gevent==21.8.0
geventhttpclient==1.4.4
google-api-core==1.31.2
google-api-python-client==2.0.2
google-auth==1.35.0
google-auth-httplib2==0.1.0
googleapis-common-protos==1.53.0
greenlet==1.1.1
gunicorn==20.1.0
hijri-converter==2.2.0
hiredis==2.0.0
holidays==0.11.2
html5lib==1.1
http-ece==1.1.0
httplib2==0.19.1
humanize==3.11.0
idna==2.10
ijson==3.1.4
iniconfig==1.1.1
intervaltree==3.1.0
ipykernel==6.2.0
ipython==7.27.0
ipython-genutils==0.2.0
isodate==0.6.0
isort==5.9.3
itsdangerous==2.0.1
itypes==1.2.0
jedi==0.18.0
Jinja2==3.0.1
jmespath==0.10.0
json5==0.9.6
jsonschema==3.2.0
jupyter-client==6.1.12
jupyter-core==4.7.1
jupyter-server==1.10.2
jupyterlab==3.1.12
jupyterlab-pygments==0.1.2
jupyterlab-server==2.7.1
kombu==4.6.11
korean-lunar-calendar==0.2.1
locust==1.6.0
lxml==4.6.3
MarkupSafe==2.0.1
matplotlib-inline==0.1.2
mccabe==0.6.1
mistune==0.8.4
mixpanel==4.8.3
mmh3==3.0.0
mock==4.0.3
more-itertools==8.8.0
moto==2.2.7
msgpack==1.0.2
multidict==5.1.0
mypy==0.910
mypy-extensions==0.4.3
nbclassic==0.3.1
nbclient==0.5.4
nbconvert==6.1.0
nbformat==5.1.3
nest-asyncio==1.5.1
notebook==6.4.3
numpy==1.21.2
openapi-codec==1.3.2
ordered-set==4.0.2
<internal package>
packaging==21.0
pandas==1.3.3
pandocfilters==1.4.3
paramiko==2.7.2
parso==0.8.2
pathspec==0.9.0
pep8==1.7.1
pexpect==4.8.0
phonenumbers==8.12.31
pickleshare==0.7.5
Pillow==8.3.2
platformdirs==2.4.0
pluggy==0.13.1
polib==1.1.1
premailer==3.9.0
prometheus-client==0.8.0
prompt-toolkit==3.0.19
protobuf==3.17.3
psutil==5.8.0
psycogreen==1.0.2
psycopg2-binary==2.8.6
ptyprocess==0.7.0
py==1.10.0
py-vapid==1.8.2
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycodestyle==2.7.0
pycountry==20.7.3
pycparser==2.20
pycryptodome==3.10.1
pycryptodomex==3.10.1
pydocstyle==6.1.1
pyfcm==1.5.4
pyflakes==2.3.1
Pygments==2.10.0
pyheif==0.5.1
PyJWT==2.1.0
pylama==7.7.1
PyMeeus==0.5.11
PyNaCl==1.4.0
pyparsing==2.4.7
pyphen==0.11.0
pyrsistent==0.18.0
pytest==6.2.5
pytest-django==4.2.0
pytest-env==0.6.2
pytest-forked==1.3.0
pytest-split==0.3.3
pytest-xdist==2.3.0
python-barcode==0.13.1
python-dateutil==2.8.2
python-http-client==3.1.0
python-magic==0.4.24
python-stdnum==1.16
pytz==2021.1
PyYAML==5.4.1
pyzipper==0.3.5
pyzmq==22.2.1
rapidfuzz==1.6.2
redis==3.5.3
regex==2021.8.3
requests==2.26.0
requests-mock==1.9.3
requests-toolbelt==0.9.1
requests-unixsocket==0.2.0
responses==0.13.4
rjsmin==1.1.0
<internal package>
rsa==4.7.2
s3transfer==0.5.0
Send2Trash==1.8.0
sendgrid==5.6.0
sentry-sdk==1.3.1
simplejson==3.17.5
six==1.16.0
sniffio==1.2.0
snowballstemmer==2.1.0
sorl-thumbnail==12.7.0
sortedcontainers==2.4.0
soupsieve==2.2.1
sqlparse==0.4.1
stripe==2.60.0
structlog==21.1.0
tenacity==8.0.1
terminado==0.11.0
testpath==0.5.0
text-unidecode==1.3
tinycss2==1.1.0
toml==0.10.2
tomli==1.2.1
tornado==6.1
traitlets==5.1.0
twilio==6.50.1
types-bleach==4.1.0
types-boto==2.49.0
types-certifi==2020.4.0
types-cryptography==3.3.3
types-enum34==1.1.0
types-freezegun==1.1.0
types-futures==3.3.0
types-ipaddress==1.0.0
types-mock==4.0.1
types-pkg-resources==0.1.3
types-protobuf==3.17.4
types-python-dateutil==2.8.0
types-pytz==2021.1.2
types-PyYAML==5.4.10
types-requests==2.25.7
types-simplejson==3.17.0
types-six==1.16.1
typing-extensions==3.10.0.0
ua-parser==0.10.0
Unidecode==1.3.2
universal-notifications==1.4.0
uritemplate==3.0.1
urllib3==1.26.6
user-agents==2.2.0
uWSGI==2.0.19.1
vine==1.3.0
wcwidth==0.2.5
WeasyPrint==52.5
webencodings==0.5.1
websocket-client==1.2.1
Werkzeug==2.0.1
wrapt==1.12.1
xmltodict==0.12.0
yarl==1.6.3
zope.event==4.5.0
zope.interface==5.4.0
```

### How can we reproduce your problem?
### What is the result that you get?
### What is the result that you expected?

Set up a Django app with multiple function (not class based) middlewares. Make a request to any view. Observe that the Datadog APM spans for all function based middlewares are labeled with the *last* middleware as set in the Django MIDDLEWARE configuration variable in settings.py. They should be labeled correctly.

I believe the error lies in the delayed evaluation of the `mw_path` variable here, when it has already finished iterating over `settings_middleware`. 

https://github.com/DataDog/dd-trace-py/blob/v0.53.2/ddtrace/contrib/django/patch.py#L260





Discussion:
@anlu sorry for the long delay getting back to you.

Your investigation was spot on. That is exactly what is happening, we are using a reference to `mw_path` which is updated by the loop, so all function middleware share the same resource name.

I have a fix available in #2884 that will resolve this.

Thank you for reporting!!

Resolving patch:
diff --git a/ddtrace/contrib/django/patch.py b/ddtrace/contrib/django/patch.py
--- a/ddtrace/contrib/django/patch.py
+++ b/ddtrace/contrib/django/patch.py
@@ -252,19 +252,28 @@ def traced_load_middleware(django, pin, func, instance, args, kwargs):
             base = ".".join(split[:-1])
             attr = split[-1]
 
-            # Function-based middleware is a factory which returns a handler function for requests.
-            # So instead of tracing the factory, we want to trace its returned value.
-            # We wrap the factory to return a traced version of the handler function.
-            def wrapped_factory(func, instance, args, kwargs):
-                # r is the middleware handler function returned from the factory
-                r = func(*args, **kwargs)
-                if r:
-                    return wrapt.FunctionWrapper(r, traced_func(django, "django.middleware", resource=mw_path))
-                # If r is an empty middleware function (i.e. returns None), don't wrap since NoneType cannot be called
-                else:
-                    return r
-
-            trace_utils.wrap(base, attr, wrapped_factory)
+            # DEV: We need to have a closure over `mw_path` for the resource name or else
+            # all function based middleware will share the same resource name
+            def _wrapper(resource):
+                # Function-based middleware is a factory which returns a handler function for requests.
+                # So instead of tracing the factory, we want to trace its returned value.
+                # We wrap the factory to return a traced version of the handler function.
+                def wrapped_factory(func, instance, args, kwargs):
+                    # r is the middleware handler function returned from the factory
+                    r = func(*args, **kwargs)
+                    if r:
+                        return wrapt.FunctionWrapper(
+                            r,
+                            traced_func(django, "django.middleware", resource=resource),
+                        )
+                    # If r is an empty middleware function (i.e. returns None), don't wrap since
+                    # NoneType cannot be called
+                    else:
+                        return r
+
+                return wrapped_factory
+
+            trace_utils.wrap(base, attr, _wrapper(resource=mw_path))
 
         # Instrument class-based middleware
         elif isclass(mw):


Test patch:
diff --git a/tests/contrib/django/middleware.py b/tests/contrib/django/middleware.py
--- a/tests/contrib/django/middleware.py
+++ b/tests/contrib/django/middleware.py
@@ -42,6 +42,16 @@ def mw(request):
     return mw
 
 
+def fn2_middleware(get_response):
+    """Function factory middleware."""
+
+    def mw(request):
+        response = get_response(request)
+        return response
+
+    return mw
+
+
 def empty_middleware(get_response):
     """Empty function middleware for regression testing."""
 
diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py
--- a/tests/contrib/django/test_django.py
+++ b/tests/contrib/django/test_django.py
@@ -278,7 +278,7 @@ def test_v2XX_middleware(client, test_spans):
         "django.middleware.security.SecurityMiddleware.process_request",
         "django.middleware.security.SecurityMiddleware.process_response",
         "tests.contrib.django.middleware.ClsMiddleware.__call__",
-        "tests.contrib.django.middleware.EverythingMiddleware",
+        "tests.contrib.django.middleware.fn_middleware",
         "tests.contrib.django.middleware.EverythingMiddleware.__call__",
         "tests.contrib.django.middleware.EverythingMiddleware.process_view",
     }
@@ -449,6 +449,15 @@ def test_empty_middleware_func_is_raised_in_django(client, test_spans):
             client.get("/")
 
 
+@pytest.mark.skipif(django.VERSION < (2, 0, 0), reason="")
+def test_multiple_fn_middleware_resource_names(client, test_spans):
+    with modify_settings(MIDDLEWARE={"append": "tests.contrib.django.middleware.fn2_middleware"}):
+        client.get("/")
+
+    assert test_spans.find_span(name="django.middleware", resource="tests.contrib.django.middleware.fn_middleware")
+    assert test_spans.find_span(name="django.middleware", resource="tests.contrib.django.middleware.fn2_middleware")
+
+
 """
 View tests
 """
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions.snap
@@ -150,7 +150,7 @@
                                    "duration" 1007000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions_21x.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions_21x.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions_21x.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_404_exceptions_21x.snap
@@ -149,7 +149,7 @@
                                    "duration" 1023000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_30.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_30.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_30.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_30.snap
@@ -150,7 +150,7 @@
                                    "duration" 239310}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_31.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_31.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_31.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_31.snap
@@ -152,7 +152,7 @@
                                    "duration" 1720934}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_3x.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_3x.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_3x.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_200_3x.snap
@@ -152,7 +152,7 @@
                                    "duration" 2065900}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_30.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_30.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_30.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_30.snap
@@ -150,7 +150,7 @@
                                    "duration" 1747119558}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_31.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_31.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_31.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_31.snap
@@ -152,7 +152,7 @@
                                    "duration" 715051343}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_3x.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_3x.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_3x.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_asgi_500_3x.snap
@@ -152,7 +152,7 @@
                                    "duration" 392354711}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view.snap
@@ -150,7 +150,7 @@
                                    "duration" 2500000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view_21x.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view_21x.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view_21x.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_callable_view_21x.snap
@@ -149,7 +149,7 @@
                                    "duration" 4249000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view.snap
@@ -150,7 +150,7 @@
                                    "duration" 826000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view_21x.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view_21x.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view_21x.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_middleware_trace_partial_based_view_21x.snap
@@ -149,7 +149,7 @@
                                    "duration" 471000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding.snap
@@ -152,7 +152,7 @@
                                    "duration" 5091000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding_21x.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding_21x.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding_21x.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_safe_string_encoding_21x.snap
@@ -151,7 +151,7 @@
                                    "duration" 1775000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include.snap
@@ -150,7 +150,7 @@
                                    "duration" 2086000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0
diff --git a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include_21x.snap b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include_21x.snap
--- a/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include_21x.snap
+++ b/tests/snapshots/tests.contrib.django.test_django_snapshots.test_urlpatterns_include_21x.snap
@@ -149,7 +149,7 @@
                                    "duration" 340000}
                                       {"name" "django.middleware"
                                        "service" "django"
-                                       "resource" "tests.contrib.django.middleware.EverythingMiddleware"
+                                       "resource" "tests.contrib.django.middleware.fn_middleware"
                                        "error" 0
                                        "span_id" 21
                                        "trace_id" 0