Skip to content

Commit 9a138fb

Browse files
github-actions[bot]bouwkastjoeyzhao2018
authored
fix(configurations): correctly parse payload_tagging_services [backport 2.21] (#12440)
Backport 6e58426 from #12180 to 2.21. Previously this: ```python "payload_tagging_services": set( os.getenv("DD_TRACE_CLOUD_PAYLOAD_TAGGING_SERVICES", default={"s3", "sns", "sqs", "kinesis", "eventbridge"}) ), ``` would require users to do `config.botocore["payload_tagging_services"].add("SERVICE_HERE")` as `os.getenv` just returns `string`. If someone were to do: ```powershell $env:DD_TRACE_CLOUD_PAYLOAD_TAGGING_SERVICES = "foo,bar" ``` it would be converted into the `set` of `{'o', 'b', 'r', 'f', ',', 'a'}` This correctly parses it as a set of `{"foo", "bar"}` while also stripping any potential whitespace. ## 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: Steven Bouwkamp <[email protected]> Co-authored-by: Joey Zhao <[email protected]>
1 parent 749133b commit 9a138fb

File tree

4 files changed

+334
-1
lines changed

4 files changed

+334
-1
lines changed

ddtrace/contrib/internal/botocore/patch.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ def _load_dynamodb_primary_key_names_for_tables() -> Dict[str, Set[str]]:
113113
os.getenv("DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_TAGS", 758)
114114
), # RFC defined default limit - spans are limited past 1000
115115
"payload_tagging_services": set(
116-
os.getenv("DD_TRACE_CLOUD_PAYLOAD_TAGGING_SERVICES", default={"s3", "sns", "sqs", "kinesis", "eventbridge"})
116+
service.strip()
117+
for service in os.getenv("DD_TRACE_CLOUD_PAYLOAD_TAGGING_SERVICES", "s3,sns,sqs,kinesis,eventbridge").split(
118+
","
119+
)
117120
),
118121
},
119122
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fixes:
2+
- |
3+
configurations: This fix resolves an issue where DD_TRACE_CLOUD_PAYLOAD_TAGGING_SERVICES env variable was not parsed correctly
4+

tests/contrib/botocore/test.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"meta.aws.response.body.HTTPHeaders.content-length",
6565
"meta.aws.response.body.HTTPHeaders.x-amzn-requestid",
6666
"meta.error.stack",
67+
"meta.aws.response.body.HTTPHeaders.x-amz-crc32",
6768
]
6869

6970

@@ -3975,6 +3976,56 @@ def test_aws_payload_tagging_s3_invalid_config(self):
39753976
with pytest.raises(Exception):
39763977
s3.list_objects(bucket="mybucket")
39773978

