From 84be62107b141c9c173f3b0f9b59da54facca0a8 Mon Sep 17 00:00:00 2001 From: quinna-h Date: Mon, 30 Dec 2024 12:52:28 -0500 Subject: [PATCH 1/9] add schematize service name --- ddtrace/contrib/internal/django/patch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddtrace/contrib/internal/django/patch.py b/ddtrace/contrib/internal/django/patch.py index c40f49b627f..d4b14487e39 100644 --- a/ddtrace/contrib/internal/django/patch.py +++ b/ddtrace/contrib/internal/django/patch.py @@ -215,7 +215,7 @@ def traced_cache(django, pin, func, instance, args, kwargs): "django.cache", span_name="django.cache", span_type=SpanTypes.CACHE, - service=config.django.cache_service_name, + service=schematize_service_name(config.django.cache_service_name), resource=utils.resource_from_cache_prefix(func_name(func), instance), tags=tags, pin=pin, From 049a40af6942696a98a8f2b3456c001a26343ca5 Mon Sep 17 00:00:00 2001 From: quinna-h Date: Mon, 30 Dec 2024 13:35:26 -0500 Subject: [PATCH 2/9] add release note --- ...-name-schematization-bef19b44b7414016.yaml | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml diff --git a/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml new file mode 100644 index 00000000000..0bca0715f2f --- /dev/null +++ b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml @@ -0,0 +1,29 @@ +--- +#instructions: +# The style guide below provides explanations, instructions, and templates to write your own release note. +# Once finished, all irrelevant sections (including this instruction section) should be removed, +# and the release note should be committed with the rest of the changes. +# +# The main goal of a release note is to provide a brief overview of a change and provide actionable steps to the user. +# The release note should clearly communicate what the change is, why the change was made, and how a user can migrate their code. +# +# The release note should also clearly distinguish between announcements and user instructions. Use: +# * Past tense for previous/existing behavior (ex: ``resulted, caused, failed``) +# * Third person present tense for the change itself (ex: ``adds, fixes, upgrades``) +# * Active present infinitive for user instructions (ex: ``set, use, add``) +# +# Release notes should: +# * Use plain language +# * Be concise +# * Include actionable steps with the necessary code changes +# * Include relevant links (bug issues, upstream issues or release notes, documentation pages) +# * Use full sentences with sentence-casing and punctuation. +# * Before using Datadog specific acronyms/terminology, a release note must first introduce them with a definition. +# +# Release notes should not: +# * Be vague. Example: ``fixes an issue in tracing``. +# * Use overly technical language +# * Use dynamic links (``stable/latest/1.x`` URLs). Instead, use static links (specific version, commit hash) whenever possible so that they don't break in the future. +fixes: + - | + Fixes issue where django cache is represented as django service rather than the third party service. \ No newline at end of file From 3f75ffce195e7c36e026a0b16cf691ed9ebae0ad Mon Sep 17 00:00:00 2001 From: quinna-h Date: Mon, 30 Dec 2024 13:55:43 -0500 Subject: [PATCH 3/9] add django test --- tests/contrib/django/test_django.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py index cf44ed6bcdd..3bea2f8285e 100644 --- a/tests/contrib/django/test_django.py +++ b/tests/contrib/django/test_django.py @@ -30,6 +30,7 @@ from ddtrace.ext import http from ddtrace.ext import user from ddtrace.internal.compat import ensure_text +from ddtrace.internal.schema import schematize_service_name from ddtrace.propagation._utils import get_wsgi_header from ddtrace.propagation.http import HTTP_HEADER_PARENT_ID from ddtrace.propagation.http import HTTP_HEADER_SAMPLING_PRIORITY @@ -1349,6 +1350,31 @@ def test_cache_set_many(test_spans): assert "second_key" in span_set_many.get_tag("django.cache.key") +def test_schematized_service_name_cache(test_spans): + from ddtrace import config + + cache = django.core.cache.caches["default"] + schema_version = "v1" + global_service_name = "custom-service" + + config.django.cache_service_name = "default-cache" + if schema_version is not None: + config._service_name_schema_version = schema_version + if global_service_name is not None: + config.service = global_service_name + + expected_service_name = schematize_service_name(config.django.cache_service_name) + + cache.set("test_key", "test_value") + + spans = test_spans.get_spans() + assert spans + + span = spans[0] + assert span.service == expected_service_name + assert span.name == "django.cache" + + def test_cache_delete_many(test_spans): # get the default cache cache = django.core.cache.caches["default"] From 06916a8dd4bf6e5892763dd59fd23a17e7f0c5cd Mon Sep 17 00:00:00 2001 From: quinna-h Date: Mon, 30 Dec 2024 14:21:59 -0500 Subject: [PATCH 4/9] update tests --- tests/contrib/django/test_django.py | 54 ++++++++--------------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py index 3bea2f8285e..870f7bf13dd 100644 --- a/tests/contrib/django/test_django.py +++ b/tests/contrib/django/test_django.py @@ -30,7 +30,6 @@ from ddtrace.ext import http from ddtrace.ext import user from ddtrace.internal.compat import ensure_text -from ddtrace.internal.schema import schematize_service_name from ddtrace.propagation._utils import get_wsgi_header from ddtrace.propagation.http import HTTP_HEADER_PARENT_ID from ddtrace.propagation.http import HTTP_HEADER_SAMPLING_PRIORITY @@ -571,7 +570,7 @@ def test_template_simple_view(client, test_spans): view_span = view_spans[0] view_span.assert_matches( name="django.view", - service="django", + service="custom-service", resource="tests.contrib.django.views.template_simple_view", error=0, ) @@ -755,7 +754,7 @@ def test_cache_get(test_spans): assert len(spans) == 1 span = spans[0] - assert span.service == "django" + assert span.service == "default-cache" assert span.resource == "django.core.cache.backends.locmem.get" assert span.name == "django.cache" assert span.span_type == "cache" @@ -782,7 +781,7 @@ def test_cache_get_rowcount_existing_key(test_spans): assert len(spans) == 2 span = spans[1] - assert span.service == "django" + assert span.service == "default-cache" assert span.resource == "django.core.cache.backends.locmem.get" assert_dict_issuperset(span.get_metrics(), {"db.row_count": 1}) @@ -798,7 +797,7 @@ def test_cache_get_rowcount_missing_key(test_spans): assert len(spans) == 1 span = spans[0] - assert span.service == "django" + assert span.service == "default-cache" assert span.resource == "django.core.cache.backends.locmem.get" assert_dict_issuperset(span.get_metrics(), {"db.row_count": 0}) @@ -839,7 +838,7 @@ def test_cache_get_rowcount_missing_key_with_default(test_spans): spans = test_spans.get_spans() assert len(spans) == 1 span = spans[0] - assert span.service == "django" + assert span.service == "default-cache" assert span.resource == "django.core.cache.backends.locmem.get" assert_dict_issuperset(span.get_metrics(), {"db.row_count": 1}) @@ -977,7 +976,7 @@ def test_cache_get_unicode(test_spans): assert len(spans) == 1 span = spans[0] - assert span.service == "django" + assert span.service == "default-cache" assert span.resource == "django.core.cache.backends.locmem.get" assert span.name == "django.cache" assert span.span_type == "cache" @@ -1170,12 +1169,12 @@ def test_cache_decr_2XX(test_spans): span_incr = spans[1] # LocMemCache doesn't provide an atomic operation - assert span_incr.service == "django" + assert span_incr.service == "default-cache" assert span_incr.resource == "django.core.cache.backends.locmem.incr" assert span_incr.name == "django.cache" assert span_incr.span_type == "cache" assert span_incr.error == 0 - assert span_decr.service == "django" + assert span_decr.service == "default-cache" assert span_decr.resource == "django.core.cache.backends.base.decr" assert span_decr.name == "django.cache" assert span_decr.span_type == "cache" @@ -1329,17 +1328,17 @@ def test_cache_set_many(test_spans): span_set_second = spans[2] # LocMemCache doesn't provide an atomic operation - assert span_set_first.service == "django" + assert span_set_first.service == "default-cache" assert span_set_first.resource == "django.core.cache.backends.locmem.set" assert span_set_first.name == "django.cache" assert span_set_first.span_type == "cache" assert span_set_first.error == 0 - assert span_set_second.service == "django" + assert span_set_second.service == "default-cache" assert span_set_second.resource == "django.core.cache.backends.locmem.set" assert span_set_second.name == "django.cache" assert span_set_second.span_type == "cache" assert span_set_second.error == 0 - assert span_set_many.service == "django" + assert span_set_many.service == "default-cache" assert span_set_many.resource == "django.core.cache.backends.base.set_many" assert span_set_many.name == "django.cache" assert span_set_many.span_type == "cache" @@ -1350,31 +1349,6 @@ def test_cache_set_many(test_spans): assert "second_key" in span_set_many.get_tag("django.cache.key") -def test_schematized_service_name_cache(test_spans): - from ddtrace import config - - cache = django.core.cache.caches["default"] - schema_version = "v1" - global_service_name = "custom-service" - - config.django.cache_service_name = "default-cache" - if schema_version is not None: - config._service_name_schema_version = schema_version - if global_service_name is not None: - config.service = global_service_name - - expected_service_name = schematize_service_name(config.django.cache_service_name) - - cache.set("test_key", "test_value") - - spans = test_spans.get_spans() - assert spans - - span = spans[0] - assert span.service == expected_service_name - assert span.name == "django.cache" - - def test_cache_delete_many(test_spans): # get the default cache cache = django.core.cache.caches["default"] @@ -1389,17 +1363,17 @@ def test_cache_delete_many(test_spans): span_delete_second = spans[2] # LocMemCache doesn't provide an atomic operation - assert span_delete_first.service == "django" + assert span_delete_first.service == "default-cache" assert span_delete_first.resource == "django.core.cache.backends.locmem.delete" assert span_delete_first.name == "django.cache" assert span_delete_first.span_type == "cache" assert span_delete_first.error == 0 - assert span_delete_second.service == "django" + assert span_delete_second.service == "default-cache" assert span_delete_second.resource == "django.core.cache.backends.locmem.delete" assert span_delete_second.name == "django.cache" assert span_delete_second.span_type == "cache" assert span_delete_second.error == 0 - assert span_delete_many.service == "django" + assert span_delete_many.service == "default-cache" assert span_delete_many.resource == "django.core.cache.backends.base.delete_many" assert span_delete_many.name == "django.cache" assert span_delete_many.span_type == "cache" From d94eecd7ac40b70ec39f93529f487be4299b62ae Mon Sep 17 00:00:00 2001 From: quinna-h Date: Mon, 30 Dec 2024 14:23:48 -0500 Subject: [PATCH 5/9] update tests update tests wip update test add test --- tests/contrib/django/test_django.py | 48 ++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py index 870f7bf13dd..93613323162 100644 --- a/tests/contrib/django/test_django.py +++ b/tests/contrib/django/test_django.py @@ -30,6 +30,7 @@ from ddtrace.ext import http from ddtrace.ext import user from ddtrace.internal.compat import ensure_text +from ddtrace.internal.schema import schematize_service_name from ddtrace.propagation._utils import get_wsgi_header from ddtrace.propagation.http import HTTP_HEADER_PARENT_ID from ddtrace.propagation.http import HTTP_HEADER_SAMPLING_PRIORITY @@ -570,7 +571,7 @@ def test_template_simple_view(client, test_spans): view_span = view_spans[0] view_span.assert_matches( name="django.view", - service="custom-service", + service="django", resource="tests.contrib.django.views.template_simple_view", error=0, ) @@ -754,7 +755,7 @@ def test_cache_get(test_spans): assert len(spans) == 1 span = spans[0] - assert span.service == "default-cache" + assert span.service == "django" assert span.resource == "django.core.cache.backends.locmem.get" assert span.name == "django.cache" assert span.span_type == "cache" @@ -769,6 +770,25 @@ def test_cache_get(test_spans): assert_dict_issuperset(span.get_tags(), expected_meta) +def test_cache_service_schematization(test_spans): + from ddtrace import config + + cache = django.core.cache.caches["default"] + + env = os.environ.copy() + + env["DD_SERVICE"] = "custom-service-name" + + cache.set("test_key", "test_value") + expected_service_name = schematize_service_name(config.django.cache_service_name) + + spans = test_spans.get_spans() + assert spans + + span = spans[0] + assert span.service == expected_service_name + + def test_cache_get_rowcount_existing_key(test_spans): # get the default cache cache = django.core.cache.caches["default"] @@ -781,7 +801,7 @@ def test_cache_get_rowcount_existing_key(test_spans): assert len(spans) == 2 span = spans[1] - assert span.service == "default-cache" + assert span.service == "django" assert span.resource == "django.core.cache.backends.locmem.get" assert_dict_issuperset(span.get_metrics(), {"db.row_count": 1}) @@ -797,7 +817,7 @@ def test_cache_get_rowcount_missing_key(test_spans): assert len(spans) == 1 span = spans[0] - assert span.service == "default-cache" + assert span.service == "django" assert span.resource == "django.core.cache.backends.locmem.get" assert_dict_issuperset(span.get_metrics(), {"db.row_count": 0}) @@ -838,7 +858,7 @@ def test_cache_get_rowcount_missing_key_with_default(test_spans): spans = test_spans.get_spans() assert len(spans) == 1 span = spans[0] - assert span.service == "default-cache" + assert span.service == "django" assert span.resource == "django.core.cache.backends.locmem.get" assert_dict_issuperset(span.get_metrics(), {"db.row_count": 1}) @@ -976,7 +996,7 @@ def test_cache_get_unicode(test_spans): assert len(spans) == 1 span = spans[0] - assert span.service == "default-cache" + assert span.service == "django" assert span.resource == "django.core.cache.backends.locmem.get" assert span.name == "django.cache" assert span.span_type == "cache" @@ -1169,12 +1189,12 @@ def test_cache_decr_2XX(test_spans): span_incr = spans[1] # LocMemCache doesn't provide an atomic operation - assert span_incr.service == "default-cache" + assert span_incr.service == "django" assert span_incr.resource == "django.core.cache.backends.locmem.incr" assert span_incr.name == "django.cache" assert span_incr.span_type == "cache" assert span_incr.error == 0 - assert span_decr.service == "default-cache" + assert span_decr.service == "django" assert span_decr.resource == "django.core.cache.backends.base.decr" assert span_decr.name == "django.cache" assert span_decr.span_type == "cache" @@ -1328,17 +1348,17 @@ def test_cache_set_many(test_spans): span_set_second = spans[2] # LocMemCache doesn't provide an atomic operation - assert span_set_first.service == "default-cache" + assert span_set_first.service == "django" assert span_set_first.resource == "django.core.cache.backends.locmem.set" assert span_set_first.name == "django.cache" assert span_set_first.span_type == "cache" assert span_set_first.error == 0 - assert span_set_second.service == "default-cache" + assert span_set_second.service == "django" assert span_set_second.resource == "django.core.cache.backends.locmem.set" assert span_set_second.name == "django.cache" assert span_set_second.span_type == "cache" assert span_set_second.error == 0 - assert span_set_many.service == "default-cache" + assert span_set_many.service == "django" assert span_set_many.resource == "django.core.cache.backends.base.set_many" assert span_set_many.name == "django.cache" assert span_set_many.span_type == "cache" @@ -1363,17 +1383,17 @@ def test_cache_delete_many(test_spans): span_delete_second = spans[2] # LocMemCache doesn't provide an atomic operation - assert span_delete_first.service == "default-cache" + assert span_delete_first.service == "django" assert span_delete_first.resource == "django.core.cache.backends.locmem.delete" assert span_delete_first.name == "django.cache" assert span_delete_first.span_type == "cache" assert span_delete_first.error == 0 - assert span_delete_second.service == "default-cache" + assert span_delete_second.service == "django" assert span_delete_second.resource == "django.core.cache.backends.locmem.delete" assert span_delete_second.name == "django.cache" assert span_delete_second.span_type == "cache" assert span_delete_second.error == 0 - assert span_delete_many.service == "default-cache" + assert span_delete_many.service == "django" assert span_delete_many.resource == "django.core.cache.backends.base.delete_many" assert span_delete_many.name == "django.cache" assert span_delete_many.span_type == "cache" From aa45be75b8dab50956e4a98ad3f321ab8e143c43 Mon Sep 17 00:00:00 2001 From: quinna-h Date: Mon, 30 Dec 2024 18:12:27 -0500 Subject: [PATCH 6/9] test --- tests/contrib/django/test_django.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py index 93613323162..da00c076675 100644 --- a/tests/contrib/django/test_django.py +++ b/tests/contrib/django/test_django.py @@ -775,18 +775,13 @@ def test_cache_service_schematization(test_spans): cache = django.core.cache.caches["default"] - env = os.environ.copy() - - env["DD_SERVICE"] = "custom-service-name" - - cache.set("test_key", "test_value") - expected_service_name = schematize_service_name(config.django.cache_service_name) - - spans = test_spans.get_spans() - assert spans - - span = spans[0] - assert span.service == expected_service_name + with override_config("django", dict(cache_service_name="test-cache-service")): + cache.get("missing_key") + spans = test_spans.get_spans() + assert spans + span = spans[0] + expected_service_name = schematize_service_name(config.django.cache_service_name) + assert span.service == expected_service_name def test_cache_get_rowcount_existing_key(test_spans): From 5b3b5c9edc4259aa727be9a9987d3aaf956280c8 Mon Sep 17 00:00:00 2001 From: quinna-h Date: Mon, 30 Dec 2024 18:20:28 -0500 Subject: [PATCH 7/9] cleanup release note --- ...-name-schematization-bef19b44b7414016.yaml | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml index 0bca0715f2f..f9e5b2d1d97 100644 --- a/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml +++ b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml @@ -1,29 +1,4 @@ --- -#instructions: -# The style guide below provides explanations, instructions, and templates to write your own release note. -# Once finished, all irrelevant sections (including this instruction section) should be removed, -# and the release note should be committed with the rest of the changes. -# -# The main goal of a release note is to provide a brief overview of a change and provide actionable steps to the user. -# The release note should clearly communicate what the change is, why the change was made, and how a user can migrate their code. -# -# The release note should also clearly distinguish between announcements and user instructions. Use: -# * Past tense for previous/existing behavior (ex: ``resulted, caused, failed``) -# * Third person present tense for the change itself (ex: ``adds, fixes, upgrades``) -# * Active present infinitive for user instructions (ex: ``set, use, add``) -# -# Release notes should: -# * Use plain language -# * Be concise -# * Include actionable steps with the necessary code changes -# * Include relevant links (bug issues, upstream issues or release notes, documentation pages) -# * Use full sentences with sentence-casing and punctuation. -# * Before using Datadog specific acronyms/terminology, a release note must first introduce them with a definition. -# -# Release notes should not: -# * Be vague. Example: ``fixes an issue in tracing``. -# * Use overly technical language -# * Use dynamic links (``stable/latest/1.x`` URLs). Instead, use static links (specific version, commit hash) whenever possible so that they don't break in the future. fixes: - | Fixes issue where django cache is represented as django service rather than the third party service. \ No newline at end of file From 1b2be7e031b1119403ec358d7cf7cd6009cd1ccd Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Thu, 2 Jan 2025 09:35:18 -0500 Subject: [PATCH 8/9] rn Co-authored-by: erikayasuda <153395705+erikayasuda@users.noreply.github.com> --- ...ango-cache-service-name-schematization-bef19b44b7414016.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml index f9e5b2d1d97..4447ecfe446 100644 --- a/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml +++ b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml @@ -1,4 +1,4 @@ --- fixes: - | - Fixes issue where django cache is represented as django service rather than the third party service. \ No newline at end of file + django: Fixes issue where django cache is represented as a django service rather than the third party service. \ No newline at end of file From 71a7f0b48cf2ce18b198dd47faf9e57008fe16a9 Mon Sep 17 00:00:00 2001 From: quinna-h Date: Thu, 2 Jan 2025 10:13:57 -0500 Subject: [PATCH 9/9] address nits --- ...ango-cache-service-name-schematization-bef19b44b7414016.yaml | 2 +- tests/contrib/django/test_django.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml index 4447ecfe446..0fbdb9993a5 100644 --- a/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml +++ b/releasenotes/notes/django-cache-service-name-schematization-bef19b44b7414016.yaml @@ -1,4 +1,4 @@ --- fixes: - | - django: Fixes issue where django cache is represented as a django service rather than the third party service. \ No newline at end of file + tracing(django): Fixes issue where django cache is represented as a django service rather than the third party service. \ No newline at end of file diff --git a/tests/contrib/django/test_django.py b/tests/contrib/django/test_django.py index da00c076675..1bd223539c9 100644 --- a/tests/contrib/django/test_django.py +++ b/tests/contrib/django/test_django.py @@ -771,8 +771,6 @@ def test_cache_get(test_spans): def test_cache_service_schematization(test_spans): - from ddtrace import config - cache = django.core.cache.caches["default"] with override_config("django", dict(cache_service_name="test-cache-service")):