Skip to content

Commit a00b8b5

Browse files
committed
initial commit
1 parent 1a5fab2 commit a00b8b5

File tree

120 files changed

+6459
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+6459
-2
lines changed

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.DS_Store
2+
*.pyc
3+
.Python
4+
.cache
5+
6+
build
7+
bin
8+
include
9+
lib
10+
dist
11+
*.egg
12+
*.egg-info
13+
.tox
14+
.python-version
15+
16+
pip-selfcheck.json
17+
18+
.coverage*
19+
htmlcov

CHANGELOG.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=========
2+
CHANGELOG
3+
=========
4+
5+
0.93
6+
====
7+
* The X-Ray SDK for Python is now an open source project. You can follow the project and submit issues and pull requests on GitHub: https://github.com/aws/aws-xray-sdk-python
8+
9+
0.92.2
10+
======
11+
* bugfix: Fixed an issue that caused the X-Ray recorder to omit the origin when recording segments with a service plugin. This caused the service's type to not appear on the service map in the X-Ray console.
12+
13+
0.92.1
14+
======
15+
* bugfix: Fixed an issue that caused all calls to Amazon DynamoDB tables to be grouped under a single node in the service map. With this update, each table gets a separate node.
16+
17+
0.92
18+
====
19+
20+
* feature: Add Flask support
21+
* feature: Add dynamic naming on segment name
22+
23+
0.91.1
24+
======
25+
26+
* bugfix: The SDK has been released as a universal wheel

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include aws_xray_sdk/ext/botocore/*.json
2+
include aws_xray_sdk/core/sampling/*.json
3+
include README.md
4+
include LICENSE

README.md

Lines changed: 154 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,154 @@
1-
# aws-xray-sdk-python
2-
AWS X-Ray SDK for the Python programming language
1+
# AWS X-Ray SDK for Python <sup><sup><sup>(beta)</sup></sup></sup>
2+
3+
![Screenshot of the AWS X-Ray console](/images/example_servicemap.png?raw=true)
4+
5+
## Installing
6+
7+
The AWS X-Ray SDK for Python is compatible with Python 2.7, 3.4, 3.5, and 3.6.
8+
9+
Install the SDK using the following command (the SDK's non-testing dependencies will be installed).
10+
11+
```
12+
pip install aws-xray-sdk
13+
```
14+
15+
To install the SDK's testing dependencies, use the following command.
16+
17+
```
18+
pip install tox
19+
```
20+
21+
## Getting Help
22+
23+
Use the following community resources for getting help with the SDK. We use the GitHub
24+
issues for tracking bugs and feature requests.
25+
26+
* Ask a question in the [AWS X-Ray Forum](https://forums.aws.amazon.com/forum.jspa?forumID=241&start=0).
27+
* Open a support ticket with [AWS Support](http://docs.aws.amazon.com/awssupport/latest/user/getting-started.html).
28+
* If you think you may have found a bug, open an [issue](https://github.com/aws/aws-xray-sdk-python/issues/new).
29+
30+
## Opening Issues
31+
32+
If you encounter a bug with the AWS X-Ray SDK for Python, we want to hear about
33+
it. Before opening a new issue, search the [existing issues](https://github.com/aws/aws-xray-sdk-python/issues)
34+
to see if others are also experiencing the issue. Include the version of the AWS X-Ray
35+
SDK for Python, Python language, and botocore/boto3 if applicable. In addition,
36+
include the repro case when appropriate.
37+
38+
The GitHub issues are intended for bug reports and feature requests. For help and
39+
questions about using the AWS SDK for Python, use the resources listed
40+
in the [Getting Help](https://github.com/aws/aws-xray-sdk-python#getting-help) section. Keeping the list of open issues lean helps us respond in a timely manner.
41+
42+
## Documentation
43+
44+
The [developer guide](https://docs.aws.amazon.com/xray/latest/devguide) provides in-depth
45+
guidance about using the AWS X-Ray service.
46+
The [API Reference](http://docs.aws.amazon.com/xray-sdk-for-python/latest/reference/)
47+
provides guidance for using the SDK and module-level documentation.
48+
49+
## Quick Start
50+
51+
**Configuration**
52+
53+
```python
54+
from aws_xray_sdk.core import xray_recorder
55+
56+
xray_recorder.configure(
57+
sampling=False,
58+
context_missing='LOG_ERROR',
59+
plugins=('EC2Plugin', 'ECSPlugin', 'ElasticBeanstalkPlugin'),
60+
daemon_address='127.0.0.1:3000',
61+
dynamic_naming='*mysite.com*'
62+
)
63+
```
64+
65+
**Start a custom segment/subsegment**
66+
67+
```python
68+
from aws_xray_sdk.core import xray_recorder
69+
70+
# Start a segment
71+
segment = xray_recorder.begin_segment('segment_name')
72+
# Start a subsegment
73+
subsegment = xray_recorder.begin_subsegment('subsegment_name')
74+
75+
# Add metadata or annotation here if necessary
76+
segment.put_metadata('key', dict, 'namespace')
77+
subsegment.put_annotation('key', 'value')
78+
xray_recorder.end_subsegment()
79+
80+
# Close the segment
81+
xray_recorder.end_segment()
82+
```
83+
84+
**Capture**
85+
86+
```python
87+
from aws_xray_sdk.core import xray_recorder
88+
89+
@xray_recorder.capture('subsegment_name')
90+
def myfunc():
91+
# Do something here
92+
93+
myfunc()
94+
```
95+
96+
**Trace AWS Lambda functions**
97+
98+
```python
99+
from aws_xray_sdk.core import xray_recorder
100+
101+
def lambda_handler(event, context):
102+
# ... some code
103+
104+
subsegment = xray_recorder.begin_subsegment('subsegment_name')
105+
# Code to record
106+
# Add metadata or annotation here, if necessary
107+
subsegment.put_metadata('key', dict, 'namespace')
108+
subsegment.put_annotation('key', 'value')
109+
110+
xray_recorder.end_subsegment()
111+
112+
# ... some other code
113+
```
114+
115+
**Patch third-party libraries**
116+
117+
```python
118+
from aws_xray_sdk.core import patch
119+
120+
libs_to_patch = ('boto3', 'mysql', 'requests')
121+
patch(libs_to_patch)
122+
```
123+
124+
**Add Django middleware**
125+
126+
In django settings.py, use the following.
127+
128+
```python
129+
INSTALLED_APPS = [
130+
# ... other apps
131+
'aws_xray_sdk.ext.django',
132+
]
133+
134+
MIDDLEWARE = [
135+
'aws_xray_sdk.ext.django.middleware.XRayMiddleware',
136+
# ... other middlewares
137+
]
138+
```
139+
140+
**Add Flask middleware**
141+
142+
```python
143+
from aws_xray_sdk.core import xray_recorder
144+
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
145+
146+
app = Flask(__name__)
147+
148+
xray_recorder.configure(service='fallback_name', dynamic_naming='*mysite.com*')
149+
XRayMiddleware(app, xray_recorder)
150+
```
151+
152+
## License
153+
154+
The AWS X-Ray SDK for Python is licensed under the Apache 2.0 License. See LICENSE and NOTICE.txt for more information.

__init__.py

Whitespace-only changes.

aws_xray_sdk/__init__.py

Whitespace-only changes.

aws_xray_sdk/core/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from .recorder import AWSXRayRecorder
2+
from .patcher import patch_all, patch
3+
4+
5+
xray_recorder = AWSXRayRecorder()
6+
7+
__all__ = [
8+
'patch',
9+
'patch_all',
10+
'xray_recorder',
11+
'AWSXRayRecorder',
12+
]

aws_xray_sdk/core/context.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import threading
2+
import logging
3+
import os
4+
5+
from .exceptions.exceptions import SegmentNotFoundException
6+
7+
log = logging.getLogger(__name__)
8+
9+
MISSING_SEGMENT_MSG = 'cannot find the current segment/subsegment, please make sure you have a segment open'
10+
SUPPORTED_CONTEXT_MISSING = ('RUNTIME_ERROR', 'LOG_ERROR')
11+
CXT_MISSING_STRATEGY_KEY = 'AWS_XRAY_CONTEXT_MISSING'
12+
13+
14+
class Context(object):
15+
"""
16+
The context storage class to store trace entities(segments/subsegments).
17+
The default implementation uses threadlocal to store these entities.
18+
It also provides interfaces to manually inject trace entities which will
19+
replace the current stored entities and to clean up the storage.
20+
21+
For any data access or data mutation, if there is no active segment present
22+
if will use user-defined behavior to handle such case. By default it throws
23+
an runtime error.
24+
25+
This data structure is thread-safe.
26+
"""
27+
def __init__(self, context_missing='RUNTIME_ERROR'):
28+
29+
self._local = threading.local()
30+
strategy = os.getenv(CXT_MISSING_STRATEGY_KEY, context_missing)
31+
self._context_missing = strategy
32+
33+
def put_segment(self, segment):
34+
"""
35+
Store the segment created by ``xray_recorder`` to the context.
36+
It overrides the current segment if there is already one.
37+
"""
38+
setattr(self._local, 'entities', [segment])
39+
40+
def end_segment(self, end_time=None):
41+
"""
42+
End the current active segment.
43+
44+
:param int end_time: epoch in seconds. If not specified the current
45+
system time will be used.
46+
"""
47+
entity = self.get_trace_entity()
48+
if not entity:
49+
log.warning("No segment to end")
50+
return
51+
if self._is_subsegment(entity):
52+
entity.parent_segment.close(end_time)
53+
else:
54+
entity.close(end_time)
55+
56+
def put_subsegment(self, subsegment):
57+
"""
58+
Store the subsegment created by ``xray_recorder`` to the context.
59+
If you put a new subsegment while there is already an open subsegment,
60+
the new subsegment becomes the child of the existing subsegment.
61+
"""
62+
entity = self.get_trace_entity()
63+
if not entity:
64+
log.warning("Active segment or subsegment not found. Discarded %s." % subsegment.name)
65+
return
66+
67+
entity.add_subsegment(subsegment)
68+
self._local.entities.append(subsegment)
69+
70+
def end_subsegment(self, end_time=None):
71+
"""
72+
End the current active segment. Return False if there is no
73+
subsegment to end.
74+
75+
:param int end_time: epoch in seconds. If not specified the current
76+
system time will be used.
77+
"""
78+
subsegment = self.get_trace_entity()
79+
if self._is_subsegment(subsegment):
80+
subsegment.close(end_time)
81+
self._local.entities.pop()
82+
return True
83+
else:
84+
log.warning("No subsegment to end.")
85+
return False
86+
87+
def get_trace_entity(self):
88+
"""
89+
Return the current trace entity(segment/subsegment). If there is none,
90+
it behaves based on pre-defined ``context_missing`` strategy.
91+
"""
92+
if not getattr(self._local, 'entities', None):
93+
return self.handle_context_missing()
94+
95+
return self._local.entities[-1]
96+
97+
def set_trace_entity(self, trace_entity):
98+
"""
99+
Store the input trace_entity to local context. It will overwrite all
100+
existing ones if there is any.
101+
"""
102+
setattr(self._local, 'entities', [trace_entity])
103+
104+
def clear_trace_entities(self):
105+
"""
106+
clear all trace_entities stored in the local context.
107+
In case of using threadlocal to store trace entites, it will
108+
clean up all trace entities created by the current thread.
109+
"""
110+
self._local.__dict__.clear()
111+
112+
def handle_context_missing(self):
113+
"""
114+
Called whenever there is no trace entity to access or mutate.
115+
"""
116+
if self.context_missing == 'RUNTIME_ERROR':
117+
log.error(MISSING_SEGMENT_MSG)
118+
raise SegmentNotFoundException(MISSING_SEGMENT_MSG)
119+
else:
120+
log.error(MISSING_SEGMENT_MSG)
121+
122+
def _is_subsegment(self, entity):
123+
124+
return hasattr(entity, 'type') and entity.type == 'subsegment'
125+
126+
@property
127+
def context_missing(self):
128+
return self._context_missing
129+
130+
@context_missing.setter
131+
def context_missing(self, value):
132+
if value not in SUPPORTED_CONTEXT_MISSING:
133+
log.warning('specified context_missing not supported, using default.')
134+
return
135+
136+
self._context_missing = value

aws_xray_sdk/core/emitters/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)