Exemplo n.º 1
0
def test_traceback_hide(elasticapm_client):
    def get_me_a_filtered_frame(hide=True):
        __traceback_hide__ = True
        if not hide:
            del __traceback_hide__

        return list(stacks.iter_stack_frames())

    # hide frame from `get_me_a_filtered_frame
    frames = list(stacks.get_stack_info(get_me_a_filtered_frame(hide=True)))
    assert frames[0]["function"] == "test_traceback_hide"

    # don't hide it:
    frames = list(stacks.get_stack_info(get_me_a_filtered_frame(hide=False)))
    assert frames[0]["function"] == "get_me_a_filtered_frame"
Exemplo n.º 2
0
    def capture(client, exc_info=None, **kwargs):
        culprit = exc_value = exc_type = exc_module = frames = exc_traceback = None
        new_exc_info = False
        if not exc_info or exc_info is True:
            new_exc_info = True
            exc_info = sys.exc_info()

        if not exc_info:
            raise ValueError("No exception found")

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = get_stack_info(
                iter_traceback_frames(exc_traceback),
                with_locals=client.config.collect_local_variables in ("errors", "all"),
                library_frame_context_lines=client.config.source_lines_error_library_frames,
                in_app_frame_context_lines=client.config.source_lines_error_app_frames,
                include_paths_re=client.include_paths_re,
                exclude_paths_re=client.exclude_paths_re,
                locals_processor_func=lambda local_var: varmap(
                    lambda k, val: shorten(
                        val,
                        list_length=client.config.local_var_list_max_length,
                        string_length=client.config.local_var_max_length,
                    ),
                    local_var,
                ),
            )

            culprit = get_culprit(frames, client.config.include_paths, client.config.exclude_paths)

            if hasattr(exc_type, "__module__"):
                exc_module = exc_type.__module__
                exc_type = exc_type.__name__
            else:
                exc_module = None
                exc_type = exc_type.__name__
        finally:
            if new_exc_info:
                try:
                    del exc_info
                    del exc_traceback
                except Exception as e:
                    logger.exception(e)
        if "message" in kwargs:
            message = kwargs["message"]
        else:
            message = "%s: %s" % (exc_type, to_unicode(exc_value)) if exc_value else str(exc_type)

        return {
            "id": "%032x" % random.getrandbits(128),
            "culprit": culprit,
            "exception": {
                "message": message,
                "type": keyword_field(str(exc_type)),
                "module": keyword_field(str(exc_module)),
                "stacktrace": frames,
            },
        }
Exemplo n.º 3
0
 def _get_stack_info_for_trace(self,
                               frames,
                               with_source_context=True,
                               with_locals=True):
     """Overrideable in derived clients to add frames/info, e.g. templates"""
     return stacks.get_stack_info(frames, with_source_context, with_locals,
                                  self.include_paths_re,
                                  self.exclude_paths_re)
Exemplo n.º 4
0
    def capture(client, exc_info=None, **kwargs):
        culprit = exc_value = exc_type = exc_module = frames = exc_traceback = None
        new_exc_info = False
        if not exc_info or exc_info is True:
            new_exc_info = True
            exc_info = sys.exc_info()

        if not exc_info:
            raise ValueError('No exception found')

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = varmap(
                lambda k, v: shorten(v),
                get_stack_info(
                    iter_traceback_frames(exc_traceback),
                    with_locals=client.config.collect_local_variables in ('errors', 'all'),
                    with_source_context=client.config.collect_source in ('errors', 'all'),
                    include_paths_re=client.include_paths_re,
                    exclude_paths_re=client.exclude_paths_re,
                )
            )

            culprit = get_culprit(frames, client.config.include_paths, client.config.exclude_paths)

            if hasattr(exc_type, '__module__'):
                exc_module = exc_type.__module__
                exc_type = exc_type.__name__
            else:
                exc_module = None
                exc_type = exc_type.__name__
        finally:
            if new_exc_info:
                try:
                    del exc_info
                    del exc_traceback
                except Exception as e:
                    logger.exception(e)
        if 'message' in kwargs:
            message = kwargs['message']
        else:
            message = '%s: %s' % (exc_type, to_unicode(exc_value)) if exc_value else str(exc_type)

        return {
            'id': str(uuid.uuid4()),
            'culprit': culprit,
            'exception': {
                'message': message,
                'type': str(exc_type),
                'module': str(exc_module),
                'stacktrace': frames,
            }
        }
