Skip to content

Commit 6470100

Browse files
brettlangdonavara1986P403n1x87taegyunkimdd-octo-sts[bot]
authored
feat(django): add DD_DJANGO_TRACING_MINIMAL configuration option (#14468)
The new `DD_DJANGO_TRACING_MINIMAL` configuration option (off by default) will disable Django ORM, cache, and template spans. This has a sizable improvement on performance overhead of the traced application. Django applications generally have both the Django ORM/cache/template spans generated as well as the underlying engines (psycopg, redis, jinja2, etc). This means we will create duplicate spans for every db query, cache call, or template render. Setting `DD_DJANGO_TRACING_MINIMAL=true` will completely disable these additional spans and should help measurably with performance overhead of the application. Our microbenchmarks show about a 20% reduction in mean request latency when this setting is enabled (my local load tests were showing a 34% reduction in mean request latency). Note: Future major versions of our library may set this setting by default. That way you only need to explicitly enable this additional Django tracing if we do not yet support tracing of the underlying engine used for db/cache/template. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) --------- Co-authored-by: Alberto Vara <[email protected]> Co-authored-by: Gabriele N. Tornetta <[email protected]> Co-authored-by: Taegyun Kim <[email protected]> Co-authored-by: dd-octo-sts[bot] <200755185+dd-octo-sts[bot]@users.noreply.github.com> Co-authored-by: quinna-h <[email protected]> Co-authored-by: Gary Huang <[email protected]> Co-authored-by: Yun Kim <[email protected]> Co-authored-by: Christophe Papazian <[email protected]> Co-authored-by: ncybul <[email protected]> Co-authored-by: Rachel Yang <[email protected]> Co-authored-by: Sam Brenner <[email protected]> Co-authored-by: wantsui <[email protected]> Co-authored-by: Nick Ripley <[email protected]> Co-authored-by: Munir Abdinur <[email protected]> Co-authored-by: Emmett Butler <[email protected]> Co-authored-by: Manuel Álvarez Álvarez <[email protected]> Co-authored-by: Joey Zhao <[email protected]> Co-authored-by: Tyler Finethy <[email protected]> Co-authored-by: Federico Mon <[email protected]> Co-authored-by: Tyler Finethy <[email protected]> Co-authored-by: Florentin Labelle <[email protected]>
1 parent f6d8df9 commit 6470100

File tree

6 files changed

+56
-3
lines changed

6 files changed

+56
-3
lines changed

.gitlab/benchmarks/bp-runner.microbenchmarks.fail-on-breach.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ experiments:
5757
thresholds:
5858
- execution_time < 21.75 ms
5959
- max_rss_usage < 66.00 MB
60+
- name: djangosimple-tracer-minimal
61+
thresholds:
62+
- execution_time < 17.50 ms
63+
- max_rss_usage < 66.00 MB
6064
- name: djangosimple-tracer-native
6165
thresholds:
6266
- execution_time < 21.75 ms

benchmarks/django_simple/config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ baseline: &baseline
1010
always_create_database_spans: true
1111
django_instrument_templates: true
1212
native_writer: false
13+
django_minimal: false
1314
tracer: &tracer
1415
<<: *baseline
1516
tracer_enabled: true
@@ -52,3 +53,6 @@ tracer-no-templates:
5253
tracer-native:
5354
<<: *tracer
5455
native_writer: true
56+
tracer-minimal:
57+
<<: *tracer
58+
django_minimal: true

benchmarks/django_simple/scenario.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class DjangoSimple(bm.Scenario):
1717
always_create_database_spans: bool
1818
django_instrument_templates: bool
1919
native_writer: bool
20+
django_minimal: bool
2021

2122
def run(self):
2223
os.environ["DJANGO_SETTINGS_MODULE"] = "app"
@@ -26,6 +27,14 @@ def run(self):
2627
os.environ["DD_DJANGO_ALWAYS_CREATE_DATABASE_SPANS"] = "1" if self.always_create_database_spans else "0"
2728
os.environ["DD_DJANGO_INSTRUMENT_TEMPLATES"] = "1" if self.django_instrument_templates else "0"
2829

