def collect_stack_traces(include_nr_threads=False, include_xrays=False):
    """Generator that yields the (thread category, stack trace) of all the
    python threads.

    """
    for (txn, thread_id, thread_category, frame) in \
            transaction_cache().active_threads():

        # Skip NR Threads unless explicitly requested.

        if (thread_category == 'AGENT') and (not include_nr_threads):
            continue

        stack_trace = format_stack_trace(frame, thread_category)

        # Skip over empty stack traces. This is merely for optimization.
        #
        # It saves us from adding an empty deque to the txn obj, which will be
        # discarded later on during call tree merge.

        if not stack_trace:
            continue

        if include_xrays and txn:
            txn.add_profile_sample(stack_trace)

        yield thread_category, stack_trace
Example #2
0
def current_transaction():
    current = transaction_cache().current_transaction()
    if current and (current.ignore_transaction or current.stopped):
        return None
    return current
Example #3
0
    def __init__(self, application, enabled=None):

        self._application = application

        self.thread_id = transaction_cache().current_thread_id()

        self._transaction_id = id(self)
        self._transaction_lock = threading.Lock()

        self._dead = False

        self._state = STATE_PENDING
        self._settings = None

        self._priority = 0
        self._group = None
        self._name = None

        self._frameworks = set()

        self._frozen_path = None

        self._node_stack = []

        self._request_uri = None

        self.queue_start = 0.0

        self.start_time = 0.0
        self.end_time = 0.0

        self.stopped = False

        self._errors = []
        self._slow_sql = []

        self._stack_trace_count = 0
        self._explain_plan_count = 0

        self._string_cache = {}

        self._custom_params = {}
        self._request_params = {}

        self._utilization_tracker = None

        self._thread_utilization_start = None
        self._thread_utilization_end = None
        self._thread_utilization_value = None

        self._cpu_user_time_start = None
        self._cpu_user_time_end = None
        self._cpu_user_time_value = 0.0

        self._read_length = None

        self._read_start = None
        self._read_end = None

        self._sent_start = None
        self._sent_end = None

        self._bytes_read = 0
        self._bytes_sent = 0

        self._calls_read = 0
        self._calls_readline = 0
        self._calls_readlines = 0

        self._calls_write = 0
        self._calls_yield = 0

        self._request_environment = {}
        self._response_properties = {}
        self._transaction_metrics = {}

        self.background_task = False

        self.enabled = False
        self.autorum_disabled = False

        self.ignore_transaction = False
        self.suppress_apdex = False
        self.suppress_transaction_trace = False

        self.capture_params = False
        self.ignored_params = []

        self.response_code = 0

        self.apdex = 0

        self.rum_token = None
        self.rum_trace = False

        # 16-digit random hex. Padded with zeros in the front.
        self.guid = '%016x' % random.getrandbits(64)

        self.client_cross_process_id = None
        self.client_account_id = None
        self.client_application_id = None
        self.referring_transaction_guid = None
        self.record_tt = False

        self._custom_metrics = CustomMetrics()

        self._profile_samples = deque()
        self._profile_frames = {}
        self._profile_skip = 1
        self._profile_count = 0

        global_settings = application.global_settings

        if global_settings.enabled:
            if enabled or (enabled is None and application.enabled):
                self._settings = application.settings
                if not self._settings:
                    application.activate()

                    # We see again if the settings is now valid
                    # in case startup timeout had been specified
                    # and registration had been started and
                    # completed within the timeout.

                    self._settings = application.settings

                if self._settings:
                    self.enabled = True
Example #4
0
 def drop_transaction(self):
     transaction_cache().drop_transaction(self)
Example #5
0
 def save_transaction(self):
     transaction_cache().save_transaction(self)
