Skip to content

Commit d5b72c6

Browse files
fix(aioredis): correctly parent commands with aioredis 1.3 (#3147) (#3151)
When using aioredis 1.3, the Redis command spans are not correctly treated as children of a parent span. To fix this, we capture and set the parent span when the span is created. fixes #3146 (cherry picked from commit a03be84) Co-authored-by: Jameel Al-Aziz <[email protected]>
1 parent d79da96 commit d5b72c6

File tree

5 files changed

+151
-1
lines changed

5 files changed

+151
-1
lines changed

ddtrace/contrib/aioredis/patch.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,13 @@ def traced_13_execute_command(func, instance, args, kwargs):
110110
# Don't activate the span since this operation is performed as a future which concludes sometime later on in
111111
# execution so subsequent operations in the stack are not necessarily semantically related
112112
# (we don't want this span to be the parent of all other spans created before the future is resolved)
113+
parent = pin.tracer.current_span()
113114
span = pin.tracer.start_span(
114-
redisx.CMD, service=trace_utils.ext_service(pin, config.aioredis), span_type=SpanTypes.REDIS, activate=False
115+
redisx.CMD,
116+
service=trace_utils.ext_service(pin, config.aioredis),
117+
span_type=SpanTypes.REDIS,
118+
activate=False,
119+
child_of=parent,
115120
)
116121

117122
span.set_tag(SPAN_MEASURED_KEY)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
Fix parenting of Redis command spans when using aioredis 1.3. Redis spans
5+
should now be correctly attributed as child of any active parent spans.

tests/contrib/aioredis/test_aioredis.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ def test_patching():
6464
assert not isinstance(aioredis.client.Pipeline.pipeline, ObjectProxy)
6565
else:
6666
assert isinstance(aioredis.Redis.execute, ObjectProxy)
67+
assert isinstance(aioredis.commands.Redis.execute, ObjectProxy)
6768
unpatch()
6869
assert not isinstance(aioredis.Redis.execute, ObjectProxy)
70+
assert not isinstance(aioredis.commands.Redis.execute, ObjectProxy)
6971

7072

7173
@pytest.mark.asyncio
@@ -240,3 +242,11 @@ async def test_two_traced_pipelines(redis_client):
240242
response_list1[1].decode() == "boo"
241243
) # response from hset is 'Integer reply: The number of fields that were added.'
242244
assert response_list2[1].decode() == "bar"
245+
246+
247+
@pytest.mark.asyncio
248+
@pytest.mark.snapshot(variants={"": aioredis_version >= (2, 0), "13": aioredis_version < (2, 0)})
249+
async def test_parenting(redis_client):
250+
with tracer.trace("web-request", service="test"):
251+
await redis_client.set("blah", "boo")
252+
await redis_client.get("blah")
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
[[
2+
{
3+
"name": "web-request",
4+
"service": "test",
5+
"resource": "web-request",
6+
"trace_id": 0,
7+
"span_id": 1,
8+
"parent_id": 0,
9+
"meta": {
10+
"runtime-id": "c75fe8a124e046a88374ca4e690d96f7"
11+
},
12+
"metrics": {
13+
"_dd.agent_psr": 1.0,
14+
"_dd.top_level": 1,
15+
"_dd.tracer_kr": 1.0,
16+
"_sampling_priority_v1": 1,
17+
"system.pid": 2807
18+
},
19+
"duration": 4925125,
20+
"start": 1642687869451527501
21+
},
22+
{
23+
"name": "redis.command",
24+
"service": "redis",
25+
"resource": "SET blah boo",
26+
"trace_id": 0,
27+
"span_id": 2,
28+
"parent_id": 1,
29+
"type": "redis",
30+
"meta": {
31+
"out.host": "127.0.0.1",
32+
"redis.raw_command": "SET blah boo"
33+
},
34+
"metrics": {
35+
"_dd.measured": 1,
36+
"_dd.top_level": 1,
37+
"out.port": 6379,
38+
"out.redis_db": 0,
39+
"redis.args_length": 3
40+
},
41+
"duration": 1989125,
42+
"start": 1642687869452441335
43+
},
44+
{
45+
"name": "redis.command",
46+
"service": "redis",
47+
"resource": "GET blah",
48+
"trace_id": 0,
49+
"span_id": 3,
50+
"parent_id": 1,
51+
"type": "redis",
52+
"meta": {
53+
"out.host": "127.0.0.1",
54+
"redis.raw_command": "GET blah"
55+
},
56+
"metrics": {
57+
"_dd.measured": 1,
58+
"_dd.top_level": 1,
59+
"out.port": 6379,
60+
"out.redis_db": 0,
61+
"redis.args_length": 2
62+
},
63+
"duration": 1576875,
64+
"start": 1642687869454763335
65+
}]]
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
[[
2+
{
3+
"name": "web-request",
4+
"service": "test",
5+
"resource": "web-request",
6+
"trace_id": 0,
7+
"span_id": 1,
8+
"parent_id": 0,
9+
"meta": {
10+
"runtime-id": "f48fe46e55d54ff38b2bd90772d8001e"
11+
},
12+
"metrics": {
13+
"_dd.agent_psr": 1.0,
14+
"_dd.top_level": 1,
15+
"_dd.tracer_kr": 1.0,
16+
"_sampling_priority_v1": 1,
17+
"system.pid": 2802
18+
},
19+
"duration": 2725083,
20+
"start": 1642687829923888303
21+
},
22+
{
23+
"name": "redis.command",
24+
"service": "redis",
25+
"resource": "SET blah boo",
26+
"trace_id": 0,
27+
"span_id": 2,
28+
"parent_id": 1,
29+
"type": "redis",
30+
"meta": {
31+
"out.host": "127.0.0.1",
32+
"redis.raw_command": "SET blah boo"
33+
},
34+
"metrics": {
35+
"_dd.measured": 1,
36+
"_dd.top_level": 1,
37+
"out.port": 6379,
38+
"out.redis_db": 0,
39+
"redis.args_length": 3
40+
},
41+
"duration": 1074709,
42+
"start": 1642687829924429969
43+
},
44+
{
45+
"name": "redis.command",
46+
"service": "redis",
47+
"resource": "GET blah",
48+
"trace_id": 0,
49+
"span_id": 3,
50+
"parent_id": 1,
51+
"type": "redis",
52+
"meta": {
53+
"out.host": "127.0.0.1",
54+
"redis.raw_command": "GET blah"
55+
},
56+
"metrics": {
57+
"_dd.measured": 1,
58+
"_dd.top_level": 1,
59+
"out.port": 6379,
60+
"out.redis_db": 0,
61+
"redis.args_length": 2
62+
},
63+
"duration": 809833,
64+
"start": 1642687829925730428
65+
}]]

0 commit comments

Comments
 (0)