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

Add annotations #348

Merged
merged 5 commits into from
Aug 8, 2022
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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,19 @@ If `AUTO_PATCH_PARENT_SEGMENT_NAME` is also specified, then a segment parent wil
with the supplied name, wrapping the automatic patching so that it captures any dangling
subsegments created on the import patching.

### Django in Lambda
X-Ray can't search on http annotations in subsegments. To enable searching the middleware adds the http values as annotations
This allows searching in the X-Ray console like so

This is configurable in settings with `URLS_AS_ANNOTATION` that has 3 valid values
`LAMBDA` - the default, which uses URLs as annotations by default if running in a lambda context
`ALL` - do this for every request (useful if running in a mixed lambda/other deployment)
`NONE` - don't do this for any (avoiding hitting the 50 annotation limit)

```
annotation.url BEGINSWITH "https://your.url.com/here"
```

### Add Flask middleware

```python
Expand Down
1 change: 1 addition & 0 deletions aws_xray_sdk/ext/django/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
'PATCH_MODULES': [],
'AUTO_PATCH_PARENT_SEGMENT_NAME': None,
'IGNORE_MODULE_PATTERNS': [],
'URLS_AS_ANNOTATION': 'LAMBDA', # 3 valid values, NONE -> don't ever, LAMBDA -> only for AWS Lambdas, ALL -> every time
}

XRAY_NAMESPACE = 'XRAY_RECORDER'
Expand Down
26 changes: 25 additions & 1 deletion aws_xray_sdk/ext/django/middleware.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from .conf import settings

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core.models import http
Expand Down Expand Up @@ -30,6 +31,14 @@ def __init__(self, get_response):
if check_in_lambda() and type(xray_recorder.context) == LambdaContext:
self.in_lambda_ctx = True

def _urls_as_annotation(self):
if settings.URLS_AS_ANNOTATION == "LAMBDA" and self.in_lambda_ctx:
return True
elif settings.URLS_AS_ANNOTATION == "ALL":
return True
return False


# hooks for django version >= 1.10
def __call__(self, request):

Expand All @@ -50,9 +59,10 @@ def __call__(self, request):
recorder=xray_recorder,
sampling_req=sampling_req,
)

if self.in_lambda_ctx:
segment = xray_recorder.begin_subsegment(name)
# X-Ray can't search/filter subsegments on URL but it can search annotations
# So for lambda to be able to filter by annotation we add these as annotations
else:
segment = xray_recorder.begin_segment(
name=name,
Expand All @@ -64,23 +74,37 @@ def __call__(self, request):
segment.save_origin_trace_header(xray_header)
segment.put_http_meta(http.URL, request.build_absolute_uri())
segment.put_http_meta(http.METHOD, request.method)
if self._urls_as_annotation():
segment.put_annotation(http.URL, request.build_absolute_uri())
segment.put_annotation(http.METHOD, request.method)

if meta.get(USER_AGENT_KEY):
segment.put_http_meta(http.USER_AGENT, meta.get(USER_AGENT_KEY))
if self._urls_as_annotation():
segment.put_annotation(http.USER_AGENT, meta.get(USER_AGENT_KEY))
if meta.get(X_FORWARDED_KEY):
# X_FORWARDED_FOR may come from untrusted source so we
# need to set the flag to true as additional information
segment.put_http_meta(http.CLIENT_IP, meta.get(X_FORWARDED_KEY))
segment.put_http_meta(http.X_FORWARDED_FOR, True)
if self._urls_as_annotation():
segment.put_annotation(http.CLIENT_IP, meta.get(X_FORWARDED_KEY))
segment.put_annotation(http.X_FORWARDED_FOR, True)
elif meta.get(REMOTE_ADDR_KEY):
segment.put_http_meta(http.CLIENT_IP, meta.get(REMOTE_ADDR_KEY))
if self._urls_as_annotation():
segment.put_annotation(http.CLIENT_IP, meta.get(REMOTE_ADDR_KEY))

response = self.get_response(request)
segment.put_http_meta(http.STATUS, response.status_code)
if self._urls_as_annotation():
segment.put_annotation(http.STATUS, response.status_code)

if response.has_header(CONTENT_LENGTH_KEY):
length = int(response[CONTENT_LENGTH_KEY])
segment.put_http_meta(http.CONTENT_LENGTH, length)
if self._urls_as_annotation():
segment.put_annotation(http.CONTENT_LENGTH, length)
response[http.XRAY_HEADER] = prepare_response_header(xray_header, segment)

if self.in_lambda_ctx:
Expand Down