opentelemetry-python-contrib/ddtrace/contrib/botocore/patch.py

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