Skip to content

Commit 90ba860

Browse files
authored
[boto] Default to None if no region (#526)
* [boto] fallback to None if no region * [boto] set aws.region tag only if defined * [boto] use constants for meta keys
1 parent 0bae457 commit 90ba860

File tree

2 files changed

+71
-36
lines changed

2 files changed

+71
-36
lines changed

ddtrace/contrib/boto/patch.py

Lines changed: 66 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@
1111
_Boto_client = boto.connection.AWSQueryConnection
1212

1313
SPAN_TYPE = "boto"
14-
AWS_QUERY_ARGS_NAME = ('operation_name', 'params', 'path', 'verb')
15-
AWS_AUTH_ARGS_NAME = ('method', 'path', 'headers', 'data', 'host', 'auth_path', 'sender')
16-
AWS_QUERY_TRACED_ARGS = ['operation_name', 'params', 'path']
17-
AWS_AUTH_TRACED_ARGS = ['path', 'data', 'host']
14+
AWS_QUERY_ARGS_NAME = ("operation_name", "params", "path", "verb")
15+
AWS_AUTH_ARGS_NAME = (
16+
"method",
17+
"path",
18+
"headers",
19+
"data",
20+
"host",
21+
"auth_path",
22+
"sender",
23+
)
24+
AWS_QUERY_TRACED_ARGS = ["operation_name", "params", "path"]
25+
AWS_AUTH_TRACED_ARGS = ["path", "data", "host"]
1826

1927

2028
def patch():
@@ -23,21 +31,29 @@ def patch():
2331
different services for connection. For exemple EC2 uses AWSQueryConnection and
2432
S3 uses AWSAuthConnection
2533
"""
26-
if getattr(boto.connection, '_datadog_patch', False):
34+
if getattr(boto.connection, "_datadog_patch", False):
2735
return
28-
setattr(boto.connection, '_datadog_patch', True)
29-
30-
wrapt.wrap_function_wrapper('boto.connection', 'AWSQueryConnection.make_request', patched_query_request)
31-
wrapt.wrap_function_wrapper('boto.connection', 'AWSAuthConnection.make_request', patched_auth_request)
32-
Pin(service="aws", app="aws", app_type="web").onto(boto.connection.AWSQueryConnection)
33-
Pin(service="aws", app="aws", app_type="web").onto(boto.connection.AWSAuthConnection)
36+
setattr(boto.connection, "_datadog_patch", True)
37+
38+
wrapt.wrap_function_wrapper(
39+
"boto.connection", "AWSQueryConnection.make_request", patched_query_request
40+
)
41+
wrapt.wrap_function_wrapper(
42+
"boto.connection", "AWSAuthConnection.make_request", patched_auth_request
43+
)
44+
Pin(service="aws", app="aws", app_type="web").onto(
45+
boto.connection.AWSQueryConnection
46+
)
47+
Pin(service="aws", app="aws", app_type="web").onto(
48+
boto.connection.AWSAuthConnection
49+
)
3450

3551

3652
def unpatch():
37-
if getattr(boto.connection, '_datadog_patch', False):
38-
setattr(boto.connection, '_datadog_patch', False)
39-
unwrap(boto.connection.AWSQueryConnection, 'make_request')
40-
unwrap(boto.connection.AWSAuthConnection, 'make_request')
53+
if getattr(boto.connection, "_datadog_patch", False):
54+
setattr(boto.connection, "_datadog_patch", False)
55+
unwrap(boto.connection.AWSQueryConnection, "make_request")
56+
unwrap(boto.connection.AWSAuthConnection, "make_request")
4157

4258

4359
# ec2, sqs, kinesis
@@ -47,32 +63,38 @@ def patched_query_request(original_func, instance, args, kwargs):
4763
if not pin or not pin.enabled():
4864
return original_func(*args, **kwargs)
4965

50-
endpoint_name = getattr(instance, "host").split('.')[0]
66+
endpoint_name = getattr(instance, "host").split(".")[0]
5167

52-
with pin.tracer.trace('{}.command'.format(endpoint_name), service="{}.{}".format(pin.service, endpoint_name),
53-
span_type=SPAN_TYPE) as span:
68+
with pin.tracer.trace(
69+
"{}.command".format(endpoint_name),
70+
service="{}.{}".format(pin.service, endpoint_name),
71+
span_type=SPAN_TYPE,
72+
) as span:
5473

5574
operation_name = None
5675
if args:
5776
operation_name = args[0]
58-
span.resource = '%s.%s' % (endpoint_name, operation_name.lower())
77+
span.resource = "%s.%s" % (endpoint_name, operation_name.lower())
5978
else:
6079
span.resource = endpoint_name
6180

6281
# Adding the args in AWS_QUERY_TRACED_ARGS if exist to the span
6382
if not aws.is_blacklist(endpoint_name):
64-
for arg in aws.unpacking_args(args, AWS_QUERY_ARGS_NAME, AWS_QUERY_TRACED_ARGS):
83+
for arg in aws.unpacking_args(
84+
args, AWS_QUERY_ARGS_NAME, AWS_QUERY_TRACED_ARGS
85+
):
6586
span.set_tag(arg[0], arg[1])
6687

6788
# Obtaining region name
68-
region = getattr(instance, "region")
69-
region_name = get_region_name(region)
89+
region_name = _get_instance_region_name(instance)
7090

7191
meta = {
72-
'aws.agent': 'boto',
73-
'aws.operation': operation_name,
74-
'aws.region': region_name,
92+
aws.AGENT: "boto",
93+
aws.OPERATION: operation_name,
7594
}
95+
if region_name:
96+
meta[aws.REGION] = region_name
97+
7698
span.set_tags(meta)
7799

78100
# Original func returns a boto.connection.HTTPResponse object
@@ -97,31 +119,37 @@ def patched_auth_request(original_func, instance, args, kwargs):
97119
if not pin or not pin.enabled():
98120
return original_func(*args, **kwargs)
99121

100-
endpoint_name = getattr(instance, "host").split('.')[0]
122+
endpoint_name = getattr(instance, "host").split(".")[0]
101123

102-
with pin.tracer.trace('{}.command'.format(endpoint_name), service="{}.{}".format(pin.service, endpoint_name),
103-
span_type=SPAN_TYPE) as span:
124+
with pin.tracer.trace(
125+
"{}.command".format(endpoint_name),
126+
service="{}.{}".format(pin.service, endpoint_name),
127+
span_type=SPAN_TYPE,
128+
) as span:
104129

105130
# Adding the args in AWS_AUTH_TRACED_ARGS if exist to the span
106131
if not aws.is_blacklist(endpoint_name):
107-
for arg in aws.unpacking_args(args, AWS_AUTH_ARGS_NAME, AWS_AUTH_TRACED_ARGS):
132+
for arg in aws.unpacking_args(
133+
args, AWS_AUTH_ARGS_NAME, AWS_AUTH_TRACED_ARGS
134+
):
108135
span.set_tag(arg[0], arg[1])
109136

110137
if args:
111138
http_method = args[0]
112-
span.resource = '%s.%s' % (endpoint_name, http_method.lower())
139+
span.resource = "%s.%s" % (endpoint_name, http_method.lower())
113140
else:
114141
span.resource = endpoint_name
115142

116143
# Obtaining region name
117-
region = getattr(instance, "region", None)
118-
region_name = get_region_name(region)
144+
region_name = _get_instance_region_name(instance)
119145

120146
meta = {
121-
'aws.agent': 'boto',
122-
'aws.operation': operation_name,
123-
'aws.region': region_name,
147+
aws.AGENT: "boto",
148+
aws.OPERATION: operation_name,
124149
}
150+
if region_name:
151+
meta[aws.REGION] = region_name
152+
125153
span.set_tags(meta)
126154

127155
# Original func returns a boto.connection.HTTPResponse object
@@ -132,7 +160,9 @@ def patched_auth_request(original_func, instance, args, kwargs):
132160
return result
133161

134162

135-
def get_region_name(region):
163+
def _get_instance_region_name(instance):
164+
region = getattr(instance, "region", None)
165+
136166
if not region:
137167
return None
138168
if isinstance(region, str):

ddtrace/ext/aws.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ def unpacking_args(args, args_name, traced_args_list):
2525
response += [(args_name[index], arg)]
2626
index += 1
2727
return response
28+
29+
30+
REGION = "aws.region"
31+
AGENT = "aws.agent"
32+
OPERATION = "aws.operation"

0 commit comments

Comments
 (0)