Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give up when there is no open segment and LOG_ERROR is configured #58

Merged
merged 4 commits into from
May 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ CHANGELOG
unreleased
==========
* feature: Added Sqlalchemy parameterized query capture. `PR34 <https://github.com/aws/aws-xray-sdk-python/pull/34>`_.
* bugfix: Added new `raise_if_not_subsegment` parameter for Aiohttp Client tracing `PR58 <https://github.com/aws/aws-xray-sdk-python/pull/58>`_.

1.0
===
Expand Down
30 changes: 23 additions & 7 deletions aws_xray_sdk/ext/aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,30 @@
async def begin_subsegment(session, trace_config_ctx, params):
name = trace_config_ctx.name if trace_config_ctx.name else strip_url(str(params.url))
subsegment = xray_recorder.begin_subsegment(name, REMOTE_NAMESPACE)
subsegment.put_http_meta(http.METHOD, params.method)
subsegment.put_http_meta(http.URL, params.url.human_repr())
inject_trace_header(params.headers, subsegment)

# No-op if subsegment is `None` due to `LOG_ERROR`.
if not subsegment:
trace_config_ctx.give_up = True
else:
trace_config_ctx.give_up = False
subsegment.put_http_meta(http.METHOD, params.method)
subsegment.put_http_meta(http.URL, params.url.human_repr())
inject_trace_header(params.headers, subsegment)


async def end_subsegment(session, trace_config_ctx, params):
if trace_config_ctx.give_up:
return

subsegment = xray_recorder.current_subsegment()
subsegment.put_http_meta(http.STATUS, params.response.status)
xray_recorder.end_subsegment()


async def end_subsegment_with_exception(session, trace_config_ctx, params):
if trace_config_ctx.give_up:
return

subsegment = xray_recorder.current_subsegment()
subsegment.add_exception(
params.exception,
Expand All @@ -54,10 +66,14 @@ def aws_xray_trace_config(name=None):
be used as identifier.
:returns: TraceConfig.
"""
trace_config = aiohttp.TraceConfig(
trace_config_ctx_factory=lambda trace_request_ctx: SimpleNamespace(name=name,
trace_request_ctx=trace_request_ctx)
)

def _trace_config_ctx_factory(trace_request_ctx):
return SimpleNamespace(
name=name,
trace_request_ctx=trace_request_ctx
)

trace_config = aiohttp.TraceConfig(trace_config_ctx_factory=_trace_config_ctx_factory)
trace_config.on_request_start.append(begin_subsegment)
trace_config.on_request_end.append(end_subsegment)
trace_config.on_request_exception.append(end_subsegment_with_exception)
Expand Down
25 changes: 25 additions & 0 deletions tests/ext/aiohttp/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core.async_context import AsyncContext
from aws_xray_sdk.core.exceptions.exceptions import SegmentNotFoundException
from aws_xray_sdk.ext.util import strip_url
from aws_xray_sdk.ext.aiohttp.client import aws_xray_trace_config
from aws_xray_sdk.ext.aiohttp.client import REMOTE_NAMESPACE, LOCAL_NAMESPACE
Expand Down Expand Up @@ -130,3 +131,27 @@ async def test_invalid_url(loop, recorder):

exception = subsegment.cause['exceptions'][0]
assert exception.type == 'ClientConnectorError'


async def test_no_segment_raise(loop, recorder):
xray_recorder.configure(context_missing='RUNTIME_ERROR')
trace_config = aws_xray_trace_config()
status_code = 200
url = 'http://{}/status/{}?foo=bar'.format(BASE_URL, status_code)
with pytest.raises(SegmentNotFoundException):
async with ClientSession(loop=loop, trace_configs=[trace_config]) as session:
async with session.get(url):
pass


async def test_no_segment_not_raise(loop, recorder):
xray_recorder.configure(context_missing='LOG_ERROR')
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) as resp:
status_received = resp.status

# Just check that the request was done correctly
assert status_received == status_code