Ejemplo n.º 1
0
    def send(self, data, headers, timeout=None):
        response = None

        # ensure headers are byte strings
        headers = {
            k.encode("ascii") if isinstance(k, compat.text_type) else k:
            v.encode("ascii") if isinstance(v, compat.text_type) else v
            for k, v in headers.items()
        }
        if compat.PY2 and isinstance(self._url, compat.text_type):
            url = self._url.encode("utf-8")
        else:
            url = self._url
        try:
            try:
                response = self.http.urlopen("POST",
                                             url,
                                             body=data,
                                             headers=headers,
                                             timeout=timeout,
                                             preload_content=False)
                logger.info("Sent request, url=%s size=%.2fkb status=%s", url,
                            len(data) / 1024.0, response.status)
            except Exception as e:
                print_trace = True
                if isinstance(e, MaxRetryError) and isinstance(
                        e.reason, TimeoutError):
                    message = "Connection to APM Server timed out " "(url: %s, timeout: %s seconds)" % (
                        self._url,
                        timeout,
                    )
                    print_trace = False
                else:
                    message = "Unable to reach APM Server: %s (url: %s)" % (
                        e, self._url)
                raise TransportException(message,
                                         data,
                                         print_trace=print_trace)
            body = response.read()
            if response.status >= 400:
                if response.status == 429:  # rate-limited
                    message = "Temporarily rate limited: "
                    print_trace = False
                else:
                    message = "HTTP %s: " % response.status
                    print_trace = True
                message += body.decode("utf8")
                raise TransportException(message,
                                         data,
                                         print_trace=print_trace)
            return response.getheader("Location")
        finally:
            if response:
                response.close()
Ejemplo n.º 2
0
    async def send(self, data, headers, timeout):
        from elasticapm.transport.base import TransportException

        self.data = data
        if self.url == urlparse("http://error"):
            raise TransportException("", data, False)
        await asyncio.sleep(0.0001)
Ejemplo n.º 3
0
    def test_send_remote_failover_async(self, should_try, http_send):
        should_try.return_value = True

        client = Client(
            servers=['http://example.com'],
            app_name='app_name',
            secret_token='secret',
            async_mode=True,
        )
        logger = mock.Mock()
        client.error_logger.error = logger

        # test error
        encoded_data = client.encode({'message': 'oh no'})
        http_send.side_effect = TransportException('oopsie', encoded_data)
        client.send_remote('http://example.com/api/store', data=encoded_data)
        client.close()
        assert client.state.status == client.state.ERROR
        assert len(logger.call_args_list) == 2
        assert 'oopsie' in logger.call_args_list[0][0][0]
        assert 'oh no' in logger.call_args_list[1][0][1]

        # test recovery
        http_send.side_effect = None
        client.send_remote('http://example.com/api/store', 'foo')
        client.close()
        assert client.state.status == client.state.ONLINE
Ejemplo n.º 4
0
 def send(self, data, headers, timeout=None):
     if timeout is None:
         timeout = defaults.TIMEOUT
     response = None
     try:
         try:
             response = self.http.urlopen('POST',
                                          self._url,
                                          body=data,
                                          headers=headers,
                                          timeout=timeout)
         except Exception as e:
             print_trace = True
             if isinstance(e, MaxRetryError) and isinstance(
                     e.reason, TimeoutError):
                 message = ("Connection to APM Server timed out "
                            "(url: %s, timeout: %d seconds)" %
                            (self._url, timeout))
                 print_trace = False
             else:
                 message = 'Unable to reach APM Server: %s (url: %s)' % (
                     e, self._url)
             raise TransportException(message,
                                      data,
                                      print_trace=print_trace)
         body = response.read()
         if response.status >= 400:
             if response.status == 429:  # rate-limited
                 message = 'Temporarily rate limited: '
                 print_trace = False
             else:
                 message = 'HTTP %s: ' % response.status
                 print_trace = True
             message += body.decode('utf8')
             raise TransportException(message,
                                      data,
                                      print_trace=print_trace)
         return response.getheader('Location')
     finally:
         if response:
             response.close()
Ejemplo n.º 5
0
def test_sync_transport_fail_and_recover(mock_send, caplog):
    mock_send.side_effect = TransportException("meh")
    transport = Transport()
    transport.queue("x", {}, flush=True)
    assert transport.state.did_fail()
    # first retry should be allowed immediately
    assert transport.state.should_try()

    # recover
    mock_send.side_effect = None
    transport.queue("x", {}, flush=True)
    assert not transport.state.did_fail()
Ejemplo n.º 6
0
def test_sync_transport_fail_and_recover(mock_send, caplog):
    transport = Transport(client=None)
    transport.start_thread()
    try:
        mock_send.side_effect = TransportException("meh")
        transport.queue("x", {})
        transport.flush()
        assert transport.state.did_fail()
        # first retry should be allowed immediately
        assert transport.state.should_try()

        # recover
        mock_send.side_effect = None
        transport.queue("x", {})
        transport.flush()
        assert not transport.state.did_fail()
    finally:
        transport.close()
Ejemplo n.º 7
0
    def send(self, data, headers, timeout=None):
        """
        Sends a request to a remote webserver using HTTP POST.

        Returns the shortcut URL of the recorded error on Elastic APM
        """
        req = Request(self._url, headers=headers)
        if timeout is None:
            timeout = defaults.TIMEOUT
        response = None
        try:
            try:
                response = urlopen(req, data, timeout)
            except TypeError:
                response = urlopen(req, data)
        except Exception as e:
            print_trace = True
            if isinstance(e, socket.timeout):
                message = ("Connection to APM Server timed out "
                           "(url: %s, timeout: %d seconds)" %
                           (self._url, timeout))
            elif isinstance(e, HTTPError):
                body = e.read()
                if e.code == 429:  # rate-limited
                    message = 'Temporarily rate limited: '
                    print_trace = False
                else:
                    message = 'Unable to reach APM Server: '
                message += '%s (url: %s, body: %s)' % (e, self._url, body)
            else:
                message = 'Unable to reach APM Server: %s (url: %s)' % (
                    e, self._url)
            raise TransportException(message, data, print_trace=print_trace)
        finally:
            if response:
                response.close()

        return response.info().get('Location')