forked from aws/aws-xray-sdk-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.py
80 lines (62 loc) · 2.54 KB
/
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""
AioHttp Client tracing, only compatible with Aiohttp 3.X versions
"""
import aiohttp
from types import SimpleNamespace
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core.models import http
from aws_xray_sdk.core.utils import stacktrace
from aws_xray_sdk.ext.util import inject_trace_header, strip_url
# All aiohttp calls will entail outgoing HTTP requests, only in some ad-hoc
# exceptions the namespace will be flip back to local.
REMOTE_NAMESPACE = 'remote'
LOCAL_NAMESPACE = 'local'
LOCAL_EXCEPTIONS = (
aiohttp.client_exceptions.ClientConnectionError,
# DNS issues
OSError
)
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)
# 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,
stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back)
)
if isinstance(params.exception, LOCAL_EXCEPTIONS):
subsegment.namespace = LOCAL_NAMESPACE
xray_recorder.end_subsegment()
def aws_xray_trace_config(name=None):
"""
:param name: name used to identify the subsegment, with None internally the URL will
be used as identifier.
:returns: TraceConfig.
"""
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)
return trace_config