Beispiel #1
0
def test_passes_parent_sampling_decision_in_sampling_context(
    sentry_init, parent_sampling_decision
):
    sentry_init(traces_sample_rate=1.0)

    sentry_trace_header = (
        "12312012123120121231201212312012-1121201211212012-{sampled}".format(
            sampled=int(parent_sampling_decision)
        )
    )

    transaction = Transaction.continue_from_headers(
        headers={"sentry-trace": sentry_trace_header}, name="dogpark"
    )
    spy = mock.Mock(wraps=transaction)
    start_transaction(transaction=spy)

    # there's only one call (so index at 0) and kwargs are always last in a call
    # tuple (so index at -1)
    sampling_context = spy._set_initial_sampling_decision.mock_calls[0][-1][
        "sampling_context"
    ]
    assert "parent_sampled" in sampling_context
    # because we passed in a spy, attribute access requires unwrapping
    assert sampling_context["parent_sampled"]._mock_wraps is parent_sampling_decision
Beispiel #2
0
def test_transaction_naming(sentry_init, capture_events):
    sentry_init(traces_sample_rate=1.0)
    events = capture_events()

    # only transactions have names - spans don't
    with pytest.raises(TypeError):
        start_span(name="foo")
    assert len(events) == 0

    # default name in event if no name is passed
    with start_transaction() as transaction:
        pass
    assert len(events) == 1
    assert events[0]["transaction"] == "<unlabeled transaction>"

    # the name can be set once the transaction's already started
    with start_transaction() as transaction:
        transaction.name = "name-known-after-transaction-started"
    assert len(events) == 2
    assert events[1]["transaction"] == "name-known-after-transaction-started"

    # passing in a name works, too
    with start_transaction(name="a"):
        pass
    assert len(events) == 3
    assert events[2]["transaction"] == "a"
Beispiel #3
0
def test_nested_transaction_sampling_override():
    with start_transaction(name="outer", sampled=True) as outer_transaction:
        assert outer_transaction.sampled is True
        with start_transaction(name="inner",
                               sampled=False) as inner_transaction:
            assert inner_transaction.sampled is False
        assert outer_transaction.sampled is True
def test_continue_from_headers(sentry_init, capture_events, sampled,
                               sample_rate):
    """
    Ensure data is actually passed along via headers, and that they are read
    correctly.
    """
    sentry_init(traces_sample_rate=sample_rate)
    events = capture_events()

    # make a parent transaction (normally this would be in a different service)
    with start_transaction(
            name="hi",
            sampled=True if sample_rate == 0 else None) as parent_transaction:
        with start_span() as old_span:
            old_span.sampled = sampled
            headers = dict(
                Hub.current.iter_trace_propagation_headers(old_span))
            tracestate = parent_transaction._sentry_tracestate

    # child transaction, to prove that we can read 'sentry-trace' and
    # `tracestate` header data correctly
    child_transaction = Transaction.continue_from_headers(headers,
                                                          name="WRONG")
    assert child_transaction is not None
    assert child_transaction.parent_sampled == sampled
    assert child_transaction.trace_id == old_span.trace_id
    assert child_transaction.same_process_as_parent is False
    assert child_transaction.parent_span_id == old_span.span_id
    assert child_transaction.span_id != old_span.span_id
    assert child_transaction._sentry_tracestate == tracestate

    # add child transaction to the scope, to show that the captured message will
    # be tagged with the trace id (since it happens while the transaction is
    # open)
    with start_transaction(child_transaction):
        with configure_scope() as scope:
            # change the transaction name from "WRONG" to make sure the change
            # is reflected in the final data
            scope.transaction = "ho"
        capture_message("hello")

    # in this case the child transaction won't be captured
    if sampled is False or (sample_rate == 0 and sampled is None):
        trace1, message = events

        assert trace1["transaction"] == "hi"
    else:
        trace1, message, trace2 = events

        assert trace1["transaction"] == "hi"
        assert trace2["transaction"] == "ho"

        assert (trace1["contexts"]["trace"]["trace_id"] ==
                trace2["contexts"]["trace"]["trace_id"] ==
                child_transaction.trace_id ==
                message["contexts"]["trace"]["trace_id"])

    assert message["message"] == "hello"
