forked from aws/aws-xray-sdk-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1a5fab2
commit a00b8b5
Showing
120 changed files
with
6,459 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
.DS_Store | ||
*.pyc | ||
.Python | ||
.cache | ||
|
||
build | ||
bin | ||
include | ||
lib | ||
dist | ||
*.egg | ||
*.egg-info | ||
.tox | ||
.python-version | ||
|
||
pip-selfcheck.json | ||
|
||
.coverage* | ||
htmlcov |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
========= | ||
CHANGELOG | ||
========= | ||
|
||
0.93 | ||
==== | ||
* 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 | ||
|
||
0.92.2 | ||
====== | ||
* 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. | ||
|
||
0.92.1 | ||
====== | ||
* 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. | ||
|
||
0.92 | ||
==== | ||
|
||
* feature: Add Flask support | ||
* feature: Add dynamic naming on segment name | ||
|
||
0.91.1 | ||
====== | ||
|
||
* bugfix: The SDK has been released as a universal wheel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
include aws_xray_sdk/ext/botocore/*.json | ||
include aws_xray_sdk/core/sampling/*.json | ||
include README.md | ||
include LICENSE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,154 @@ | ||
# aws-xray-sdk-python | ||
AWS X-Ray SDK for the Python programming language | ||
# AWS X-Ray SDK for Python <sup><sup><sup>(beta)</sup></sup></sup> | ||
|
||
 | ||
|
||
## Installing | ||
|
||
The AWS X-Ray SDK for Python is compatible with Python 2.7, 3.4, 3.5, and 3.6. | ||
|
||
Install the SDK using the following command (the SDK's non-testing dependencies will be installed). | ||
|
||
``` | ||
pip install aws-xray-sdk | ||
``` | ||
|
||
To install the SDK's testing dependencies, use the following command. | ||
|
||
``` | ||
pip install tox | ||
``` | ||
|
||
## Getting Help | ||
|
||
Use the following community resources for getting help with the SDK. We use the GitHub | ||
issues for tracking bugs and feature requests. | ||
|
||
* Ask a question in the [AWS X-Ray Forum](https://forums.aws.amazon.com/forum.jspa?forumID=241&start=0). | ||
* Open a support ticket with [AWS Support](http://docs.aws.amazon.com/awssupport/latest/user/getting-started.html). | ||
* If you think you may have found a bug, open an [issue](https://github.com/aws/aws-xray-sdk-python/issues/new). | ||
|
||
## Opening Issues | ||
|
||
If you encounter a bug with the AWS X-Ray SDK for Python, we want to hear about | ||
it. Before opening a new issue, search the [existing issues](https://github.com/aws/aws-xray-sdk-python/issues) | ||
to see if others are also experiencing the issue. Include the version of the AWS X-Ray | ||
SDK for Python, Python language, and botocore/boto3 if applicable. In addition, | ||
include the repro case when appropriate. | ||
|
||
The GitHub issues are intended for bug reports and feature requests. For help and | ||
questions about using the AWS SDK for Python, use the resources listed | ||
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. | ||
|
||
## Documentation | ||
|
||
The [developer guide](https://docs.aws.amazon.com/xray/latest/devguide) provides in-depth | ||
guidance about using the AWS X-Ray service. | ||
The [API Reference](http://docs.aws.amazon.com/xray-sdk-for-python/latest/reference/) | ||
provides guidance for using the SDK and module-level documentation. | ||
|
||
## Quick Start | ||
|
||
**Configuration** | ||
|
||
```python | ||
from aws_xray_sdk.core import xray_recorder | ||
|
||
xray_recorder.configure( | ||
sampling=False, | ||
context_missing='LOG_ERROR', | ||
plugins=('EC2Plugin', 'ECSPlugin', 'ElasticBeanstalkPlugin'), | ||
daemon_address='127.0.0.1:3000', | ||
dynamic_naming='*mysite.com*' | ||
) | ||
``` | ||
|
||
**Start a custom segment/subsegment** | ||
|
||
```python | ||
from aws_xray_sdk.core import xray_recorder | ||
|
||
# Start a segment | ||
segment = xray_recorder.begin_segment('segment_name') | ||
# Start a subsegment | ||
subsegment = xray_recorder.begin_subsegment('subsegment_name') | ||
|
||
# Add metadata or annotation here if necessary | ||
segment.put_metadata('key', dict, 'namespace') | ||
subsegment.put_annotation('key', 'value') | ||
xray_recorder.end_subsegment() | ||
|
||
# Close the segment | ||
xray_recorder.end_segment() | ||
``` | ||
|
||
**Capture** | ||
|
||
```python | ||
from aws_xray_sdk.core import xray_recorder | ||
|
||
@xray_recorder.capture('subsegment_name') | ||
def myfunc(): | ||
# Do something here | ||
|
||
myfunc() | ||
``` | ||
|
||
**Trace AWS Lambda functions** | ||
|
||
```python | ||
from aws_xray_sdk.core import xray_recorder | ||
|
||
def lambda_handler(event, context): | ||
# ... some code | ||
|
||
subsegment = xray_recorder.begin_subsegment('subsegment_name') | ||
# Code to record | ||
# Add metadata or annotation here, if necessary | ||
subsegment.put_metadata('key', dict, 'namespace') | ||
subsegment.put_annotation('key', 'value') | ||
|
||
xray_recorder.end_subsegment() | ||
|
||
# ... some other code | ||
``` | ||
|
||
**Patch third-party libraries** | ||
|
||
```python | ||
from aws_xray_sdk.core import patch | ||
|
||
libs_to_patch = ('boto3', 'mysql', 'requests') | ||
patch(libs_to_patch) | ||
``` | ||
|
||
**Add Django middleware** | ||
|
||
In django settings.py, use the following. | ||
|
||
```python | ||
INSTALLED_APPS = [ | ||
# ... other apps | ||
'aws_xray_sdk.ext.django', | ||
] | ||
|
||
MIDDLEWARE = [ | ||
'aws_xray_sdk.ext.django.middleware.XRayMiddleware', | ||
# ... other middlewares | ||
] | ||
``` | ||
|
||
**Add Flask middleware** | ||
|
||
```python | ||
from aws_xray_sdk.core import xray_recorder | ||
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware | ||
|
||
app = Flask(__name__) | ||
|
||
xray_recorder.configure(service='fallback_name', dynamic_naming='*mysite.com*') | ||
XRayMiddleware(app, xray_recorder) | ||
``` | ||
|
||
## License | ||
|
||
The AWS X-Ray SDK for Python is licensed under the Apache 2.0 License. See LICENSE and NOTICE.txt for more information. |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from .recorder import AWSXRayRecorder | ||
from .patcher import patch_all, patch | ||
|
||
|
||
xray_recorder = AWSXRayRecorder() | ||
|
||
__all__ = [ | ||
'patch', | ||
'patch_all', | ||
'xray_recorder', | ||
'AWSXRayRecorder', | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import threading | ||
import logging | ||
import os | ||
|
||
from .exceptions.exceptions import SegmentNotFoundException | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
MISSING_SEGMENT_MSG = 'cannot find the current segment/subsegment, please make sure you have a segment open' | ||
SUPPORTED_CONTEXT_MISSING = ('RUNTIME_ERROR', 'LOG_ERROR') | ||
CXT_MISSING_STRATEGY_KEY = 'AWS_XRAY_CONTEXT_MISSING' | ||
|
||
|
||
class Context(object): | ||
""" | ||
The context storage class to store trace entities(segments/subsegments). | ||
The default implementation uses threadlocal to store these entities. | ||
It also provides interfaces to manually inject trace entities which will | ||
replace the current stored entities and to clean up the storage. | ||
For any data access or data mutation, if there is no active segment present | ||
if will use user-defined behavior to handle such case. By default it throws | ||
an runtime error. | ||
This data structure is thread-safe. | ||
""" | ||
def __init__(self, context_missing='RUNTIME_ERROR'): | ||
|
||
self._local = threading.local() | ||
strategy = os.getenv(CXT_MISSING_STRATEGY_KEY, context_missing) | ||
self._context_missing = strategy | ||
|
||
def put_segment(self, segment): | ||
""" | ||
Store the segment created by ``xray_recorder`` to the context. | ||
It overrides the current segment if there is already one. | ||
""" | ||
setattr(self._local, 'entities', [segment]) | ||
|
||
def end_segment(self, end_time=None): | ||
""" | ||
End the current active segment. | ||
:param int end_time: epoch in seconds. If not specified the current | ||
system time will be used. | ||
""" | ||
entity = self.get_trace_entity() | ||
if not entity: | ||
log.warning("No segment to end") | ||
return | ||
if self._is_subsegment(entity): | ||
entity.parent_segment.close(end_time) | ||
else: | ||
entity.close(end_time) | ||
|
||
def put_subsegment(self, subsegment): | ||
""" | ||
Store the subsegment created by ``xray_recorder`` to the context. | ||
If you put a new subsegment while there is already an open subsegment, | ||
the new subsegment becomes the child of the existing subsegment. | ||
""" | ||
entity = self.get_trace_entity() | ||
if not entity: | ||
log.warning("Active segment or subsegment not found. Discarded %s." % subsegment.name) | ||
return | ||
|
||
entity.add_subsegment(subsegment) | ||
self._local.entities.append(subsegment) | ||
|
||
def end_subsegment(self, end_time=None): | ||
""" | ||
End the current active segment. Return False if there is no | ||
subsegment to end. | ||
:param int end_time: epoch in seconds. If not specified the current | ||
system time will be used. | ||
""" | ||
subsegment = self.get_trace_entity() | ||
if self._is_subsegment(subsegment): | ||
subsegment.close(end_time) | ||
self._local.entities.pop() | ||
return True | ||
else: | ||
log.warning("No subsegment to end.") | ||
return False | ||
|
||
def get_trace_entity(self): | ||
""" | ||
Return the current trace entity(segment/subsegment). If there is none, | ||
it behaves based on pre-defined ``context_missing`` strategy. | ||
""" | ||
if not getattr(self._local, 'entities', None): | ||
return self.handle_context_missing() | ||
|
||
return self._local.entities[-1] | ||
|
||
def set_trace_entity(self, trace_entity): | ||
""" | ||
Store the input trace_entity to local context. It will overwrite all | ||
existing ones if there is any. | ||
""" | ||
setattr(self._local, 'entities', [trace_entity]) | ||
|
||
def clear_trace_entities(self): | ||
""" | ||
clear all trace_entities stored in the local context. | ||
In case of using threadlocal to store trace entites, it will | ||
clean up all trace entities created by the current thread. | ||
""" | ||
self._local.__dict__.clear() | ||
|
||
def handle_context_missing(self): | ||
""" | ||
Called whenever there is no trace entity to access or mutate. | ||
""" | ||
if self.context_missing == 'RUNTIME_ERROR': | ||
log.error(MISSING_SEGMENT_MSG) | ||
raise SegmentNotFoundException(MISSING_SEGMENT_MSG) | ||
else: | ||
log.error(MISSING_SEGMENT_MSG) | ||
|
||
def _is_subsegment(self, entity): | ||
|
||
return hasattr(entity, 'type') and entity.type == 'subsegment' | ||
|
||
@property | ||
def context_missing(self): | ||
return self._context_missing | ||
|
||
@context_missing.setter | ||
def context_missing(self, value): | ||
if value not in SUPPORTED_CONTEXT_MISSING: | ||
log.warning('specified context_missing not supported, using default.') | ||
return | ||
|
||
self._context_missing = value |
Empty file.
Oops, something went wrong.