Exemplo n.º 5
0
    def capture(client, exc_info=None, **kwargs):
        culprit = exc_value = exc_type = exc_module = frames = None
        new_exc_info = False
        if not exc_info or exc_info is True:
            new_exc_info = True
            exc_info = sys.exc_info()

        if not exc_info:
            raise ValueError('No exception found')

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = varmap(
                lambda k, v: shorten(v,
                                     string_length=client.string_max_length,
                                     list_length=client.list_max_length),
                get_stack_info((iter_traceback_frames(exc_traceback))))

            culprit = get_culprit(frames, client.include_paths,
                                  client.exclude_paths)

            if hasattr(exc_type, '__module__'):
                exc_module = exc_type.__module__
                exc_type = exc_type.__name__
            else:
                exc_module = None
                exc_type = exc_type.__name__
        finally:
            if new_exc_info:
                try:
                    del exc_info
                    del exc_traceback
                except Exception as e:
                    logger.exception(e)

        return {
            'id': str(uuid.uuid4()),
            'culprit': culprit,
            'exception': {
                'message':
                '%s: %s' % (exc_type, to_unicode(exc_value))
                if exc_value else str(exc_type),
                'type':
                str(exc_type),
                'module':
                str(exc_module),
                'stacktrace':
                frames,
            }
        }
Exemplo n.º 6
0
def test_bad_locals_in_frame():
    frame = Mock()
    frame.f_locals = Context({"foo": "bar", "biz": "baz"})
    frame.f_lineno = 1
    frame.f_globals = {}
    frame.f_code.co_filename = __file__.replace(".pyc", ".py")
    frame.f_code.co_name = __name__
    frames = [(frame, 1)]
    results = get_stack_info(frames)
    assert len(results) == 1
    result = results[0]
    assert "vars" in result
    variables = {"foo": "bar", "biz": "baz"}
    assert result["vars"] == variables
Exemplo n.º 7
0
 def _get_stack_info_for_trace(self, frames,
                               library_frame_context_lines=None,
                               in_app_frame_context_lines=None,
                               with_locals=True,
                               locals_processor_func=None):
     """Overrideable in derived clients to add frames/info, e.g. templates"""
     return stacks.get_stack_info(
         frames,
         library_frame_context_lines=library_frame_context_lines,
         in_app_frame_context_lines=in_app_frame_context_lines,
         with_locals=with_locals,
         include_paths_re=self.include_paths_re,
         exclude_paths_re=self.exclude_paths_re,
         locals_processor_func=locals_processor_func,
     )
Exemplo n.º 8
0
def test_bad_locals_in_frame():
    frame = Mock()
    frame.f_locals = Context({
        'foo': 'bar',
        'biz': 'baz',
    })
    frame.f_lineno = 1
    frame.f_globals = {}
    frame.f_code.co_filename = __file__.replace('.pyc', '.py')
    frame.f_code.co_name = __name__
    frames = [(frame, 1)]
    results = get_stack_info(frames)
    assert len(results) == 1
    result = results[0]
    assert 'vars' in result
    variables = {
        "foo": "bar",
        "biz": "baz",
    }
    assert result['vars'] == variables
Exemplo n.º 9
0
 def test_bad_locals_in_frame(self):
     frame = Mock()
     frame.f_locals = Context({
         'foo': 'bar',
         'biz': 'baz',
     })
     frame.f_lineno = 1
     frame.f_globals = {}
     frame.f_code.co_filename = __file__.replace('.pyc', '.py')
     frame.f_code.co_name = __name__
     frames = [(frame, 1)]
     results = get_stack_info(frames)
     self.assertEquals(len(results), 1)
     result = results[0]
     self.assertTrue('vars' in result)
     vars = {
         "foo": "bar",
         "biz": "baz",
     }
     self.assertEquals(result['vars'], vars)