3979+
@pytest.mark.snapshot(ignores=snapshot_ignores)
3980+
@pytest.mark.skipif(
3981+
PYTHON_VERSION_INFO < (3, 8),
3982+
reason="Skipping for older py versions whose latest supported moto versions don't have the right dynamodb api",
3983+
)
3984+
@mock_dynamodb
3985+
def test_dynamodb_payload_tagging(self):
3986+
with self.override_config(
3987+
"botocore",
3988+
dict(payload_tagging_request="all", payload_tagging_response="all", payload_tagging_services="s3,dynamodb"),
3989+
):
3990+
ddb = self.session.create_client("dynamodb", region_name="us-west-2")
3991+
pin = Pin(service=self.TEST_SERVICE, tracer=self.tracer)
3992+
pin.onto(ddb)
3993+
3994+
with self.override_config("botocore", dict(instrument_internals=True)):
3995+
ddb.create_table(
3996+
TableName="foobar",
3997+
AttributeDefinitions=[{"AttributeName": "myattr", "AttributeType": "S"}],
3998+
KeySchema=[{"AttributeName": "myattr", "KeyType": "HASH"}],
3999+
BillingMode="PAY_PER_REQUEST",
4000+
)
4001+
ddb.put_item(TableName="foobar", Item={"myattr": {"S": "baz"}})
4002+
ddb.get_item(TableName="foobar", Key={"myattr": {"S": "baz"}})
4003+
4004+
spans = self.get_spans()
4005+
assert spans
4006+
span = spans[0]
4007+
assert len(spans) == 6
4008+
assert_is_measured(span)
4009+
assert span.get_tag("aws.operation") == "CreateTable"
4010+
assert span.get_tag("component") == "botocore"
4011+
assert span.get_tag("span.kind"), "client"
4012+
assert_span_http_status_code(span, 200)
4013+
assert span.service == "test-botocore-tracing.dynamodb"
4014+
assert span.resource == "dynamodb.createtable"
4015+
4016+
span = spans[1]
4017+
assert span.name == "botocore.parsers.parse"
4018+
assert span.get_tag("component") == "botocore"
4019+
assert span.get_tag("span.kind"), "client"
4020+
assert span.service == "test-botocore-tracing.dynamodb"
4021+
assert span.resource == "botocore.parsers.parse"
4022+
4023+
span = spans[2]
4024+
assert span.get_tag("aws.operation") == "PutItem"
4025+
# Since the dynamodb_primary_key_names_for_tables isn't configured, we
4026+
# cannot create span pointers for this item.
4027+
assert not span._links
4028+
39784029
@pytest.mark.skip(reason="broken during period of skipping on main branch")
39794030
@pytest.mark.snapshot(ignores=snapshot_ignores)
39804031
@mock_s3
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
[[
2+
{
3+
"name": "dynamodb.command",
4+
"service": "test-botocore-tracing.dynamodb",
5+
"resource": "dynamodb.getitem",
6+
"trace_id": 0,
7+
"span_id": 1,
8+
"parent_id": 0,
9+
"type": "http",
10+
"error": 0,
11+
"meta": {
12+
"_dd.base_service": "tests.contrib.botocore",
13+
"_dd.p.dm": "-0",
14+
"_dd.p.tid": "67a6776f00000000",
15+
"aws.agent": "botocore",
16+
"aws.dynamodb.table_name": "foobar",
17+
"aws.operation": "GetItem",
18+
"aws.region": "us-west-2",
19+
"aws.request.body.Key.myattr.S": "baz",
20+
"aws.request.body.TableName": "foobar",
21+
"aws.requestid": "1pGBOmkOZ1BdOWIHeWnkX96CO0n93XaZSqtfcgRZJhe6hrREgPCs",
22+
"aws.response.body.HTTPHeaders.date": "Fri, 07 Feb 2025 21:13:20 GMT",
23+
"aws.response.body.HTTPHeaders.server": "amazon.com",
24+
"aws.response.body.HTTPHeaders.x-amz-crc32": "357125523",
25+
"aws.response.body.HTTPHeaders.x-amzn-requestid": "1pGBOmkOZ1BdOWIHeWnkX96CO0n93XaZSqtfcgRZJhe6hrREgPCs",
26+
"aws.response.body.HTTPStatusCode": "200",
27+
"aws.response.body.RequestId": "1pGBOmkOZ1BdOWIHeWnkX96CO0n93XaZSqtfcgRZJhe6hrREgPCs",
28+
"aws.response.body.RetryAttempts": "0",
29+
"aws_service": "dynamodb",
30+
"component": "botocore",
31+
"http.status_code": "200",
32+
"language": "python",
33+
"region": "us-west-2",
34+
"runtime-id": "ef4281e602a34aa3b78873db2aa0da91",
35+
"span.kind": "client",
36+
"tablename": "foobar"
37+
},
38+
"metrics": {
39+
"_dd.measured": 1,
40+
"_dd.top_level": 1,
41+
"_dd.tracer_kr": 1.0,
42+
"_sampling_priority_v1": 1,
43+
"process_id": 7842,
44+
"retry_attempts": 0
45+
},
46+
"duration": 898096696,
47+
"start": 1738962799557241364
48+
},
49+
{
50+
"name": "botocore.parsers.parse",
51+
"service": "test-botocore-tracing.dynamodb",
52+
"resource": "botocore.parsers.parse",
53+
"trace_id": 0,
54+
"span_id": 2,
55+
"parent_id": 1,
56+
"type": "",
57+
"error": 0,
58+
"meta": {
59+
"_dd.base_service": "tests.contrib.botocore",
60+
"component": "botocore",
61+
"span.kind": "client"
62+
},
63+
"duration": 328440,
64+
"start": 1738962800007520310
65+
}],
66+
[
67+
{
68+
"name": "dynamodb.command",
69+
"service": "test-botocore-tracing.dynamodb",
70+
"resource": "dynamodb.createtable",
71+
"trace_id": 1,
72+
"span_id": 1,
73+
"parent_id": 0,
74+
"type": "http",
75+
"error": 0,
76+
"meta": {
77+
"_dd.base_service": "tests.contrib.botocore",
78+
"_dd.p.dm": "-0",
79+
"_dd.p.tid": "67a6776d00000000",
80+
"aws.agent": "botocore",
81+
"aws.dynamodb.table_name": "foobar",
82+
"aws.operation": "CreateTable",
83+
"aws.region": "us-west-2",
84+
"aws.request.body.AttributeDefinitions.0.AttributeName": "myattr",
85+
"aws.request.body.AttributeDefinitions.0.AttributeType": "S",
86+
"aws.request.body.BillingMode": "PAY_PER_REQUEST",
87+
"aws.request.body.KeySchema.0.AttributeName": "myattr",
88+
"aws.request.body.KeySchema.0.KeyType": "HASH",
89+
"aws.request.body.TableName": "foobar",
90+
"aws.requestid": "s5qfbhhfkr4Go9yZWDL5eSDNflqO9AY7R1PtdbeHgZSnABZRXWwc",
91+
"aws.response.body.HTTPHeaders.date": "Fri, 07 Feb 2025 21:13:17 GMT",
92+
"aws.response.body.HTTPHeaders.server": "amazon.com",
93+
"aws.response.body.HTTPHeaders.x-amz-crc32": "725802381",
94+
"aws.response.body.HTTPHeaders.x-amzn-requestid": "s5qfbhhfkr4Go9yZWDL5eSDNflqO9AY7R1PtdbeHgZSnABZRXWwc",
95+
"aws.response.body.HTTPStatusCode": "200",
96+
"aws.response.body.RequestId": "s5qfbhhfkr4Go9yZWDL5eSDNflqO9AY7R1PtdbeHgZSnABZRXWwc",
97+
"aws.response.body.RetryAttempts": "0",
98+
"aws_service": "dynamodb",
99+
"component": "botocore",
100+
"http.status_code": "200",
101+
"language": "python",
102+
"region": "us-west-2",
103+
"runtime-id": "ef4281e602a34aa3b78873db2aa0da91",
104+
"span.kind": "client",
105+
"tablename": "foobar"
106+
},
107+
"metrics": {
108+
"_dd.measured": 1,
109+
"_dd.top_level": 1,
110+
"_dd.tracer_kr": 1.0,
111+
"_sampling_priority_v1": 1,
112+
"process_id": 7842,
113+
"retry_attempts": 0
114+
},
115+
"duration": 1169517214,
116+
"start": 1738962797488686721
117+
},
118+
{
119+
"name": "botocore.parsers.parse",
120+
"service": "test-botocore-tracing.dynamodb",
121+
"resource": "botocore.parsers.parse",
122+
"trace_id": 1,
123+
"span_id": 2,
124+
"parent_id": 1,
125+
"type": "",
126+
"error": 0,
127+
"meta": {
128+
"_dd.base_service": "tests.contrib.botocore",
129+
"component": "botocore",
130+
"span.kind": "client"
131+
},
132+
"duration": 680298,
133+
"start": 1738962798196385705
134+
}],
135+
[
136+
{
137+
"name": "dynamodb.command",
138+
"service": "test-botocore-tracing.dynamodb",
139+
"resource": "dynamodb.putitem",
140+
"trace_id": 2,
141+
"span_id": 1,
142+
"parent_id": 0,
143+
"type": "http",
144+
"error": 0,
145+
"meta": {
146+
"_dd.base_service": "tests.contrib.botocore",
147+
"_dd.p.dm": "-0",
148+
"_dd.p.tid": "67a6776e00000000",
149+
"aws.agent": "botocore",
150+
"aws.dynamodb.table_name": "foobar",
151+
"aws.operation": "PutItem",
152+
"aws.region": "us-west-2",
153+
"aws.request.body.Item.myattr.S": "baz",
154+
"aws.request.body.TableName": "foobar",
155+
"aws.requestid": "l8KoXDDLWxK9lyqrrMRmtbdenA29koyXlCZEOlqgXgh46RkAzTiV",
156+
"aws.response.body.HTTPHeaders.date": "Fri, 07 Feb 2025 21:13:19 GMT",
157+
"aws.response.body.HTTPHeaders.server": "amazon.com",
158+
"aws.response.body.HTTPHeaders.x-amz-crc32": "2745614147",
159+
"aws.response.body.HTTPHeaders.x-amzn-requestid": "l8KoXDDLWxK9lyqrrMRmtbdenA29koyXlCZEOlqgXgh46RkAzTiV",
160+
"aws.response.body.HTTPStatusCode": "200",
161+
"aws.response.body.RequestId": "l8KoXDDLWxK9lyqrrMRmtbdenA29koyXlCZEOlqgXgh46RkAzTiV",
162+
"aws.response.body.RetryAttempts": "0",
163+
"aws_service": "dynamodb",
164+
"component": "botocore",
165+
"http.status_code": "200",
166+
"language": "python",
167+
"region": "us-west-2",
168+
"runtime-id": "ef4281e602a34aa3b78873db2aa0da91",
169+
"span.kind": "client",
170+
"tablename": "foobar"
171+
},
172+
"metrics": {
173+
"_dd.measured": 1,
174+
"_dd.top_level": 1,
175+
"_dd.tracer_kr": 1.0,
176+
"_sampling_priority_v1": 1,
177+
"process_id": 7842,
178+
"retry_attempts": 0
179+
},
180+
"duration": 897531031,
181+
"start": 1738962798659199416
182+
},
183+
{
184+
"name": "botocore.parsers.parse",
185+
"service": "test-botocore-tracing.dynamodb",
186+
"resource": "botocore.parsers.parse",
187+
"trace_id": 2,
188+
"span_id": 2,
189+
"parent_id": 1,
190+
"type": "",
191+
"error": 0,
192+
"meta": {
193+
"_dd.base_service": "tests.contrib.botocore",
194+
"component": "botocore",
195+
"span.kind": "client"
196+
},
197+
"duration": 188248,
198+
"start": 1738962799115125322
199+
}],
200+
[
201+
{
202+
"name": "sqs.command",
203+
"service": "aws.sqs",
204+
"resource": "sqs.listqueues",
205+
"trace_id": 3,
206+
"span_id": 1,
207+
"parent_id": 0,
208+
"type": "http",
209+
"error": 0,
210+
"meta": {
211+
"_dd.base_service": "tests.contrib.botocore",
212+
"_dd.p.dm": "-0",
213+
"_dd.p.tid": "67a6776d00000000",
214+
"aws.agent": "botocore",
215+
"aws.operation": "ListQueues",
216+
"aws.region": "us-east-1",
217+
"aws.requestid": "8BQ748A97HZTB3DQNICVX52K4H4KRCK9BWKBM3QX1FE0F9DJ4481",
218+
"aws_service": "sqs",
219+
"component": "botocore",
220+
"http.status_code": "200",
221+
"language": "python",
222+
"region": "us-east-1",
223+
"runtime-id": "ef4281e602a34aa3b78873db2aa0da91",
224+
"span.kind": "client"
225+
},
226+
"metrics": {
227+
"_dd.measured": 1,
228+
"_dd.top_level": 1,
229+
"_dd.tracer_kr": 1.0,
230+
"_sampling_priority_v1": 1,
231+
"process_id": 7842,
232+
"retry_attempts": 0
233+
},
234+
"duration": 17043485,
235+
"start": 1738962797437241544
236+
}],
237+
[
238+
{
239+
"name": "sqs.command",
240+
"service": "aws.sqs",
241+
"resource": "sqs.createqueue",
242+
"trace_id": 4,
243+
"span_id": 1,
244+
"parent_id": 0,
245+
"type": "http",
246+
"error": 0,
247+
"meta": {
248+
"_dd.base_service": "tests.contrib.botocore",
249+
"_dd.p.dm": "-0",
250+
"_dd.p.tid": "67a6776d00000000",
251+
"aws.agent": "botocore",
252+
"aws.operation": "CreateQueue",
253+
"aws.region": "us-east-1",
254+
"aws.requestid": "P5XR375SOHFTGCNG78FP0M00O7J8TR5Y01KWQXDNSAC2MR17BVSN",
255+
"aws.sqs.queue_name": "Test",
256+
"aws_service": "sqs",
257+
"component": "botocore",
258+
"http.status_code": "200",
259+
"language": "python",
260+
"queuename": "Test",
261+
"region": "us-east-1",
262+
"runtime-id": "ef4281e602a34aa3b78873db2aa0da91",
263+
"span.kind": "client"
264+
},
265+
"metrics": {
266+
"_dd.measured": 1,
267+
"_dd.top_level": 1,
268+
"_dd.tracer_kr": 1.0,
269+
"_sampling_priority_v1": 1,
270+
"process_id": 7842,
271+
"retry_attempts": 0
272+
},
273+
"duration": 9204293,
274+
"start": 1738962797455089485
275+
}]]

0 commit comments

Comments
 (0)