Beispiel #5
0
def test_nested_transaction_sampling_override(sentry_init, sampled):
    sentry_init(traces_sample_rate=1.0)

    with start_transaction(name="outer", sampled=sampled) as outer_transaction:
        assert outer_transaction.sampled is sampled
        with start_transaction(name="inner",
                               sampled=(not sampled)) as inner_transaction:
            assert inner_transaction.sampled is not sampled
        assert outer_transaction.sampled is sampled
def test_continue_from_headers(sentry_init, capture_events, sampled, sample_rate):
    sentry_init(traces_sample_rate=sample_rate)
    events = capture_events()

    # make a parent transaction (normally this would be in a different service)
    with start_transaction(name="hi", sampled=True if sample_rate == 0 else None):
        with start_span() as old_span:
            old_span.sampled = sampled
            headers = dict(Hub.current.iter_trace_propagation_headers(old_span))

    # test that the sampling decision is getting encoded in the header correctly
    header = headers["sentry-trace"]
    if sampled is True:
        assert header.endswith("-1")
    if sampled is False:
        assert header.endswith("-0")
    if sampled is None:
        assert header.endswith("-")

    # child transaction, to prove that we can read 'sentry-trace' header data
    # correctly
    transaction = Transaction.continue_from_headers(headers, name="WRONG")
    assert transaction is not None
    assert transaction.parent_sampled == sampled
    assert transaction.trace_id == old_span.trace_id
    assert transaction.same_process_as_parent is False
    assert transaction.parent_span_id == old_span.span_id
    assert transaction.span_id != old_span.span_id

    # add child transaction to the scope, to show that the captured message will
    # be tagged with the trace id (since it happens while the transaction is
    # open)
    with start_transaction(transaction):
        with configure_scope() as scope:
            scope.transaction = "ho"
        capture_message("hello")

    if sampled is False or (sample_rate == 0 and sampled is None):
        trace1, message = events

        assert trace1["transaction"] == "hi"
    else:
        trace1, message, trace2 = events

        assert trace1["transaction"] == "hi"
        assert trace2["transaction"] == "ho"

        assert (
            trace1["contexts"]["trace"]["trace_id"]
            == trace2["contexts"]["trace"]["trace_id"]
            == transaction.trace_id
            == message["contexts"]["trace"]["trace_id"]
        )

    assert message["message"] == "hello"
Beispiel #7
0
def test_passes_custom_samling_context_from_start_transaction_to_traces_sampler(
    sentry_init, DictionaryContaining  # noqa: N803
):
    traces_sampler = mock.Mock()
    sentry_init(traces_sampler=traces_sampler)

    start_transaction(custom_sampling_context={"dogs": "yes", "cats": "maybe"})

    traces_sampler.assert_any_call(
        DictionaryContaining({"dogs": "yes", "cats": "maybe"})
    )
Beispiel #8
0
def test_start_transaction(sentry_init):
    sentry_init(traces_sample_rate=1.0)

    # you can have it start a transaction for you
    result1 = start_transaction(name="/interactions/other-dogs/new-dog",
                                op="greeting.sniff")
    assert isinstance(result1, Transaction)
    assert result1.name == "/interactions/other-dogs/new-dog"
    assert result1.op == "greeting.sniff"

    # or you can pass it an already-created transaction
    preexisting_transaction = Transaction(
        name="/interactions/other-dogs/new-dog", op="greeting.sniff")
    result2 = start_transaction(preexisting_transaction)
    assert result2 is preexisting_transaction
