示例#1
0
 def send_metrics(self, project_id, payload, timestamp=None):
     envelope = Envelope()
     envelope.add_item(
         Item(
             payload=PayloadRef(bytes=payload.encode()),
             type="metrics",
             headers=None if timestamp is None else {"timestamp": timestamp},
         )
     )
     self.send_envelope(project_id, envelope)
示例#2
0
def test_drop_unknown_item(mini_sentry, relay):
    relay = relay(mini_sentry, {"routing": {"accept_unknown_items": False}})
    PROJECT_ID = 42
    mini_sentry.add_basic_project_config(PROJECT_ID)

    envelope = Envelope()
    envelope.add_item(
        Item(payload=PayloadRef(bytes=b"something"), type="invalid_unknown")
    )
    relay.send_envelope(PROJECT_ID, envelope)

    # there is nothing sent to the upstream
    with pytest.raises(queue.Empty):
        mini_sentry.captured_events.get(timeout=1)
示例#3
0
def test_unknown_item(mini_sentry, relay):
    relay = relay(mini_sentry)
    PROJECT_ID = 42
    mini_sentry.add_basic_project_config(PROJECT_ID)

    envelope = Envelope()
    envelope.add_item(
        Item(payload=PayloadRef(bytes=b"something"), type="invalid_unknown")
    )
    relay.send_envelope(PROJECT_ID, envelope)

    envelope = mini_sentry.captured_events.get(timeout=1)
    assert len(envelope.items) == 1
    assert envelope.items[0].type == "invalid_unknown"
示例#4
0
def test_multi_item_envelope(mini_sentry, relay, rule_type, event_factory):
    """
    Associated items are removed together with event item.

    The event is sent twice to account for both fast and slow paths.

    When sampling decides to remove a transaction it should also remove all
    dependent items (attachments).
    """
    project_id = 42
    relay = relay(mini_sentry, _outcomes_enabled_config())

    # create a basic project config
    config = mini_sentry.add_basic_project_config(project_id)
    # add a sampling rule to project config that removes all transactions (sample_rate=0)
    public_key = config["publicKeys"][0]["publicKey"]

    # add a sampling rule to project config that drops all events (sample_rate=0), it should be ignored
    # because there is an invalid rule in the configuration
    _add_sampling_config(config, sample_rate=0, rule_type=rule_type)

    for i in range(2):
        # create an envelope with a trace context that is initiated by this project (for simplicity)
        envelope = Envelope()
        # create an envelope with a trace context that is initiated by this project (for simplicity)
        envelope, trace_id, event_id = event_factory(public_key)
        envelope.add_item(
            Item(payload=PayloadRef(json={"x": "some attachment"}),
                 type="attachment"))
        envelope.add_item(
            Item(
                payload=PayloadRef(json={"y": "some other attachment"}),
                type="attachment",
            ))

        # send the event, the transaction should be removed.
        relay.send_envelope(project_id, envelope)
        # the event should be removed by Relay sampling
        with pytest.raises(queue.Empty):
            mini_sentry.captured_events.get(timeout=1)

        outcomes = mini_sentry.captured_outcomes.get(timeout=2)
        assert outcomes is not None
示例#5
0
 def send_client_report(self, project_id, payload):
     envelope = Envelope()
     envelope.add_item(Item(PayloadRef(json=payload), type="client_report"))
     self.send_envelope(project_id, envelope)
示例#6
0
 def send_session_aggregates(self, project_id, payload):
     envelope = Envelope()
     envelope.add_item(Item(payload=PayloadRef(json=payload), type="sessions"))
     self.send_envelope(project_id, envelope)
