82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
"""
|
|
Trace queries to aws api done via botocore client
|
|
"""
|
|
# 3p
|
|
from ddtrace.vendor import wrapt
|
|
from ddtrace import config
|
|
import botocore.client
|
|
|
|
# project
|
|
from ...constants import ANALYTICS_SAMPLE_RATE_KEY
|
|
from ...pin import Pin
|
|
from ...ext import SpanTypes, http, aws
|
|
from ...utils.formats import deep_getattr
|
|
from ...utils.wrappers import unwrap
|
|
|
|
|
|
# Original botocore client class
|
|
_Botocore_client = botocore.client.BaseClient
|
|
|
|
ARGS_NAME = ('action', 'params', 'path', 'verb')
|
|
TRACED_ARGS = ['params', 'path', 'verb']
|
|
|
|
|
|
def patch():
|
|
if getattr(botocore.client, '_datadog_patch', False):
|
|
return
|
|
setattr(botocore.client, '_datadog_patch', True)
|
|
|
|
wrapt.wrap_function_wrapper('botocore.client', 'BaseClient._make_api_call', patched_api_call)
|
|
Pin(service='aws', app='aws').onto(botocore.client.BaseClient)
|
|
|
|
|
|
def unpatch():
|
|
if getattr(botocore.client, '_datadog_patch', False):
|
|
setattr(botocore.client, '_datadog_patch', False)
|
|
unwrap(botocore.client.BaseClient, '_make_api_call')
|
|
|
|
|
|
def patched_api_call(original_func, instance, args, kwargs):
|
|
|
|
pin = Pin.get_from(instance)
|
|
if not pin or not pin.enabled():
|
|
return original_func(*args, **kwargs)
|
|
|
|
endpoint_name = deep_getattr(instance, '_endpoint._endpoint_prefix')
|
|
|
|
with pin.tracer.trace('{}.command'.format(endpoint_name),
|
|
service='{}.{}'.format(pin.service, endpoint_name),
|
|
span_type=SpanTypes.HTTP) as span:
|
|
|
|
operation = None
|
|
if args:
|
|
operation = args[0]
|
|
span.resource = '%s.%s' % (endpoint_name, operation.lower())
|
|
|
|
else:
|
|
span.resource = endpoint_name
|
|
|
|
aws.add_span_arg_tags(span, endpoint_name, args, ARGS_NAME, TRACED_ARGS)
|
|
|
|
region_name = deep_getattr(instance, 'meta.region_name')
|
|
|
|
meta = {
|
|
'aws.agent': 'botocore',
|
|
'aws.operation': operation,
|
|
'aws.region': region_name,
|
|
}
|
|
span.set_tags(meta)
|
|
|
|
result = original_func(*args, **kwargs)
|
|
|
|
span.set_tag(http.STATUS_CODE, result['ResponseMetadata']['HTTPStatusCode'])
|
|
span.set_tag('retry_attempts', result['ResponseMetadata']['RetryAttempts'])
|
|
|
|
# set analytics sample rate
|
|
span.set_tag(
|
|
ANALYTICS_SAMPLE_RATE_KEY,
|
|
config.botocore.get_analytics_sample_rate()
|
|
)
|
|
|
|
return result
|