Beispiel #9
0
def test_continue_from_headers(sentry_init, capture_events, sampled):
    sentry_init(traces_sample_rate=1.0, traceparent_v2=True)
    events = capture_events()

    with start_transaction(name="hi"):
        with start_span() as old_span:
            old_span.sampled = sampled
            headers = dict(Hub.current.iter_trace_propagation_headers())

    header = headers["sentry-trace"]
    if sampled is True:
        assert header.endswith("-1")
    if sampled is False:
        assert header.endswith("-0")
    if sampled is None:
        assert header.endswith("-")

    transaction = Transaction.continue_from_headers(headers, name="WRONG")
    assert transaction is not None
    assert transaction.sampled == sampled
    assert transaction.trace_id == old_span.trace_id
    assert transaction.same_process_as_parent is False
    assert transaction.parent_span_id == old_span.span_id
    assert transaction.span_id != old_span.span_id

    with start_transaction(transaction):
        with configure_scope() as scope:
            scope.transaction = "ho"
        capture_message("hello")

    if sampled is False:
        trace1, message = events

        assert trace1["transaction"] == "hi"
    else:
        trace1, message, trace2 = events

        assert trace1["transaction"] == "hi"
        assert trace2["transaction"] == "ho"

        assert (
            trace1["contexts"]["trace"]["trace_id"]
            == trace2["contexts"]["trace"]["trace_id"]
            == transaction.trace_id
            == message["contexts"]["trace"]["trace_id"]
        )

    assert message["message"] == "hello"
Beispiel #10
0
    def get_with_pagination(self, path: str, *args: Any,
                            **kwargs: Any) -> Sequence[JSONData]:
        """
        Github uses the Link header to provide pagination links. Github
        recommends using the provided link relations and not constructing our
        own URL.
        https://docs.github.com/en/rest/guides/traversing-with-pagination
        """
        try:
            with sentry_sdk.configure_scope() as scope:
                parent_span_id = scope.span.span_id
                trace_id = scope.span.trace_id
        except AttributeError:
            parent_span_id = None
            trace_id = None

        with sentry_sdk.start_transaction(
                op=f"{self.integration_type}.http.pagination",
                name=
                f"{self.integration_type}.http_response.pagination.{self.name}",
                parent_span_id=parent_span_id,
                trace_id=trace_id,
                sampled=True,
        ):
            output = []
            resp = self.get(path, params={"per_page": self.page_size})
            output.extend(resp)
            page_number = 1

            while get_next_link(resp) and page_number < self.page_number_limit:
                resp = self.get(get_next_link(resp))
                output.extend(resp)
                page_number += 1
            return output
Beispiel #11
0
def test_crumb_capture_and_hint(sentry_init, capture_events):
    def before_breadcrumb(crumb, hint):
        crumb["data"]["extra"] = "foo"
        return crumb

    sentry_init(integrations=[HttpxIntegration()],
                before_breadcrumb=before_breadcrumb)
    clients = (httpx.Client(), httpx.AsyncClient())
    for i, c in enumerate(clients):
        with start_transaction():
            events = capture_events()

            url = "https://httpbin.org/status/200"
            if not asyncio.iscoroutinefunction(c.get):
                response = c.get(url)
            else:
                response = asyncio.get_event_loop().run_until_complete(
                    c.get(url))

            assert response.status_code == 200
            capture_message("Testing!")

            (event, ) = events
            # send request twice so we need get breadcrumb by index
            crumb = event["breadcrumbs"]["values"][i]
            assert crumb["type"] == "http"
            assert crumb["category"] == "httplib"
            assert crumb["data"] == {
                "url": url,
                "method": "GET",
                "status_code": 200,
                "reason": "OK",
                "extra": "foo",
            }
Beispiel #12
0
def test_outgoing_trace_headers(
        sentry_init,
        monkeypatch,
        StringContaining  # noqa: N803
):
    # HTTPSConnection.send is passed a string containing (among other things)
    # the headers on the request. Mock it so we can check the headers, and also
    # so it doesn't try to actually talk to the internet.
    mock_send = mock.Mock()
    monkeypatch.setattr(HTTPSConnection, "send", mock_send)

    sentry_init(traces_sample_rate=1.0)

    with start_transaction(
            name="/interactions/other-dogs/new-dog",
            op="greeting.sniff",
            trace_id="12312012123120121231201212312012",
    ) as transaction:

        HTTPSConnection("www.squirrelchasers.com").request(
            "GET", "/top-chasers")

        request_span = transaction._span_recorder.spans[-1]

        expected_sentry_trace = (
            "sentry-trace: {trace_id}-{parent_span_id}-{sampled}".format(
                trace_id=transaction.trace_id,
                parent_span_id=request_span.span_id,
                sampled=1,
            ))

        mock_send.assert_called_with(StringContaining(expected_sentry_trace))