示例#7
0
    def capture_event(
            self,
            event,  # type: Event
            hint=None,  # type: Optional[Hint]
            scope=None,  # type: Optional[Scope]
    ):
        # type: (...) -> Optional[str]
        """Captures an event.

        :param event: A ready-made event that can be directly sent to Sentry.

        :param hint: Contains metadata about the event that can be read from `before_send`, such as the original exception object or a HTTP request object.

        :returns: An event ID. May be `None` if there is no DSN set or of if the SDK decided to discard the event for other reasons. In such situations setting `debug=True` on `init()` may help.
        """
        if disable_capture_event.get(False):
            return None

        if self.transport is None:
            return None
        if hint is None:
            hint = {}
        event_id = event.get("event_id")
        hint = dict(hint or ())  # type: Hint

        if event_id is None:
            event["event_id"] = event_id = uuid.uuid4().hex
        if not self._should_capture(event, hint, scope):
            return None

        event_opt = self._prepare_event(event, hint, scope)
        if event_opt is None:
            return None

        # whenever we capture an event we also check if the session needs
        # to be updated based on that information.
        session = scope._session if scope else None
        if session:
            self._update_session_from_event(session, event)

        attachments = hint.get("attachments")
        is_transaction = event_opt.get("type") == "transaction"

        if is_transaction or attachments:
            # Transactions or events with attachments should go to the
            # /envelope/ endpoint.
            envelope = Envelope(
                headers={
                    "event_id": event_opt["event_id"],
                    "sent_at": format_timestamp(datetime.utcnow()),
                })

            if is_transaction:
                envelope.add_transaction(event_opt)
            else:
                envelope.add_event(event_opt)

            for attachment in attachments or ():
                envelope.add_item(attachment.to_envelope_item())
            self.transport.capture_envelope(envelope)
        else:
            # All other events go to the /store/ endpoint.
            self.transport.capture_event(event_opt)
        return event_id
示例#8
0
文件: __init__.py 项目: armenzg/relay
 def send_metrics(self, project_id, payload):
     envelope = Envelope()
     envelope.add_item(
         Item(payload=PayloadRef(bytes=payload.encode()), type="metrics"))
     self.send_envelope(project_id, envelope)
示例#9
0
    def capture_event(
            self,
            event,  # type: Event
            hint=None,  # type: Optional[Hint]
            scope=None,  # type: Optional[Scope]
    ):
        # type: (...) -> Optional[str]
        """Captures an event.

        :param event: A ready-made event that can be directly sent to Sentry.

        :param hint: Contains metadata about the event that can be read from `before_send`, such as the original exception object or a HTTP request object.

        :returns: An event ID. May be `None` if there is no DSN set or of if the SDK decided to discard the event for other reasons. In such situations setting `debug=True` on `init()` may help.
        """
        if disable_capture_event.get(False):
            return None

        if self.transport is None:
            return None
        if hint is None:
            hint = {}
        event_id = event.get("event_id")
        hint = dict(hint or ())  # type: Hint

        if event_id is None:
            event["event_id"] = event_id = uuid.uuid4().hex
        if not self._should_capture(event, hint, scope):
            return None

        event_opt = self._prepare_event(event, hint, scope)
        if event_opt is None:
            return None

        # whenever we capture an event we also check if the session needs
        # to be updated based on that information.
        session = scope._session if scope else None
        if session:
            self._update_session_from_event(session, event)

        is_transaction = event_opt.get("type") == "transaction"

        if not is_transaction and not self._should_sample_error(event):
            return None

        attachments = hint.get("attachments")

        # this is outside of the `if` immediately below because even if we don't
        # use the value, we want to make sure we remove it before the event is
        # sent
        raw_tracestate = (event_opt.get("contexts",
                                        {}).get("trace",
                                                {}).pop("tracestate", ""))

        # Transactions or events with attachments should go to the /envelope/
        # endpoint.
        if is_transaction or attachments:

            headers = {
                "event_id": event_opt["event_id"],
                "sent_at": format_timestamp(datetime.utcnow()),
            }

            tracestate_data = raw_tracestate and reinflate_tracestate(
                raw_tracestate.replace("sentry=", ""))
            if tracestate_data and has_tracestate_enabled():
                headers["trace"] = tracestate_data

            envelope = Envelope(headers=headers)

            if is_transaction:
                envelope.add_transaction(event_opt)
            else:
                envelope.add_event(event_opt)

            for attachment in attachments or ():
                envelope.add_item(attachment.to_envelope_item())
            self.transport.capture_envelope(envelope)
        else:
            # All other events go to the /store/ endpoint.
            self.transport.capture_event(event_opt)
        return event_id