Exemplo n.º 10
0
    def _build_msg_for_logging(self,
                               event_type,
                               date=None,
                               context=None,
                               custom=None,
                               stack=None,
                               handled=True,
                               **kwargs):
        """
        Captures, processes and serializes an event into a dict object
        """
        transaction = get_transaction()
        if transaction:
            transaction_context = deepcopy(transaction.context)
        else:
            transaction_context = {}
        event_data = {}
        if custom is None:
            custom = {}
        if date is not None:
            warnings.warn(
                "The date argument is no longer evaluated and will be removed in a future release",
                DeprecationWarning)
        date = time.time()
        if stack is None:
            stack = self.config.auto_log_stacks
        if context:
            transaction_context.update(context)
            context = transaction_context
        else:
            context = transaction_context
        event_data["context"] = context
        if transaction and transaction.tags:
            context["tags"] = deepcopy(transaction.tags)

        # if '.' not in event_type:
        # Assume it's a builtin
        event_type = "elasticapm.events.%s" % event_type

        handler = self.get_handler(event_type)
        result = handler.capture(self, **kwargs)
        if self._filter_exception_type(result):
            return
        # data (explicit) culprit takes over auto event detection
        culprit = result.pop("culprit", None)
        if custom.get("culprit"):
            culprit = custom.pop("culprit")

        for k, v in compat.iteritems(result):
            if k not in event_data:
                event_data[k] = v

        log = event_data.get("log", {})
        if stack and "stacktrace" not in log:
            if stack is True:
                frames = stacks.iter_stack_frames(skip=3)
            else:
                frames = stack
            frames = stacks.get_stack_info(
                frames,
                with_locals=self.config.collect_local_variables
                in ("errors", "all"),
                library_frame_context_lines=self.config.
                source_lines_error_library_frames,
                in_app_frame_context_lines=self.config.
                source_lines_error_app_frames,
                include_paths_re=self.include_paths_re,
                exclude_paths_re=self.exclude_paths_re,
                locals_processor_func=lambda local_var: varmap(
                    lambda k, v: shorten(
                        v,
                        list_length=self.config.local_var_list_max_length,
                        string_length=self.config.local_var_max_length,
                    ),
                    local_var,
                ),
            )
            log["stacktrace"] = frames

        if "stacktrace" in log and not culprit:
            culprit = stacks.get_culprit(log["stacktrace"],
                                         self.config.include_paths,
                                         self.config.exclude_paths)

        if "level" in log and isinstance(log["level"], compat.integer_types):
            log["level"] = logging.getLevelName(log["level"]).lower()

        if log:
            event_data["log"] = log

        if culprit:
            event_data["culprit"] = culprit

        if "custom" in context:
            context["custom"].update(custom)
        else:
            context["custom"] = custom

        # Make sure all data is coerced
        event_data = transform(event_data)
        if "exception" in event_data:
            event_data["exception"]["handled"] = bool(handled)

        event_data["timestamp"] = int(date * 1000000)

        transaction = get_transaction()
        if transaction:
            if transaction.trace_parent:
                event_data["trace_id"] = transaction.trace_parent.trace_id
            event_data["parent_id"] = transaction.id
            event_data["transaction_id"] = transaction.id

        return event_data