Beispiel #13
0
def subscription_checker(**kwargs):
    """
    Checks for subscriptions stuck in a transition status and attempts to repair them
    """
    count = 0
    with sentry_sdk.start_transaction(
        op="subscription_checker",
        name="subscription_checker",
        sampled=False,
    ):
        for subscription in QuerySubscription.objects.filter(
            status__in=(
                QuerySubscription.Status.CREATING.value,
                QuerySubscription.Status.UPDATING.value,
                QuerySubscription.Status.DELETING.value,
            ),
            date_updated__lt=timezone.now() - SUBSCRIPTION_STATUS_MAX_AGE,
        ):
            with sentry_sdk.start_span(op="repair_subscription") as span:
                span.set_data("subscription_id", subscription.id)
                span.set_data("status", subscription.status)
                count += 1
                if subscription.status == QuerySubscription.Status.CREATING.value:
                    create_subscription_in_snuba.delay(query_subscription_id=subscription.id)
                elif subscription.status == QuerySubscription.Status.UPDATING.value:
                    update_subscription_in_snuba.delay(query_subscription_id=subscription.id)
                elif subscription.status == QuerySubscription.Status.DELETING.value:
                    delete_subscription_from_snuba.delay(query_subscription_id=subscription.id)

    metrics.incr("snuba.subscriptions.repair", amount=count)
Beispiel #14
0
 def do_GET(self):  # pylint: disable=invalid-name
     """Respond to CC w/ the current image"""
     with sentry_sdk.start_transaction(op="http", name="GET"):
         self.send_response(200)
         self.send_header("Content-type", "image/png")
         self.end_headers()
         parent.image.save(self.wfile, "PNG", optimize=True)
def test_basic(sentry_init, capture_events, sample_rate):
    sentry_init(traces_sample_rate=sample_rate)
    events = capture_events()

    with start_transaction(name="hi") as transaction:
        transaction.set_status("ok")
        with pytest.raises(ZeroDivisionError):
            with start_span(op="foo", description="foodesc"):
                1 / 0

        with start_span(op="bar", description="bardesc"):
            pass

    if sample_rate:
        assert len(events) == 1
        event = events[0]

        span1, span2 = event["spans"]
        parent_span = event
        assert span1["tags"]["status"] == "internal_error"
        assert span1["op"] == "foo"
        assert span1["description"] == "foodesc"
        assert "status" not in span2.get("tags", {})
        assert span2["op"] == "bar"
        assert span2["description"] == "bardesc"
        assert parent_span["transaction"] == "hi"
        assert "status" not in event["tags"]
        assert event["contexts"]["trace"]["status"] == "ok"
    else:
        assert not events
Beispiel #16
0
def test_tolerates_traces_sampler_returning_a_boolean(
        sentry_init, traces_sampler_return_value):
    sentry_init(traces_sampler=mock.Mock(
        return_value=traces_sampler_return_value))

    transaction = start_transaction(name="dogpark")
    assert transaction.sampled is traces_sampler_return_value
Beispiel #17
0
def test_simple(capture_events, celery, celery_invocation):
    events = capture_events()

    @celery.task(name="dummy_task")
    def dummy_task(x, y):
        foo = 42  # noqa
        return x / y

    with start_transaction() as transaction:
        celery_invocation(dummy_task, 1, 2)
        _, expected_context = celery_invocation(dummy_task, 1, 0)

    (event,) = events

    assert event["contexts"]["trace"]["trace_id"] == transaction.trace_id
    assert event["contexts"]["trace"]["span_id"] != transaction.span_id
    assert event["transaction"] == "dummy_task"
    assert "celery_task_id" in event["tags"]
    assert event["extra"]["celery-job"] == dict(
        task_name="dummy_task", **expected_context
    )

    (exception,) = event["exception"]["values"]
    assert exception["type"] == "ZeroDivisionError"
    assert exception["mechanism"]["type"] == "celery"
    assert exception["stacktrace"]["frames"][0]["vars"]["foo"] == "42"
