Skip to content

Commit df0ef7f

Browse files
chore(tracing/aiohttp_jinja2): automatically enable aiohttp_jinja2 tracing on its own (#3450) (#3507)
aiohttp_jinja2 used to be included in the aiohttp integration. In #3356 the aiohttp_jinja2 integration was separated into its own integration but kept in the testsuite of aiohttp. For backwards compatibility aiohttp_jinja2 was still enabled using the aiohttp integration. Both of these combined this led to a bug that went uncaught by the testsuite which was fixed in #3449. To avoid further issues and to be consistent with the rest of the library the aiohttp_jinja2 is separated further out with its test suite and is no longer enabled via aiohttp so now the two integrations are independent. Co-authored-by: Kyle Verhoog <[email protected]> (cherry picked from commit db50385) Co-authored-by: Brett Langdon <[email protected]>
1 parent 7e78698 commit df0ef7f

18 files changed

+257
-113
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ jobs:
480480
parallelism: 6
481481
steps:
482482
- run_test:
483-
pattern: 'aiohttp'
483+
pattern: 'aiohttp' # includes aiohttp_jinja2
484484
snapshot: true
485485
docker_services: 'httpbin_local'
486486

ddtrace/_monkey.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"sqlalchemy": False, # Prefer DB client instrumentation
5353
"sqlite3": True,
5454
"aiohttp": True, # requires asyncio (Python 3.4+)
55+
"aiohttp_jinja2": True,
5556
"aiopg": True,
5657
"aiobotocore": False,
5758
"httplib": False,
@@ -74,7 +75,6 @@
7475
"fastapi": True,
7576
"dogpile_cache": True,
7677
"yaaredis": True,
77-
"aiohttp_jinja2": False, # disabled as this is handled by aiohttp for now.
7878
"asyncpg": True,
7979
}
8080

ddtrace/contrib/aiohttp/patch.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,6 @@ def _patch_client(aiohttp):
104104

105105

106106
def patch():
107-
# Legacy patch aiohttp_jinja2
108-
from ddtrace.contrib.aiohttp_jinja2.patch import patch as aiohttp_jinja2_patch
109-
110-
aiohttp_jinja2_patch()
111-
112107
import aiohttp
113108

114109
if getattr(aiohttp, "_datadog_patch", False):
@@ -125,10 +120,6 @@ def _unpatch_client(aiohttp):
125120

126121

127122
def unpatch():
128-
from ddtrace.contrib.aiohttp_jinja2.patch import unpatch as aiohttp_jinja2_unpatch
129-
130-
aiohttp_jinja2_unpatch()
131-
132123
import aiohttp
133124

134125
if not getattr(aiohttp, "_datadog_patch", False):
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
upgrade:
3+
- |
4+
aiohttp_jinja2: use ``patch(aiohttp_jinja2=True)`` instead of ``patch(aiohttp=True)`` for
5+
enabling/disabling the integration.