Exemplo n.º 11
0
    def _build_msg_for_logging(self,
                               event_type,
                               date=None,
                               context=None,
                               custom=None,
                               stack=None,
                               handled=True,
                               **kwargs):
        """
        Captures, processes and serializes an event into a dict object
        """
        transaction = get_transaction()
        if transaction:
            transaction_context = deepcopy(transaction.context)
        else:
            transaction_context = {}
        event_data = {}
        if custom is None:
            custom = {}
        if not date:
            date = datetime.datetime.utcnow()
        if stack is None:
            stack = self.config.auto_log_stacks
        if context:
            transaction_context.update(context)
            context = transaction_context
        else:
            context = transaction_context
        event_data['context'] = context
        if transaction and transaction.tags:
            context['tags'] = deepcopy(transaction.tags)

        # if '.' not in event_type:
        # Assume it's a builtin
        event_type = 'elasticapm.events.%s' % event_type

        handler = self.get_handler(event_type)
        result = handler.capture(self, **kwargs)
        if self._filter_exception_type(result):
            return
        # data (explicit) culprit takes over auto event detection
        culprit = result.pop('culprit', None)
        if custom.get('culprit'):
            culprit = custom.pop('culprit')

        for k, v in compat.iteritems(result):
            if k not in event_data:
                event_data[k] = v

        log = event_data.get('log', {})
        if stack and 'stacktrace' not in log:
            if stack is True:
                frames = stacks.iter_stack_frames(skip=3)
            else:
                frames = stack
            frames = stacks.get_stack_info(
                frames,
                with_locals=self.config.collect_local_variables
                in ('errors', 'all'),
                library_frame_context_lines=self.config.
                source_lines_error_library_frames,
                in_app_frame_context_lines=self.config.
                source_lines_error_app_frames,
                include_paths_re=self.include_paths_re,
                exclude_paths_re=self.exclude_paths_re,
                locals_processor_func=lambda local_var: varmap(
                    lambda k, v: shorten(
                        v,
                        list_length=self.config.local_var_list_max_length,
                        string_length=self.config.local_var_max_length,
                    ), local_var))
            log['stacktrace'] = frames

        if 'stacktrace' in log and not culprit:
            culprit = stacks.get_culprit(log['stacktrace'],
                                         self.config.include_paths,
                                         self.config.exclude_paths)

        if 'level' in log and isinstance(log['level'], compat.integer_types):
            log['level'] = logging.getLevelName(log['level']).lower()

        if log:
            event_data['log'] = log

        if culprit:
            event_data['culprit'] = culprit

        if 'custom' in context:
            context['custom'].update(custom)
        else:
            context['custom'] = custom

        # Run the data through processors
        for processor in self.processors:
            event_data = processor(self, event_data)

        # Make sure all data is coerced
        event_data = transform(event_data)
        if 'exception' in event_data:
            event_data['exception']['handled'] = bool(handled)

        event_data.update({
            'timestamp':
            date.strftime(constants.TIMESTAMP_FORMAT),
        })

        transaction = get_transaction()
        if transaction:
            event_data['transaction'] = {'id': transaction.id}

        return self._build_msg({'errors': [event_data]})
Exemplo n.º 12
0
    def build_msg_for_logging(self,
                              event_type,
                              data=None,
                              date=None,
                              extra=None,
                              stack=None,
                              **kwargs):
        """
        Captures, processes and serializes an event into a dict object
        """

        if data is None:
            data = {}
        if extra is None:
            extra = {}
        if not date:
            date = datetime.datetime.utcnow()
        if stack is None:
            stack = self.auto_log_stacks
        if 'context' not in data:
            data['context'] = context = {}
        else:
            context = data['context']

        # if '.' not in event_type:
        # Assume it's a builtin
        event_type = 'elasticapm.events.%s' % event_type

        handler = self.get_handler(event_type)
        result = handler.capture(self, data=data, **kwargs)
        if self._filter_exception_type(result):
            return
        # data (explicit) culprit takes over auto event detection
        culprit = result.pop('culprit', None)
        if data.get('culprit'):
            culprit = data['culprit']

        for k, v in six.iteritems(result):
            if k not in data:
                data[k] = v

        log = data.get('log', {})
        if stack and 'stacktrace' not in log:
            if stack is True:
                frames = iter_stack_frames()
            else:
                frames = stack
            frames = varmap(
                lambda k, v: shorten(v,
                                     string_length=self.string_max_length,
                                     list_length=self.list_max_length),
                stacks.get_stack_info(frames))
            log['stacktrace'] = frames

        if 'stacktrace' in log and not culprit:
            culprit = get_culprit(log['stacktrace'], self.include_paths,
                                  self.exclude_paths)

        if 'level' in log and isinstance(log['level'], six.integer_types):
            log['level'] = logging.getLevelName(log['level']).lower()

        if log:
            data['log'] = log

        if culprit:
            data['culprit'] = culprit

        context['custom'] = extra

        # Run the data through processors
        for processor in self.processors:
            data = processor(self, data)

        # Make sure all data is coerced
        data = transform(data)

        data.update({
            'timestamp': date.strftime(defaults.TIMESTAMP_FORMAT),
        })

        return self.build_msg({'errors': [data]})