30+
# Use only the minimal setting and the defaults for everything else (mostly based on the value of "minimal")
31+
if self.django_minimal:
32+
os.environ["DD_DJANGO_TRACING_MINIMAL"] = "1"
33+
del os.environ["DD_DJANGO_INSTRUMENT_CACHES"]
34+
del os.environ["DD_DJANGO_INSTRUMENT_DATABASES"]
35+
del os.environ["DD_DJANGO_ALWAYS_CREATE_DATABASE_SPANS"]
36+
del os.environ["DD_DJANGO_INSTRUMENT_TEMPLATES"]
37+
2938
if self.profiler_enabled:
3039
os.environ.update(
3140
{"DD_PROFILING_ENABLED": "1", "DD_PROFILING_API_TIMEOUT": "0.1", "DD_PROFILING_UPLOAD_INTERVAL": "10"}

ddtrace/contrib/internal/django/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,29 @@
8585
8686
Default: ``False``
8787
88+
.. envvar:: DD_DJANGO_TRACING_MINIMAL
89+
90+
Enables minimal tracing mode for performance-sensitive applications. When enabled, this disables
91+
Django ORM, cache, and template instrumentation while keeping middleware instrumentation enabled.
92+
This can significantly reduce overhead by removing Django-specific spans while preserving visibility
93+
into the underlying database drivers, cache clients, and other integrations.
94+
95+
This is equivalent to setting:
96+
- ``DD_DJANGO_INSTRUMENT_TEMPLATES=false``
97+
- ``DD_DJANGO_INSTRUMENT_DATABASES=false``
98+
- ``DD_DJANGO_INSTRUMENT_CACHES=false``
99+
100+
For example, with ``DD_DJANGO_INSTRUMENT_DATABASES=false``, Django ORM query spans are disabled
101+
but database driver spans (e.g., psycopg, MySQLdb) will still be created, providing visibility
102+
into the actual database queries without the Django ORM overhead.
103+
104+
Consider using this option if your application is performance-sensitive and the additional
105+
Django-layer spans are not required for your observability needs.
106+
107+
Default: ``False``
108+
109+
*New in version v3.15.0.*
110+
88111
.. py:data:: ddtrace.config.django['instrument_middleware']
89112
90113
Whether or not to instrument middleware.

ddtrace/contrib/internal/django/patch.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939

4040
log = get_logger(__name__)
4141

42+
# TODO[4.0]: Change this to True by default
43+
DJANGO_TRACING_MINIMAL = asbool(_get_config("DD_DJANGO_TRACING_MINIMAL", default=False))
44+
4245
config._add(
4346
"django",
4447
dict(
@@ -49,10 +52,11 @@
4952
trace_fetch_methods=asbool(os.getenv("DD_DJANGO_TRACE_FETCH_METHODS", default=False)),
5053
distributed_tracing_enabled=True,
5154
instrument_middleware=asbool(os.getenv("DD_DJANGO_INSTRUMENT_MIDDLEWARE", default=True)),
52-
instrument_templates=asbool(os.getenv("DD_DJANGO_INSTRUMENT_TEMPLATES", default=True)),
53-
instrument_databases=asbool(os.getenv("DD_DJANGO_INSTRUMENT_DATABASES", default=True)),
55+
instrument_templates=asbool(os.getenv("DD_DJANGO_INSTRUMENT_TEMPLATES", default=not DJANGO_TRACING_MINIMAL)),
56+
instrument_databases=asbool(os.getenv("DD_DJANGO_INSTRUMENT_DATABASES", default=not DJANGO_TRACING_MINIMAL)),
57+
# TODO[4.0]: remove this option and make it the default behavior when databases are instrumented
5458
always_create_database_spans=asbool(os.getenv("DD_DJANGO_ALWAYS_CREATE_DATABASE_SPANS", default=True)),
55-
instrument_caches=asbool(os.getenv("DD_DJANGO_INSTRUMENT_CACHES", default=True)),
59+
instrument_caches=asbool(os.getenv("DD_DJANGO_INSTRUMENT_CACHES", default=not DJANGO_TRACING_MINIMAL)),
5660
trace_query_string=None, # Default to global config
5761
include_user_name=asm_config._django_include_user_name,
5862
include_user_email=asm_config._django_include_user_email,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
features:
3+
- |
4+
django: This introduces the ``DD_DJANGO_TRACING_MINIMAL`` environment variable for performance-sensitive applications.
5+
When enabled, this disables Django ORM, cache, and template instrumentation while keeping middleware instrumentation enabled.
6+
This significantly reduces overhead by removing Django-specific spans while preserving visibility into the underlying
7+
database drivers, cache clients, and other integrations. For example, with this enabled, Django ORM query spans are
8+
disabled but database driver spans (e.g., psycopg, MySQLdb) will still be created. To enable minimal tracing,
9+
set ``DD_DJANGO_TRACING_MINIMAL=true``.

0 commit comments

Comments
 (0)