Beispiel #18
0
    def request(self, *args, **kwargs):

        metrics.incr(
            "%s.http_request" % self.datadog_prefix,
            sample_rate=1.0,
            tags={self.integration_type: self.name},
        )

        try:
            with sentry_sdk.configure_scope() as scope:
                parent_span_id = scope.span.span_id
                trace_id = scope.span.trace_id
        except AttributeError:
            parent_span_id = None
            trace_id = None

        with sentry_sdk.start_transaction(
            op=f"{self.integration_type}.http",
            name=f"{self.integration_type}.http_response.{self.name}",
            parent_span_id=parent_span_id,
            trace_id=trace_id,
            sampled=True,
        ) as span:
            resp = ApiClient.request(self, *args, **kwargs)
            self.track_response_data(resp.status_code, span, None, resp)
            return resp
Beispiel #19
0
def process_event(cache_key,
                  start_time=None,
                  event_id=None,
                  data_has_changed=None,
                  **kwargs):
    """
    Handles event processing (for those events that need it)

    This excludes symbolication via symbolicator service (see symbolicate_event).

    :param string cache_key: the cache key for the event data
    :param int start_time: the timestamp when the event was ingested
    :param string event_id: the event identifier
    :param boolean data_has_changed: set to True if the event data was changed in previous tasks
    """
    with sentry_sdk.start_transaction(
            op="tasks.store.process_event",
            name="TaskProcessEvent",
            sampled=sample_process_event_apm(),
    ):
        return _do_process_event(
            cache_key=cache_key,
            start_time=start_time,
            event_id=event_id,
            process_task=process_event,
            data_has_changed=data_has_changed,
        )
Beispiel #20
0
def test_transaction_events(capture_events, init_celery, celery_invocation,
                            task_fails):
    celery = init_celery(traces_sample_rate=1.0)

    @celery.task(name="dummy_task")
    def dummy_task(x, y):
        return x / y

    # XXX: For some reason the first call does not get instrumented properly.
    celery_invocation(dummy_task, 1, 1)

    events = capture_events()

    with start_transaction(name="submission") as transaction:
        celery_invocation(dummy_task, 1, 0 if task_fails else 1)

    if task_fails:
        error_event = events.pop(0)
        assert error_event["contexts"]["trace"][
            "trace_id"] == transaction.trace_id
        assert error_event["exception"]["values"][0][
            "type"] == "ZeroDivisionError"

    execution_event, submission_event = events

    assert execution_event["transaction"] == "dummy_task"
    assert submission_event["transaction"] == "submission"

    assert execution_event["type"] == submission_event["type"] == "transaction"
    assert execution_event["contexts"]["trace"][
        "trace_id"] == transaction.trace_id
    assert submission_event["contexts"]["trace"][
        "trace_id"] == transaction.trace_id

    if task_fails:
        assert execution_event["contexts"]["trace"][
            "status"] == "internal_error"
    else:
        assert execution_event["contexts"]["trace"]["status"] == "ok"

    assert execution_event["spans"] == []
    assert submission_event["spans"] == [{
        u"description":
        u"dummy_task",
        u"op":
        "celery.submit",
        u"parent_span_id":
        submission_event["contexts"]["trace"]["span_id"],
        u"same_process_as_parent":
        True,
        u"span_id":
        submission_event["spans"][0]["span_id"],
        u"start_timestamp":
        submission_event["spans"][0]["start_timestamp"],
        u"timestamp":
        submission_event["spans"][0]["timestamp"],
        u"trace_id":
        text_type(transaction.trace_id),
    }]