Exemplo n.º 13
0
    def get_stack_info_for_trace(self, frames, extended=True):
        """Overrideable in derived clients to add frames/info, e.g. templates

        4.0: Use for error frames too.
        """
        return stacks.get_stack_info(frames, extended)
Exemplo n.º 14
0
    def capture(client, exc_info=None, **kwargs):
        culprit = exc_value = exc_type = exc_module = frames = exc_traceback = None
        new_exc_info = False
        if not exc_info or exc_info is True:
            new_exc_info = True
            exc_info = sys.exc_info()

        if exc_info == (None, None, None):
            raise ValueError("No exception found: capture_exception requires an active exception.")

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = get_stack_info(
                iter_traceback_frames(exc_traceback, config=client.config),
                with_locals=client.config.collect_local_variables in ("errors", "all"),
                library_frame_context_lines=client.config.source_lines_error_library_frames,
                in_app_frame_context_lines=client.config.source_lines_error_app_frames,
                include_paths_re=client.include_paths_re,
                exclude_paths_re=client.exclude_paths_re,
                locals_processor_func=lambda local_var: varmap(
                    lambda k, val: shorten(
                        val,
                        list_length=client.config.local_var_list_max_length,
                        string_length=client.config.local_var_max_length,
                        dict_length=client.config.local_var_dict_max_length,
                    ),
                    local_var,
                ),
            )

            culprit = kwargs.get("culprit", None) or get_culprit(
                frames, client.config.include_paths, client.config.exclude_paths
            )

            if hasattr(exc_type, "__module__"):
                exc_module = exc_type.__module__
                exc_type = exc_type.__name__
            else:
                exc_module = None
                exc_type = exc_type.__name__
        finally:
            if new_exc_info:
                try:
                    del exc_info
                    del exc_traceback
                except Exception as e:
                    logger.exception(e)
        if "message" in kwargs:
            message = kwargs["message"]
        else:
            message = "%s: %s" % (exc_type, to_unicode(exc_value)) if exc_value else str(exc_type)

        data = {
            "id": "%032x" % random.getrandbits(128),
            "culprit": keyword_field(culprit),
            "exception": {
                "message": message,
                "type": keyword_field(str(exc_type)),
                "module": keyword_field(str(exc_module)),
                "stacktrace": frames,
            },
        }
        if compat.PY3:
            depth = kwargs.get("_exc_chain_depth", 0)
            if depth > EXCEPTION_CHAIN_MAX_DEPTH:
                return
            cause = exc_value.__cause__
            chained_context = exc_value.__context__

            # we follow the pattern of Python itself here and only capture the chained exception
            # if cause is not None and __suppress_context__ is False
            if chained_context and not (exc_value.__suppress_context__ and cause is None):
                if cause:
                    chained_exc_type = type(cause)
                    chained_exc_value = cause
                else:
                    chained_exc_type = type(chained_context)
                    chained_exc_value = chained_context
                chained_exc_info = chained_exc_type, chained_exc_value, chained_context.__traceback__

                chained_cause = Exception.capture(
                    client, exc_info=chained_exc_info, culprit="None", _exc_chain_depth=depth + 1
                )
                if chained_cause:
                    data["exception"]["cause"] = [chained_cause["exception"]]
        return data