Example #6
0
def current_thread_id():
    return transaction_cache().current_thread_id()
    def __init__(self, application, enabled=None):

        self._application = application

        self.thread_id = transaction_cache().current_thread_id()

        self._transaction_id = id(self)
        self._transaction_lock = threading.Lock()

        self._dead = False

        self._state = self.STATE_PENDING
        self._settings = None

        self._priority = 0
        self._group = None
        self._name = None

        self._frameworks = set()

        self._frozen_path = None

        self._node_stack = []

        self._request_uri = None

        self.queue_start = 0.0

        self.start_time = 0.0
        self.end_time = 0.0

        self.stopped = False

        self._trace_node_count = 0

        self._errors = []
        self._slow_sql = []

        self._stack_trace_count = 0
        self._explain_plan_count = 0

        self._string_cache = {}

        self._custom_params = {}
        self._request_params = {}

        self._utilization_tracker = None

        self._thread_utilization_start = None
        self._thread_utilization_end = None
        self._thread_utilization_value = None

        self._cpu_user_time_start = None
        self._cpu_user_time_end = None
        self._cpu_user_time_value = 0.0

        self._read_length = None

        self._read_start = None
        self._read_end = None

        self._sent_start = None
        self._sent_end = None

        self._bytes_read = 0
        self._bytes_sent = 0

        self._calls_read = 0
        self._calls_readline = 0
        self._calls_readlines = 0

        self._calls_write = 0
        self._calls_yield = 0

        self._request_environment = {}
        self._response_properties = {}
        self._transaction_metrics = {}

        self.background_task = False

        self.enabled = False
        self.autorum_disabled = False

        self.ignore_transaction = False
        self.suppress_apdex = False
        self.suppress_transaction_trace = False

        self.capture_params = False
        self.ignored_params = []

        self.response_code = 0

        self.apdex = 0

        self.rum_token = None
        self.rum_trace = False

        # 16-digit random hex. Padded with zeros in the front.
        self.guid = '%016x' % random.getrandbits(64)

        self.client_cross_process_id = None
        self.client_account_id = None
        self.client_application_id = None
        self.referring_transaction_guid = None
        self.record_tt = False
        self._trip_id = None
        self._referring_path_hash = None
        self._alternate_path_hashes = {}
        self.is_part_of_cat = False

        self.synthetics_resource_id = None
        self.synthetics_job_id = None
        self.synthetics_monitor_id = None
        self.synthetics_header = None

        self._custom_metrics = CustomMetrics()

        self._profile_samples = deque()
        self._profile_frames = {}
        self._profile_skip = 1
        self._profile_count = 0

        global_settings = application.global_settings

        if global_settings.enabled:
            if enabled or (enabled is None and application.enabled):
                self._settings = application.settings
                if not self._settings:
                    application.activate()

                    # We see again if the settings is now valid
                    # in case startup timeout had been specified
                    # and registration had been started and
                    # completed within the timeout.

                    self._settings = application.settings

                if self._settings:
                    self.enabled = True
 def drop_transaction(self):
     transaction_cache().drop_transaction(self)
 def save_transaction(self):
     transaction_cache().save_transaction(self)
def current_transaction(active_only=True):
    current = transaction_cache().current_transaction()
    if active_only:
        if current and (current.ignore_transaction or current.stopped):
            return None
    return current
Example #11
0
def current_transaction():
    current = transaction_cache().current_transaction()
    if current and (current.ignore_transaction or current.stopped):
        return None
    return current
Example #12
0
def _argspec_py3(func):
    a = inspect.getfullargspec(func)
    return (a.args, a.varargs, a.varkw, a.defaults)

if hasattr(inspect, 'getfullargspec'):
    _argspec = _argspec_py3
else:
    _argspec = _argspec_py2

from newrelic.core.agent import agent_instance
from newrelic.core.config import global_settings, flatten_settings
from newrelic.api.transaction import Transaction
from newrelic.api.object_wrapper import ObjectWrapper
from newrelic.core.transaction_cache import transaction_cache

_transaction_cache = transaction_cache()

def shell_command(wrapped):
    args, varargs, keywords, defaults = _argspec(wrapped)

    parser = optparse.OptionParser()
    for name in args[1:]:
        parser.add_option('--%s' % name, dest=name)

    @functools.wraps(wrapped)
    def wrapper(self, line):
        result = shlex.split(line)

        (options, args) = parser.parse_args(result)

        kwargs = {}
