def test_throttle(): status_code = 429 url = 'https://{}/status/{}'.format(BASE_URL, status_code) _do_req(url, 'HEAD') subsegment = xray_recorder.current_segment().subsegments[1] assert subsegment.name == get_hostname(url) assert subsegment.error assert subsegment.throttle http_meta = subsegment.http assert http_meta['request']['url'] == strip_url(url) assert http_meta['request']['method'].upper() == 'HEAD' assert http_meta['response']['status'] == status_code
def requests_processor(wrapped, instance, args, kwargs, return_value, exception, subsegment, stack): method = kwargs.get('method') or args[0] url = kwargs.get('url') or args[1] subsegment.put_http_meta(http.METHOD, method) subsegment.put_http_meta(http.URL, strip_url(url)) if return_value is not None: subsegment.put_http_meta(http.STATUS, return_value.status_code) elif exception: subsegment.add_exception(exception, stack)
def _xray_traced_http_getresponse(wrapped, instance, args, kwargs): if not PY2 and kwargs.get('buffering', False): # ignore py2 calls that fail as 'buffering` only exists in py2. return wrapped(*args, **kwargs) xray_data = getattr(instance, _XRAY_PROP) return xray_recorder.record_subsegment( wrapped, instance, args, kwargs, name=strip_url(xray_data.url), namespace='remote', meta_processor=http_response_processor, )
def test_invalid_url(): url = 'KLSDFJKLSDFJKLSDJF' try: requests.get(url) except Exception: # prevent uncatch exception from breaking test run pass subsegment = xray_recorder.current_segment().subsegments[0] assert subsegment.name == get_hostname(url) assert subsegment.fault http_meta = subsegment.http assert http_meta['request']['url'] == strip_url(url) exception = subsegment.cause['exceptions'][0] assert exception.type == 'MissingSchema'
async def test_ok(loop, recorder): xray_recorder.begin_segment('name') trace_config = aws_xray_trace_config() status_code = 200 url = 'http://{}/status/{}?foo=bar'.format(BASE_URL, status_code) async with ClientSession(loop=loop, trace_configs=[trace_config]) as session: async with session.get(url): pass subsegment = xray_recorder.current_segment().subsegments[0] assert subsegment.name == strip_url(url) assert subsegment.namespace == REMOTE_NAMESPACE http_meta = subsegment.http assert http_meta['request']['url'] == url assert http_meta['request']['method'] == 'GET' assert http_meta['response']['status'] == status_code
def wrapper(*args, **kw): from ..query import XRayQuery, XRaySession try: from ...flask_sqlalchemy.query import XRaySignallingSession has_sql_alchemy = True except ImportError: has_sql_alchemy = False class_name = str(cls.__module__) c = xray_recorder._context sql = None subsegment = None if class_name == "sqlalchemy.orm.session": for arg in args: if isinstance(arg, XRaySession): sql = parse_bind(arg.bind) if has_sql_alchemy and isinstance(arg, XRaySignallingSession): sql = parse_bind(arg.bind) if class_name == 'sqlalchemy.orm.query': for arg in args: if isinstance(arg, XRayQuery): try: sql = parse_bind(arg.session.bind) if xray_recorder.stream_sql: sql['sanitized_query'] = str(arg) except Exception: sql = None if sql is not None: if getattr(c._local, 'entities', None) is not None: # Strip URL of ? and following text sub_name = strip_url(sql['url']) subsegment = xray_recorder.begin_subsegment(sub_name, namespace='remote') else: subsegment = None try: res = func(*args, **kw) finally: if subsegment is not None: subsegment.set_sql(sql) subsegment.put_annotation("sqlalchemy", class_name + '.' + func.__name__) xray_recorder.end_subsegment() return res
def http_response_processor(wrapped, instance, args, kwargs, return_value, exception, subsegment, stack): xray_data = getattr(instance, _XRAY_PROP, None) if not xray_data: return subsegment.put_http_meta(http.METHOD, xray_data.method) subsegment.put_http_meta(http.URL, strip_url(xray_data.url)) if return_value: subsegment.put_http_meta(http.STATUS, return_value.status) # propagate to response object xray_data = _XRay_Data('READ', xray_data.host, xray_data.url) setattr(return_value, _XRAY_PROP, xray_data) if exception: subsegment.add_exception(exception, stack)
async def test_error(loop, recorder): xray_recorder.begin_segment('name') trace_config = aws_xray_trace_config() status_code = 400 url = 'http://{}/status/{}'.format(BASE_URL, status_code) async with ClientSession(loop=loop, trace_configs=[trace_config]) as session: async with session.post(url): pass subsegment = xray_recorder.current_segment().subsegments[0] assert subsegment.name == get_hostname(url) assert subsegment.error http_meta = subsegment.http assert http_meta['request']['url'] == strip_url(url) assert http_meta['request']['method'] == 'POST' assert http_meta['response']['status'] == status_code
def decompose_args(method, url, body, headers, encode_chunked=False): inject_trace_header(headers, xray_recorder.current_subsegment()) # we have to check against sock because urllib3's HTTPSConnection inherit's from http.client.HTTPConnection scheme = 'https' if isinstance(instance.sock, ssl.SSLSocket) else 'http' xray_url = '{}://{}{}'.format(scheme, instance.host, url) xray_data = _XRay_Data(method, instance.host, xray_url) setattr(instance, _XRAY_PROP, xray_data) # we add a segment here in case connect fails return xray_recorder.record_subsegment( wrapped, instance, args, kwargs, name=strip_url(xray_data.url), namespace='remote', meta_processor=http_send_request_processor)
def decompose_args(method, url, body, headers, encode_chunked=False): # skip httplib tracing for SDK built-in centralized sampling pollers if (('/GetSamplingRules' in args or '/SamplingTargets' in args) and type(instance).__name__ == 'botocore.awsrequest.AWSHTTPConnection'): return wrapped(*args, **kwargs) # Only injects headers when the subsegment for the outgoing # calls are opened successfully. subsegment = None try: subsegment = xray_recorder.current_subsegment() except SegmentNotFoundException: pass if subsegment: inject_trace_header(headers, subsegment) if issubclass(instance.__class__, urllib3.connection.HTTPSConnection): ssl_cxt = getattr(instance, 'ssl_context', None) elif issubclass(instance.__class__, httplib.HTTPSConnection): ssl_cxt = getattr(instance, '_context', None) else: # In this case, the patcher can't determine which module the connection instance is from. # We default to it to check ssl_context but may be None so that the default scheme would be # (and may falsely be) http. ssl_cxt = getattr(instance, 'ssl_context', None) scheme = 'https' if ssl_cxt and type( ssl_cxt).__name__ == 'SSLContext' else 'http' xray_url = '{}://{}{}'.format(scheme, instance.host, url) xray_data = _XRay_Data(method, instance.host, xray_url) setattr(instance, _XRAY_PROP, xray_data) # we add a segment here in case connect fails return xray_recorder.record_subsegment( wrapped, instance, args, kwargs, name=strip_url(xray_data.url), namespace='remote', meta_processor=http_send_request_processor)