Beispiel #21
0
def test_transactions(sentry_init, capture_events, render_span_tree):

    sentry_init(integrations=[SqlalchemyIntegration()],
                _experiments={"record_sql_params": True})
    events = capture_events()

    Base = declarative_base()  # noqa: N806

    class Person(Base):
        __tablename__ = "person"
        id = Column(Integer, primary_key=True)
        name = Column(String(250), nullable=False)

    class Address(Base):
        __tablename__ = "address"
        id = Column(Integer, primary_key=True)
        street_name = Column(String(250))
        street_number = Column(String(250))
        post_code = Column(String(250), nullable=False)
        person_id = Column(Integer, ForeignKey("person.id"))
        person = relationship(Person)

    engine = create_engine("sqlite:///:memory:")
    Base.metadata.create_all(engine)

    Session = sessionmaker(bind=engine)  # noqa: N806
    session = Session()

    with start_transaction(name="test_transaction", sampled=True):
        with session.begin_nested():
            session.query(Person).first()

        for _ in range(2):
            with pytest.raises(IntegrityError):
                with session.begin_nested():
                    session.add(Person(id=1, name="bob"))
                    session.add(Person(id=1, name="bob"))

        with session.begin_nested():
            session.query(Person).first()

    (event, ) = events

    assert (render_span_tree(event) == """\
- op=null: description=null
  - op="db": description="SAVEPOINT sa_savepoint_1"
  - op="db": description="SELECT person.id AS person_id, person.name AS person_name \\nFROM person\\n LIMIT ? OFFSET ?"
  - op="db": description="RELEASE SAVEPOINT sa_savepoint_1"
  - op="db": description="SAVEPOINT sa_savepoint_2"
  - op="db": description="INSERT INTO person (id, name) VALUES (?, ?)"
  - op="db": description="ROLLBACK TO SAVEPOINT sa_savepoint_2"
  - op="db": description="SAVEPOINT sa_savepoint_3"
  - op="db": description="INSERT INTO person (id, name) VALUES (?, ?)"
  - op="db": description="ROLLBACK TO SAVEPOINT sa_savepoint_3"
  - op="db": description="SAVEPOINT sa_savepoint_4"
  - op="db": description="SELECT person.id AS person_id, person.name AS person_name \\nFROM person\\n LIMIT ? OFFSET ?"
  - op="db": description="RELEASE SAVEPOINT sa_savepoint_4"\
""")
Beispiel #22
0
 def get_full_info(self, request, pk=None, *args, **kwargs):
     with start_transaction(op="task", name="articles_get_full_info"):
         queryset = Article.objects.all()
         article = get_object_or_404(queryset, pk=pk)
         author = get_object_or_404(Author, id=article.author_id)
         article_data = ArticleSerializer(article).data
         author_data = AuthorSerializer(author).data
         article_data['author'] = author_data
         return Response(article_data, status=status.HTTP_200_OK)
Beispiel #23
0
def test_only_captures_transaction_when_sampled_is_true(
        sentry_init, sampling_decision, capture_events):
    sentry_init(traces_sampler=mock.Mock(return_value=sampling_decision))
    events = capture_events()

    transaction = start_transaction(name="dogpark")
    transaction.finish()

    assert len(events) == (1 if sampling_decision else 0)
Beispiel #24
0
def test_warns_and_sets_sampled_to_false_on_invalid_traces_sampler_return_value(
    sentry_init, traces_sampler_return_value, StringContaining  # noqa: N803
):
    sentry_init(traces_sampler=mock.Mock(return_value=traces_sampler_return_value))

    with mock.patch.object(logger, "warning", mock.Mock()):
        transaction = start_transaction(name="dogpark")
        logger.warning.assert_any_call(StringContaining("Given sample rate is invalid"))
        assert transaction.sampled is False