def collect_stack_traces():
    """Collects representaions for the stack of each active thread
    within the process. A item is yielded for each thread which consists
    of a tuple with the category of thread and then the stack trace.

    """

    for txn, thread_id, thread_category, frame in \
                transaction_cache().active_threads():
        stack_trace = []

        # The initial stack frame is the lowest frame or leaf node and
        # we will track back up the stack. For that lowest stack frame
        # we optionally want to introduce a fake node which captures the
        # actual execution line so will be displayed as a separate item
        # in the UI. This makes it easier to identify where in the
        # actual code it was executing.

        leaf_node = ADD_REAL_LINE_LEAF_NODE

        while frame:
            # The value frame.f_code.co_firstlineno is the first line of
            # code in the file for the specified function. The value
            # frame.f_lineno is the actual line which is being executed
            # at the time the stack frame was being viewed.

            filename = frame.f_code.co_filename
            func_name = frame.f_code.co_name
            first_line = frame.f_code.co_firstlineno

            real_line = frame.f_lineno

            # As we experiment with representation of the stack trace in
            # UI, allow line number for each stack frame to either be
            # the actual execution line or start of function. It would
            # appear at this point it should always be execution line.

            line_no = real_line if USE_REAL_LINE_NUMBERS else first_line

            # Set ourselves up to process next frame back up the stack.

            frame = frame.f_back

            # So as to make it more obvious to the user as to what their
            # code is doing, we drop out stack frames related to the
            # agent instrumentation. Don't do this for the agent threads
            # though as we still need to seem them in that case so can
            # debug what the agent itself is doing.

            if IGNORE_AGENT_FRAMES and thread_category != 'AGENT':
                if filename.startswith(AGENT_PACKAGE_DIRECTORY):
                    continue

            if leaf_node:
                # Add the fake leaf node with line number of where the
                # code was executing at the point of the sample. This
                # could be actual Python code within the function, or
                # more likely showing the point where a call is being
                # made into a C function wrapped as Python object. The
                # latter can occur because we will not see stack frames
                # when calling into C functions.

                name = '@%s#%s' % (func_name, real_line)
                method_data = _MethodData(filename, name, line_no)
                stack_trace.append(method_data)

                leaf_node = False

            # Add the actual node for the function being called at this
            # level in the stack frames.

            if ADD_LINE_TO_FUNC_NAME:
                name = '%s#%s' % (func_name, first_line)
            else:
                name = func_name

            method_data = _MethodData(filename, name, line_no)

            stack_trace.append(method_data)

        # Collect the stack trace samples in a list attached to the transaction
        # obj. This will be merged together to create a call tree if the
        # transaction is an xray txn.

        if txn:
            txn.add_profile_sample(stack_trace)

        yield thread_category, stack_trace
Example #14
0
def collect_stack_traces():
    """Collects representaions for the stack of each active thread
    within the process. A item is yielded for each thread which consists
    of a tuple with the category of thread and then the stack trace.

    """

    for thread_id, thread_category, frame in \
                transaction_cache().active_threads():
        stack_trace = []

        # The initial stack frame is the lowest frame or leaf node and
        # we will track back up the stack. For that lowest stack frame
        # we optionally want to introduce a fake node which captures the
        # actual execution line so will be displayed as a separate item
        # in the UI. This makes it easier to identify where in the
        # actual code it was executing.

        leaf_node = ADD_REAL_LINE_LEAF_NODE

        while frame:
            # The value frame.f_code.co_firstlineno is the first line of
            # code in the file for the specified function. The value
            # frame.f_lineno is the actual line which is being executed
            # at the time the stack frame was being viewed.

            filename = frame.f_code.co_filename
            func_name = frame.f_code.co_name
            first_line = frame.f_code.co_firstlineno

            real_line = frame.f_lineno

            # As we experiment with representation of the stack trace in
            # UI, allow line number for each stack frame to either be
            # the actual execution line or start of function. It would
            # appear at this point it should always be execution line.

            line_no = real_line if USE_REAL_LINE_NUMBERS else first_line

            # Set ourselves up to process next frame back up the stack.

            frame = frame.f_back

            # So as to make it more obvious to the user as to what their
            # code is doing, we drop out stack frames related to the
            # agent instrumentation. Don't do this for the agent threads
            # though as we still need to seem them in that case so can
            # debug what the agent itself is doing.

            if IGNORE_AGENT_FRAMES and thread_category != 'AGENT':
                if filename.startswith(AGENT_PACKAGE_DIRECTORY):
                    continue

            if leaf_node:
                # Add the fake leaf node with line number of where the
                # code was executing at the point of the sample. This
                # could be actual Python code within the function, or
                # more likely showing the point where a call is being
                # made into a C function wrapped as Python object. The
                # latter can occur because we will not see stack frames
                # when calling into C functions.

                name = '@%s#%s' % (func_name, real_line)
                method_data = _MethodData(filename, name, line_no)
                stack_trace.append(method_data)

                leaf_node = False

            # Add the actual node for the function being called at this
            # level in the stack frames.

            if ADD_LINE_TO_FUNC_NAME:
                name = '%s#%s' % (func_name, first_line)
            else:
                name = func_name

            method_data = _MethodData(filename, name, line_no)

            stack_trace.append(method_data)

        yield thread_category, stack_trace
Example #15
0
def current_thread_id():
    return transaction_cache().current_thread_id()