Exemple #1
0
 def set_transaction_extra_data(self, data, _key=None):
     transaction = get_transaction()
     if not transaction:
         return
     if not _key:
         _key = 'extra'
     transaction.extra[_key] = data
 def call_if_sampling(self, module, method, wrapped, instance, args,
                      kwargs):
     transaction = get_transaction()
     if not transaction or not transaction.is_sampled:
         return wrapped(*args, **kwargs)
     else:
         return self.call(module, method, wrapped, instance, args, kwargs)
Exemple #3
0
 def call_if_sampling(self, module, method, wrapped, instance, args,
                      kwargs):
     transaction = get_transaction()
     if not transaction:
         return wrapped(*args, **kwargs)
     elif not transaction.is_sampled:
         args, kwargs = self.mutate_unsampled_call_args(
             module, method, wrapped, instance, args, kwargs, transaction)
         return wrapped(*args, **kwargs)
     else:
         return self.call(module, method, wrapped, instance, args, kwargs)
def rum_tracing(request):
    transaction = get_transaction()
    if transaction and transaction.trace_parent:
        return {
            "apm": {
                "trace_id": transaction.trace_parent.trace_id,
                # only put the callable into the context to ensure that we only change the span_id if the value
                # is rendered
                "span_id": transaction.ensure_parent_id,
                "is_sampled": transaction.is_sampled,
                "is_sampled_js": "true" if transaction.is_sampled else "false",
            }
        }
    return {}
Exemple #5
0
 def rum_tracing():
     """
     Adds APM related IDs to the context used for correlating the backend transaction with the RUM transaction
     """
     transaction = get_transaction()
     if transaction and transaction.trace_parent:
         return {
             "apm": {
                 "trace_id": transaction.trace_parent.trace_id,
                 "span_id": lambda: transaction.ensure_parent_id(),
                 "is_sampled": transaction.is_sampled,
                 "is_sampled_js": "true" if transaction.is_sampled else "false",
             }
         }
     return {}
Exemple #6
0
    def call(self, module, method, wrapped, instance, args, kwargs):
        if "method" in kwargs:
            method = kwargs["method"]
        else:
            method = args[0]

        headers = None
        if "headers" in kwargs:
            headers = kwargs["headers"]
            if headers is None:
                headers = {}
                kwargs["headers"] = headers

        host = instance.host

        if instance.port != default_ports.get(instance.scheme):
            host += ":" + str(instance.port)

        if "url" in kwargs:
            url = kwargs["url"]
        else:
            url = args[1]

        signature = method.upper() + " " + host

        url = instance.scheme + "://" + host + url
        transaction = get_transaction()

        with capture_span(signature,
                          "ext.http.urllib3", {"url": url},
                          leaf=True) as span:
            # if urllib3 has been called in a leaf span, this span might be a DroppedSpan.
            leaf_span = span
            while isinstance(leaf_span, DroppedSpan):
                leaf_span = leaf_span.parent

            if headers is not None:
                # It's possible that there are only dropped spans, e.g. if we started dropping spans.
                # In this case, the transaction.id is used
                parent_id = leaf_span.id if leaf_span else transaction.id
                trace_parent = transaction.trace_parent.copy_from(
                    span_id=parent_id,
                    trace_options=TracingOptions(recorded=True))
                headers[constants.
                        TRACEPARENT_HEADER_NAME] = trace_parent.to_ascii()
            return wrapped(*args, **kwargs)
Exemple #7
0
def test_get_transaction_clear():
    requests_store = TransactionsStore(lambda: [], 99999)
    t = requests_store.begin_transaction("test")
    assert t == get_transaction(clear=True)
    assert get_transaction() is None
Exemple #8
0
def test_get_transaction():
    requests_store = TransactionsStore(lambda: [], 99999)
    t = requests_store.begin_transaction("test")
    assert t == get_transaction()
Exemple #9
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
Exemple #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 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]})
Exemple #11
0
 def set_transaction_name(self, name):
     transaction = get_transaction()
     if not transaction:
         return
     transaction.name = name
Exemple #12
0
def test_get_transaction_clear():
    requests_store = Tracer(lambda: [], lambda: [], lambda *args: None)
    t = requests_store.begin_transaction("test")
    assert t == get_transaction(clear=True)
    assert get_transaction() is None