riotfile.py

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,6 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION):
14041404
pys=select_pys(min_version="3.5", max_version="3.6"),
14051405
pkgs={
14061406
"aiohttp": ["~=2.0", "~=2.1", "~=2.2", "~=2.3"],
1407-
"aiohttp_jinja2": ["~=0.12", "~=0.13", "~=0.15"],
14081407
"async-timeout": ["<4.0.0"],
14091408
"yarl": "~=0.18.0",
14101409
},
@@ -1421,12 +1420,11 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION):
14211420
"~=3.8",
14221421
latest,
14231422
],
1424-
"aiohttp_jinja2": latest,
14251423
"yarl": "~=1.0",
14261424
},
14271425
),
14281426
Venv(
1429-
pys=select_pys(min_version="3.7", max_version="3.10"),
1427+
pys=select_pys(min_version="3.7"),
14301428
pkgs={
14311429
"pytest-asyncio": [latest],
14321430
"aiohttp": [
@@ -1437,12 +1435,71 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION):
14371435
"~=3.8",
14381436
latest,
14391437
],
1440-
"aiohttp_jinja2": latest,
14411438
"yarl": "~=1.0",
14421439
},
14431440
),
14441441
],
14451442
),
1443+
Venv(
1444+
name="aiohttp_jinja2",
1445+
command="pytest {cmdargs} tests/contrib/aiohttp_jinja2",
1446+
pkgs={
1447+
"pytest-aiohttp": [latest],
1448+
},
1449+
venvs=[
1450+
Venv(
1451+
pys="3.6",
1452+
pkgs={
1453+
"aiohttp": [
1454+
"~=3.4",
1455+
"~=3.6",
1456+
latest,
1457+
],
1458+
"aiohttp_jinja2": [
1459+
"~=1.3.0",
1460+
"~=1.4.0",
1461+
latest,
1462+
],
1463+
},
1464+
),
1465+
Venv(
1466+
pys=select_pys(min_version="3.7"),
1467+
pkgs={
1468+
"pytest-asyncio": [latest],
1469+
"aiohttp": [
1470+
"~=3.4",
1471+
"~=3.6",
1472+
"~=3.8",
1473+
latest,
1474+
],
1475+
},
1476+
venvs=[
1477+
Venv(
1478+
pkgs={
1479+
"aiohttp_jinja2": [
1480+
"~=1.3.0",
1481+
"~=1.4.0",
1482+
latest,
1483+
],
1484+
# Jinja2 makes breaking changes in 3.0.
1485+
"jinja2": "<3.0",
1486+
# MarkupSafe makes breaking changes in 2.1.
1487+
"MarkupSafe": "<2.1",
1488+
}
1489+
),
1490+
Venv(
1491+
pkgs={
1492+
"aiohttp_jinja2": [
1493+
"~=1.5.0",
1494+
latest,
1495+
],
1496+
"jinja2": latest,
1497+
}
1498+
),
1499+
],
1500+
),
1501+
],
1502+
),
14461503
Venv(
14471504
name="jinja2",
14481505
venvs=[

tests/conftest.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import pytest
66

7+
import ddtrace
78
from tests.utils import DummyTracer
89
from tests.utils import TracerSpanContainer
910
from tests.utils import call_program
@@ -17,8 +18,16 @@ def pytest_configure(config):
1718

1819

1920
@pytest.fixture
20-
def tracer():
21-
return DummyTracer()
21+
def use_global_tracer():
22+
yield False
23+
24+
25+
@pytest.fixture
26+
def tracer(use_global_tracer):
27+
if use_global_tracer:
28+
return ddtrace.tracer
29+
else:
30+
return DummyTracer()
2231

2332

2433
@pytest.fixture

tests/contrib/aiohttp/app/web.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22
import os
33

44
from aiohttp import web
5-
import aiohttp_jinja2
6-
import jinja2
5+
6+
7+
try:
8+
import aiohttp_jinja2
9+
except ImportError:
10+
aiohttp_jinja2 = None
11+
else:
12+
import jinja2
713

814
from ddtrace.contrib.aiohttp.middlewares import CONFIG_KEY
915

@@ -77,20 +83,6 @@ async def coro_2(request):
7783
return "OK"
7884

7985

80-
async def template_handler(request):
81-
return aiohttp_jinja2.render_template("template.jinja2", request, {"text": "OK"})
82-
83-
84-
@aiohttp_jinja2.template("template.jinja2")
85-
async def template_decorator(request):
86-
return {"text": "OK"}
87-
88-
89-
@aiohttp_jinja2.template("error.jinja2")
90-
async def template_error(request):
91-
return {}
92-
93-
9486
async def delayed_handler(request):
9587
await asyncio.sleep(0.01)
9688
return web.Response(text="Done")
@@ -105,6 +97,20 @@ async def middleware_handler(request):
10597
return middleware_handler
10698

10799

100+
if aiohttp_jinja2:
101+
102+
async def template_handler(request):
103+
return aiohttp_jinja2.render_template("template.jinja2", request, {"text": "OK"})
104+
105+
@aiohttp_jinja2.template("template.jinja2")
106+
async def template_decorator(request):
107+
return {"text": "OK"}
108+
109+
@aiohttp_jinja2.template("error.jinja2")
110+
async def template_error(request):
111+
return {}
112+
113+
108114
def setup_app(loop=None):
109115
"""
110116
Use this method to create the app. It must receive
@@ -129,11 +135,12 @@ def setup_app(loop=None):
129135
app.router.add_get("/uncaught_server_error", uncaught_server_error)
130136
app.router.add_get("/caught_server_error", caught_server_error)
131137
app.router.add_static("/statics", STATIC_DIR)
132-
# configure templates
133-
set_memory_loader(app)
134-
app.router.add_get("/template/", template_handler)
135-
app.router.add_get("/template_decorator/", template_decorator)
136-
app.router.add_get("/template_error/", template_error)
138+
if aiohttp_jinja2:
139+
# configure templates
140+
set_memory_loader(app)
141+
app.router.add_get("/template/", template_handler)
142+
app.router.add_get("/template_decorator/", template_decorator)
143+
app.router.add_get("/template_error/", template_error)
137144
app.router.add_get("/response_headers/", response_headers)
138145

139146
return app

tests/contrib/aiohttp/conftest.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import aiohttp
2-
import aiohttp_jinja2
32
import pytest
43

54
from ddtrace.contrib.aiohttp.middlewares import trace_app
6-
from ddtrace.contrib.aiohttp_jinja2.patch import patch as patch_jinja2
75
from ddtrace.internal.utils import version
8-
from ddtrace.pin import Pin
96

107
from .app.web import setup_app
118

@@ -24,19 +21,15 @@ def app_tracer(tracer, loop):
2421

2522
@pytest.fixture
2623
def patched_app_tracer(app_tracer):
27-
patch_jinja2()
2824
app, tracer = app_tracer
29-
Pin.override(aiohttp_jinja2, tracer=tracer)
3025
return app, tracer
3126
# When Python 3.5 is dropped, rather do:
3227
# yield app, tracer
3328
# unpatch()
3429

3530
@pytest.fixture
3631
def untraced_app_tracer(tracer, loop):
37-
patch_jinja2()
3832
app = setup_app()
39-
Pin.override(aiohttp_jinja2, tracer=tracer)
4033
return app, tracer
4134
# When Python 3.5 is dropped, rather do:
4235
# yield app, tracer
@@ -53,19 +46,15 @@ async def app_tracer(tracer, loop):
5346

5447
@pytest.fixture
5548
async def patched_app_tracer(app_tracer):
56-
patch_jinja2()
5749
app, tracer = app_tracer
58-
Pin.override(aiohttp_jinja2, tracer=tracer)
5950
return app, tracer
6051
# When Python 3.5 is dropped, rather do:
6152
# yield app, tracer
6253
# unpatch()
6354

6455
@pytest.fixture
6556
async def untraced_app_tracer(tracer, loop):
66-
patch_jinja2()
6757
app = setup_app()
68-
Pin.override(aiohttp_jinja2, tracer=tracer)
6958
return app, tracer
7059
# When Python 3.5 is dropped, rather do:
7160
# yield app, tracer

tests/contrib/aiohttp/test_middleware.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ async def test_analytics_integration_enabled(app_tracer, aiohttp_client):
455455
client = await aiohttp_client(app)
456456
app["datadog_trace"]["analytics_enabled"] = True
457457
app["datadog_trace"]["analytics_sample_rate"] = 0.5
458-
request = await client.request("GET", "/template/")
458+
request = await client.request("GET", "/")
459459
await request.text()
460460

461461
# Assert root span sets the appropriate metric
@@ -467,7 +467,7 @@ async def test_analytics_integration_default(app_tracer, aiohttp_client):
467467
"""Check trace has analytics sample rate set"""
468468
app, tracer = app_tracer
469469
client = await aiohttp_client(app)
470-
request = await client.request("GET", "/template/")
470+
request = await client.request("GET", "/")
471471
await request.text()
472472

473473
# Assert root span does not have the appropriate metric
@@ -480,7 +480,7 @@ async def test_analytics_integration_disabled(app_tracer, aiohttp_client):
480480
app, tracer = app_tracer
481481
client = await aiohttp_client(app)
482482
app["datadog_trace"]["analytics_enabled"] = False
483-
request = await client.request("GET", "/template/")
483+
request = await client.request("GET", "/")
484484
await request.text()
485485

486486
# Assert root span does not have the appropriate metric

0 commit comments

Comments
 (0)