Skip to content

Improve recorded detail of stacktraces #70

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

Merged
merged 2 commits into from
Sep 5, 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
4 changes: 2 additions & 2 deletions aws_xray_sdk/core/async_recorder.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import time
import traceback

import wrapt

from aws_xray_sdk.core.recorder import AWSXRayRecorder
from aws_xray_sdk.core.utils import stacktrace


class AsyncAWSXRayRecorder(AWSXRayRecorder):
Expand Down Expand Up @@ -47,7 +47,7 @@ async def record_subsegment_async(self, wrapped, instance, args, kwargs, name,
return return_value
except Exception as e:
exception = e
stack = traceback.extract_stack(limit=self._max_trace_back)
stack = stacktrace.get_stacktrace(limit=self._max_trace_back)
raise
finally:
# No-op if subsegment is `None` due to `LOG_ERROR`.
Expand Down
4 changes: 2 additions & 2 deletions aws_xray_sdk/core/recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import os
import platform
import time
import traceback

import wrapt

Expand All @@ -23,6 +22,7 @@
from .lambda_launcher import check_in_lambda
from .exceptions.exceptions import SegmentNameMissingException
from .utils.compat import string_types
from .utils import stacktrace

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -398,7 +398,7 @@ def record_subsegment(self, wrapped, instance, args, kwargs, name,
return return_value
except Exception as e:
exception = e
stack = traceback.extract_stack(limit=self.max_trace_back)
stack = stacktrace.get_stacktrace(limit=self.max_trace_back)
raise
finally:
# No-op if subsegment is `None` due to `LOG_ERROR`.
Expand Down
51 changes: 51 additions & 0 deletions aws_xray_sdk/core/utils/stacktrace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import sys
import traceback


def get_stacktrace(limit=None):
"""
Get a full stacktrace for the current state of execution.

Include the current state of the stack, minus this function.
If there is an active exception, include the stacktrace information from
the exception as well.

:param int limit:
Optionally limit stack trace size results. This parmaeters has the same
meaning as the `limit` parameter in `traceback.print_stack`.
:returns:
List of stack trace objects, in the same form as
`traceback.extract_stack`.
"""
if limit is not None and limit == 0:
# Nothing to return. This is consistent with the behavior of the
# functions in the `traceback` module.
return []

stack = traceback.extract_stack()
# Remove this `get_stacktrace()` function call from the stack info.
# For what we want to report, this is superfluous information and arguably
# adds garbage to the report.
# Also drop the `traceback.extract_stack()` call above from the returned
# stack info, since this is also superfluous.
stack = stack[:-2]

_exc_type, _exc, exc_traceback = sys.exc_info()
if exc_traceback is not None:
# If and only if there is a currently triggered exception, combine the
# exception traceback information with the current stack state to get a
# complete trace.
exc_stack = traceback.extract_tb(exc_traceback)
stack += exc_stack

# Limit the stack trace size, if a limit was specified:
if limit is not None:
# Copy the behavior of `traceback` functions with a `limit` argument.
# See https://docs.python.org/3/library/traceback.html.
if limit > 0:
# limit > 0: include the last `limit` items
stack = stack[-limit:]
else:
# limit < 0: include the first `abs(limit)` items
stack = stack[:abs(limit)]
return stack
4 changes: 2 additions & 2 deletions aws_xray_sdk/ext/aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
AioHttp Client tracing, only compatible with Aiohttp 3.X versions
"""
import aiohttp
import traceback

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
Expand Down Expand Up @@ -51,7 +51,7 @@ async def end_subsegment_with_exception(session, trace_config_ctx, params):
subsegment = xray_recorder.current_subsegment()
subsegment.add_exception(
params.exception,
traceback.extract_stack(limit=xray_recorder._max_trace_back)
stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back)
)

if isinstance(params.exception, LOCAL_EXCEPTIONS):
Expand Down
4 changes: 2 additions & 2 deletions aws_xray_sdk/ext/aiohttp/middleware.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""
AioHttp Middleware
"""
import traceback
from aiohttp import web
from aiohttp.web_exceptions import HTTPException

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 calculate_sampling_decision, \
calculate_segment_name, construct_xray_header, prepare_response_header

Expand Down Expand Up @@ -69,7 +69,7 @@ async def middleware(request, handler):
# Store exception information including the stacktrace to the segment
response = None
segment.put_http_meta(http.STATUS, 500)
stack = traceback.extract_stack(limit=xray_recorder.max_trace_back)
stack = stacktrace.get_stacktrace(limit=xray_recorder.max_trace_back)
segment.add_exception(err, stack)
raise
finally:
Expand Down
4 changes: 2 additions & 2 deletions aws_xray_sdk/ext/django/middleware.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import logging
import traceback

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 calculate_sampling_decision, \
calculate_segment_name, construct_xray_header, prepare_response_header

Expand Down Expand Up @@ -87,5 +87,5 @@ def process_exception(self, request, exception):
segment = xray_recorder.current_segment()
segment.put_http_meta(http.STATUS, 500)

stack = traceback.extract_stack(limit=xray_recorder._max_trace_back)
stack = stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back)
segment.add_exception(exception, stack)
5 changes: 2 additions & 3 deletions aws_xray_sdk/ext/flask/middleware.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import traceback

import flask.templating
from flask import request

from aws_xray_sdk.core.models import http
from aws_xray_sdk.core.utils import stacktrace
from aws_xray_sdk.ext.util import calculate_sampling_decision, \
calculate_segment_name, construct_xray_header, prepare_response_header

Expand Down Expand Up @@ -86,7 +85,7 @@ def _handle_exception(self, exception):
return

segment.put_http_meta(http.STATUS, 500)
stack = traceback.extract_stack(limit=self._recorder._max_trace_back)
stack = stacktrace.get_stacktrace(limit=self._recorder._max_trace_back)
segment.add_exception(exception, stack)
self._recorder.end_segment()

Expand Down