Beispiel #25
0
def test_traces_sampler_doesnt_overwrite_explicitly_passed_sampling_decision(
        sentry_init, explicit_decision):
    # make traces_sampler pick the opposite of the explicit decision, to prove
    # that the explicit decision takes precedence
    traces_sampler = mock.Mock(return_value=not explicit_decision)
    sentry_init(traces_sampler=traces_sampler)

    transaction = start_transaction(name="dogpark", sampled=explicit_decision)
    assert transaction.sampled is explicit_decision
Beispiel #26
0
    def __call__(self, function_name, **kws):
        with push_scope() as scope:
            transaction_name = "{0}  ||  {1}".format(
                mlconfig.MLCHAIN_SERVER_NAME, function_name)
            scope.transaction = transaction_name

            with start_transaction(op="task", name=transaction_name):
                uid = self.init_context()

                request_context = {'api_version': self.server.version}
                try:
                    headers, form, files, data = self.parse_data()
                    mlchain_context['REQUESTS_HEADERS'] = headers
                    mlchain_context['REQUESTS_FORM'] = form
                    mlchain_context['REQUESTS_FILES'] = files
                    mlchain_context['REQUESTS_DATA'] = data

                except Exception as ex:
                    request_context['time_process'] = 0
                    output = self.normalize_output(self.base_format,
                                                   function_name, {}, None, ex,
                                                   request_context)
                    return self.make_response(output)

                formatter = self.get_format(headers, form, files, data)
                start_time = time.time()
                try:
                    if self.authentication is not None:
                        self.authentication.check(headers)
                    args, kwargs = formatter.parse_request(
                        function_name, headers, form, files, data,
                        request_context)
                    func = self.server.model.get_function(function_name)
                    kwargs = self.server.get_kwargs(func, *args, **kwargs)
                    kwargs = self.server._normalize_kwargs_to_valid_format(
                        kwargs, func)

                    uid = self.init_context_with_headers(headers, uid)
                    scope.set_tag("transaction_id", uid)
                    logger.debug("Mlchain transaction id: {0}".format(uid))

                    output = self.server.model.call_function(
                        function_name, uid, **kwargs)
                    exception = None
                except MlChainError as ex:
                    exception = ex
                    output = None
                except Exception as ex:
                    exception = ex
                    output = None

                time_process = time.time() - start_time
                request_context['time_process'] = time_process
                output = self.normalize_output(formatter, function_name,
                                               headers, output, exception,
                                               request_context)
                return self.make_response(output)
Beispiel #27
0
        def _transaction_wrapper(*fargs, **fkwargs):
            if not sentry_available:
                if pass_transaction:
                    fkwargs["transaction"] = Mock()
                return function(*fargs, **fkwargs)

            with start_transaction(**kwargs) as transaction:
                if pass_transaction:
                    fkwargs["transaction"] = transaction
                return function(*fargs, **fkwargs)
Beispiel #28
0
def test_ignores_inherited_sample_decision_when_traces_sampler_defined(
        sentry_init, parent_sampling_decision):
    # make traces_sampler pick the opposite of the inherited decision, to prove
    # that traces_sampler takes precedence
    traces_sampler = mock.Mock(return_value=not parent_sampling_decision)
    sentry_init(traces_sampler=traces_sampler)

    transaction = start_transaction(name="dogpark",
                                    parent_sampled=parent_sampling_decision)
    assert transaction.sampled is not parent_sampling_decision
Beispiel #29
0
def test_get_transaction_and_span_from_scope_regardless_of_sampling_decision(
        sentry_init, sampling_decision):
    sentry_init(traces_sample_rate=1.0)

    with start_transaction(name="/", sampled=sampling_decision):
        with start_span(op="child-span"):
            with start_span(op="child-child-span"):
                scope = Hub.current.scope
                assert scope.span.op == "child-child-span"
                assert scope.transaction.name == "/"
Beispiel #30
0
def test_no_double_sampling(sentry_init, capture_events):
    # Transactions should not be subject to the global/error sample rate.
    # Only the traces_sample_rate should apply.
    sentry_init(traces_sample_rate=1.0, sample_rate=0.0)
    events = capture_events()

    with start_transaction(name="/"):
        pass

    assert len(events) == 1