class SentryReporter(object): def __init__(self, sentry_dsn, **unused): if Client is None: raise RavenNotAvailable('Raven is not installed, maybe run "pip install raven"') self.client = Client(sentry_dsn) def report(self, traceback): environ = traceback.context.get('environ', {}) data = { 'sentry.interfaces.Http': { 'method': environ.get('REQUEST_METHOD'), 'url': get_current_url(environ, strip_querystring=True), 'query_string': environ.get('QUERY_STRING'), # TODO # 'data': environ.get('wsgi.input'), 'headers': dict(get_headers(environ)), 'env': dict(get_environ(environ)), } } is_backlash_event = getattr(traceback.exc_value, 'backlash_event', False) if is_backlash_event: # Just a Stack Dump request from backlash self.client.captureMessage(traceback.exception, data=data, stack=traceback.frames) else: # This is a real crash self.client.captureException(data=data)
def test_build_then_send(self): c = Client( dsn="mock://*****:*****@localhost:8143/1", name="test_server") mydate = datetime.datetime(2012, 5, 4, tzinfo=pytz.utc) d = calendar.timegm(mydate.timetuple()) msg = c.build_msg('raven.events.Message', message='foo', date=d) expected = { 'project': '1', 'sentry.interfaces.Message': { 'message': 'foo', 'params': (), 'formatted': None, }, 'server_name': 'test_server', 'level': 40, 'tags': {}, 'time_spent': None, 'timestamp': 1336089600, 'message': 'foo', } # The event_id is always overridden del msg['event_id'] self.assertDictContainsSubset(expected, msg)
def test_build_then_send(self): c = Client(dsn="mock://*****:*****@localhost:8143/1", name="test_server") mydate = datetime.datetime(2012, 5, 4, tzinfo=pytz.utc) d = calendar.timegm(mydate.timetuple()) msg = c.build_msg("Message", message='foo', date=d) expected = { 'project': '1', 'public_key': 'some_username', 'sentry.interfaces.Message': {'message': 'foo', 'params': ()}, 'server_name': u'test_server', 'level': 40, 'checksum': 'acbd18db4cc2f85cedef654fccc4a4d8', 'modules': {}, 'site': None, 'tags': None, 'time_spent': None, 'timestamp': 1336089600, 'message': 'foo', } # The event_id is always overridden del msg['event_id'] self.assertDictContainsSubset(expected, msg)
def test_send(self, fake_client): url = "https://*****:*****@host:1234/1" timeout = 1 verify_ssl = 1 ca_certs = "/some/path/somefile" fake = fake_client.return_value raven_client = Client( dsn="tornado+{0}?timeout={1}&verify_ssl={2}&ca_certs={3}". format(url, timeout, verify_ssl, ca_certs)) raven_client.captureMessage(message="test") # make sure an instance of HTTPClient was created, since we are not in # an IOLoop fake_client.assert_called_once_with() fake_fetch = fake.fetch # make sure we called fetch() which does the sending self.assertEqual(fake_fetch.call_count, 1) # only verify the special kwargs that we should be passing through, # no need to verify the urls and whatnot args, kwargs = fake_fetch.call_args self.assertEqual(kwargs["connect_timeout"], timeout) self.assertEqual(kwargs["validate_cert"], bool(verify_ssl)) self.assertEqual(kwargs["ca_certs"], ca_certs)
def test_build_then_send(self): try: Client.register_scheme('mock', DummyScheme) except: pass c = Client(dsn="mock://*****:*****@localhost:8143/1", name="test_server") mydate = datetime.datetime(2012, 5, 4, tzinfo=pytz.utc) d = calendar.timegm(mydate.timetuple()) msg = c.build_msg("Message", message='foo', date=d) expected = {'project': '1', 'sentry.interfaces.Message': {'message': 'foo', 'params': ()}, 'server_name': u'test_server', 'level': 40, 'checksum': 'acbd18db4cc2f85cedef654fccc4a4d8', 'extra': {}, 'modules': {}, 'site': None, 'time_spent': None, 'timestamp': 1336089600, 'message': 'foo'} # The event_id is always overridden del msg['event_id'] self.assertEquals(msg, expected)
def test_build_then_send(self): try: Client.register_scheme('mock', DummyScheme) except: pass c = Client(dsn="mock://*****:*****@localhost:8143/1") d = time.mktime(datetime.datetime(2012,5,4).timetuple()) msg = c.build_msg("Message", message='foo', date=d) expected = {'project': '1', 'sentry.interfaces.Message': {'message': 'foo', 'params': ()}, 'server_name': u'Victors-MacBook-Air.local', 'level': 40, 'checksum': 'acbd18db4cc2f85cedef654fccc4a4d8', 'extra': {}, 'modules': {}, 'site': None, 'time_spent': None, 'timestamp': 1336104000.0, 'message': 'foo'} # The event_id is always overridden del msg['event_id'] assert msg == expected
def test_async_send_remote_failover(self, should_try, get_transport): should_try.return_value = True async_transport = AsyncTransport() async_transport.async_send = async_send = mock.Mock() get_transport.return_value = async_transport client = Client( dsn='http://*****:*****@example.com/1', ) # test immediate raise of error async_send.side_effect = Exception() client.send_remote('http://example.com/api/1/store/', client.encode({})) self.assertEquals(client.state.status, client.state.ERROR) # test recovery client.send_remote('http://example.com/api/1/store/', client.encode({})) success_cb = async_send.call_args[0][3] success_cb() self.assertEquals(client.state.status, client.state.ONLINE) # test delayed raise of error client.send_remote('http://example.com/api/1/store/', client.encode({})) failure_cb = async_send.call_args[0][4] failure_cb(Exception()) self.assertEquals(client.state.status, client.state.ERROR)
class ThreadedTransportTest(TestCase): def setUp(self): self.url = "threaded+requests+http://some_username:some_password@localhost:8143/1" self.client = Client(dsn=self.url) @mock.patch('raven.transport.requests.post') def test_does_send(self, send): self.client.captureMessage(message='foo') time.sleep(0.1) self.assertEqual(send.call_count, 1) expected_url = 'http://localhost:8143/api/1/store/' self.assertEqual(expected_url, send.call_args[0][0]) def test_shutdown_waits_for_send(self): url = urlparse(self.url) transport = DummyThreadedScheme(url) transport.send_delay = 0.5 data = self.client.build_msg('raven.events.Message', message='foo') transport.async_send(data, None, None, None) time.sleep(0.1) # this should wait for the message to get sent transport.get_worker().main_thread_terminated() self.assertEqual(len(transport.events), 1)
def test_build_then_send(self): c = Client(dsn="mock://*****:*****@localhost:8143/1", name="test_server") mydate = datetime.datetime(2012, 5, 4, tzinfo=pytz.utc) d = calendar.timegm(mydate.timetuple()) msg = c.build_msg("Message", message="foo", date=d) expected = { "project": "1", "public_key": "some_username", "sentry.interfaces.Message": {"message": "foo", "params": ()}, "server_name": u"test_server", "level": 40, "checksum": "acbd18db4cc2f85cedef654fccc4a4d8", "extra": {}, "modules": {}, "site": None, "tags": None, "time_spent": None, "timestamp": 1336089600, "message": "foo", } # The event_id is always overridden del msg["event_id"] self.assertEquals(msg, expected)
class ThreadedTransportTest(TestCase): def setUp(self): self.url = "threaded+http://some_username:some_password@localhost:8143/1" self.client = Client(dsn=self.url) @mock.patch('raven.transport.http.HTTPTransport.send') def test_does_send(self, send): self.client.captureMessage(message='foo') time.sleep(0.1) # TODO: This test could be more precise by ensuring it's sending the same params that are sent # to the ThreadedHTTPTransport.send() method self.assertEqual(send.call_count, 1) def test_shutdown_waits_for_send(self): url = urlparse(self.url) transport = DummyThreadedScheme(url) transport.send_delay = 0.5 data = self.client.build_msg('raven.events.Message', message='foo') transport.async_send(data, None, None, None) time.sleep(0.1) # this should wait for the message to get sent transport.get_worker().main_thread_terminated() self.assertEqual(len(transport.events), 1)
def test_custom_transport(self): c = Client(dsn="mock://*****:*****@localhost:8143/1") data = dict(a=42, b=55, c=list(range(50))) c.send(**data) expected_message = c.encode(data) self.assertIn('mock://localhost:8143/api/1/store/', Client._registry._transports) mock_cls = Client._registry._transports['mock://localhost:8143/api/1/store/'] assert mock_cls._data == expected_message
class ServerTest(TestCase): def setUp(self): self.raven = Client(include_paths=['tests']) def test_text(self): message_id, checksum = self.raven.create_from_text('hello') self.assertEquals(GroupedMessage.objects.count(), 1) self.assertEquals(Message.objects.count(), 1) message = Message.objects.get() self.assertEquals(message.message_id, message_id) self.assertEquals(message.checksum, checksum) self.assertEquals(message.message, 'hello') self.assertEquals(message.logger, 'root') self.assertEquals(message.level, logging.ERROR) data = message.data self.assertTrue('__sentry__' in data) self.assertTrue('versions' in data['__sentry__']) self.assertTrue('tests' in data['__sentry__']['versions']) self.assertEquals(data['__sentry__']['versions']['tests'], '1.0') def test_exception(self): try: raise ValueError('hello') except: pass else: self.fail('Whatttt?') message_id, checksum = self.raven.create_from_exception() self.assertEquals(GroupedMessage.objects.count(), 1) self.assertEquals(Message.objects.count(), 1) message = Message.objects.get() self.assertEquals(message.message_id, message_id) self.assertEquals(message.checksum, checksum) self.assertEquals(message.class_name, 'ValueError') self.assertEquals(message.message, 'hello') self.assertEquals(message.logger, 'root') self.assertEquals(message.level, logging.ERROR) data = message.data self.assertTrue('__sentry__' in data) self.assertTrue('versions' in data['__sentry__']) self.assertTrue('tests' in data['__sentry__']['versions']) self.assertEquals(data['__sentry__']['versions']['tests'], '1.0') self.assertTrue('frames' in data['__sentry__']) self.assertEquals(len(data['__sentry__']['frames']), 1) frame = data['__sentry__']['frames'][0] self.assertEquals(frame['function'], 'test_exception') self.assertEquals(frame['module'], __name__) self.assertEquals(frame['filename'], __file__) self.assertTrue('exception' in data['__sentry__']) exception = data['__sentry__']['exception'] self.assertTrue(len(exception), 1) self.assertEquals(exception[0], '__builtin__') self.assertEquals(exception[1], ('hello',))
def __init__(self, *args, **kwargs): if len(args) == 1: self.client = args[0] elif 'client' in kwargs: self.client = kwargs['client'] elif len(args) == 2 and not kwargs: servers, key = args self.client = Client(servers=servers, key=key) else: self.client = Client(*args, **kwargs) logging.Handler.__init__(self)
class RequestsTransportTest(TestCase): def setUp(self): self.client = Client( dsn="requests+http://some_username:some_password@localhost:8143/1", ) @mock.patch('raven.transport.requests.post') def test_does_send(self, post): self.client.captureMessage(message='foo') self.assertEqual(post.call_count, 1) expected_url = 'http://localhost:8143/api/1/store/' self.assertEqual(expected_url, post.call_args[0][0])
def test_send_with_auth_header(self, time, send_remote): time.return_value = 1328055286.51 client = Client(servers=["http://example.com"], public_key="public", secret_key="secret", project=1) client.send(auth_header="foo", **{"foo": "bar"}) send_remote.assert_called_once_with( url="http://example.com", data="eJyrVkrLz1eyUlBKSixSqgUAIJgEVA==", headers={ "User-Agent": "raven-python/%s" % (raven.VERSION,), "Content-Type": "application/octet-stream", "X-Sentry-Auth": "foo", }, )
def test_send_remote_failover(self, should_try, send): should_try.return_value = True client = Client(servers=["http://example.com"], public_key="public", secret_key="secret", project=1) # test error send.side_effect = Exception() client.send_remote("http://example.com/api/store", "foo") self.assertEquals(client.state.status, client.state.ERROR) # test recovery send.side_effect = None client.send_remote("http://example.com/api/store", "foo") self.assertEquals(client.state.status, client.state.ONLINE)
def test_send_with_auth_header(self, time, send_remote): time.return_value = 1328055286.51 client = Client(dsn="http://*****:*****@example.com/1") client.send(auth_header="foo", **{"foo": "bar"}) send_remote.assert_called_once_with( url="http://example.com/api/1/store/", data=client.encode({"foo": "bar"}), headers={ "User-Agent": "raven-python/%s" % (raven.VERSION,), "Content-Type": "application/octet-stream", "Content-Encoding": client.get_content_encoding(), "X-Sentry-Auth": "foo", }, )
class ClientUDPTest(TestCase): def setUp(self): self.server_socket = socket(AF_INET, SOCK_DGRAM) self.server_socket.bind(('127.0.0.1', 0)) self.client = Client(servers=["udp://%s:%s" % self.server_socket.getsockname()], key='BassOmatic') def test_delivery(self): self.client.create_from_text('test') data, address = self.server_socket.recvfrom(2**16) self.assertTrue("\n\n" in data) header, payload = data.split("\n\n") for substring in ("sentry_timestamp=", "sentry_client=", "sentry_signature="): self.assertTrue(substring in header) def tearDown(self): self.server_socket.close()
def includeme(config): from raven.base import Client from raven.utils.wsgi import get_current_url, get_headers, \ get_environ settings = config.registry.settings client_config = {} for key in settings: if key.startswith('raven.'): client_config[key[6:]] = settings[key] client = Client(**client_config) config.registry.raven = client client.get_current_url = get_current_url client.get_headers = get_headers client.get_environ = get_environ
class ThreadedTransportTest(TestCase): def setUp(self): self.client = Client( dsn="threaded+http://some_username:some_password@localhost:8143/1", ) @mock.patch('raven.transport.http.HTTPTransport.send') def test_does_send(self, send): self.client.captureMessage(message='foo') time.sleep(0.1) # TODO: This test could be more precise by ensuring it's sending the same params that are sent # to the ThreadedHTTPTransport.send() method self.assertEqual(send.call_count, 1)
def test_send_remote_failover(self, should_try, send): should_try.return_value = True client = Client( dsn='sync+http://public:[email protected]/1' ) # test error send.side_effect = Exception() client.send_remote('sync+http://example.com/api/store', 'foo') self.assertEquals(client.state.status, client.state.ERROR) # test recovery send.side_effect = None client.send_remote('sync+http://example.com/api/store', 'foo') self.assertEquals(client.state.status, client.state.ONLINE)
def test_send_with_auth_header(self, time, send_remote): time.return_value = 1328055286.51 client = Client( dsn='http://*****:*****@example.com/1', ) client.send(auth_header='foo', **{ 'foo': 'bar', }) send_remote.assert_called_once_with( url='http://example.com/api/1/store/', data=six.b('eJyrVkrLz1eyUlBKSixSqgUAIJgEVA=='), headers={ 'User-Agent': 'raven-python/%s' % (raven.VERSION,), 'Content-Type': 'application/octet-stream', 'X-Sentry-Auth': 'foo' }, )
def test_custom_transport(self): c = Client(dsn="mock://*****:*****@localhost:8143/1") data = dict(a=42, b=55, c=list(range(50))) c.send(**data) mock_cls = c._transport_cache['mock://*****:*****@localhost:8143/1'].get_transport() expected_message = zlib.decompress(c.encode(data)) actual_message = zlib.decompress(mock_cls._data) # These loads()/dumps() pairs order the dict keys before comparing the string. # See GH504 self.assertEqual( json.dumps(json.loads(expected_message.decode('utf-8')), sort_keys=True), json.dumps(json.loads(actual_message.decode('utf-8')), sort_keys=True) )
def setUp(self): gevent.monkey.patch_socket() self.addCleanup(reload, socket) gevent.monkey.patch_time() self.addCleanup(reload, time) self.client = Client( dsn="gevent+http://some_username:some_password@localhost:8143/1", )
def test_async_send_remote_failover(self, should_try, get_transport): should_try.return_value = True async_transport = AsyncTransport() async_transport.async_send = async_send = mock.Mock() get_transport.return_value = async_transport client = Client( servers=['http://example.com'], public_key='public', secret_key='secret', project=1, ) # test immediate raise of error async_send.side_effect = Exception() client.send_remote('http://example.com/api/store', 'foo') self.assertEquals(client.state.status, client.state.ERROR) # test recovery client.send_remote('http://example.com/api/store', 'foo') success_cb = async_send.call_args[0][2] success_cb() self.assertEquals(client.state.status, client.state.ONLINE) # test delayed raise of error client.send_remote('http://example.com/api/store', 'foo') failure_cb = async_send.call_args[0][3] failure_cb(Exception()) self.assertEquals(client.state.status, client.state.ERROR)
def test_send_with_auth_header(self, time, send_remote): time.return_value = 1328055286.51 client = Client( dsn='http://*****:*****@example.com/1', ) client.send(auth_header='foo', **{ 'foo': 'bar', }) send_remote.assert_called_once_with( url='http://example.com/api/1/store/', data=client.encode({'foo': 'bar'}), headers={ 'User-Agent': 'raven-python/%s' % (raven.VERSION,), 'Content-Type': 'application/octet-stream', 'Content-Encoding': client.get_content_encoding(), 'X-Sentry-Auth': 'foo', }, )
def test_custom_transport(self): c = Client(dsn="mock://*****:*****@localhost:8143/1") data = dict(a=42, b=55, c=list(range(50))) c.send(**data) expected_message = zlib.decompress(base64.b64decode(c.encode(data))) self.assertIn('mock://localhost:8143/api/1/store/', Client._registry._transports) mock_cls = Client._registry._transports['mock://localhost:8143/api/1/store/'] actual_message = zlib.decompress(base64.b64decode(mock_cls._data)) # These loads()/dumps() pairs order the dict keys before comparing the string. # See GH504 self.assertEqual( json.dumps(json.loads(expected_message.decode('utf-8')), sort_keys=True), json.dumps(json.loads(actual_message.decode('utf-8')), sort_keys=True) )
class GeventTransportTest(TestCase): def setUp(self): gevent.monkey.patch_socket() self.addCleanup(reload, socket) gevent.monkey.patch_time() self.addCleanup(reload, time) self.client = Client( dsn="gevent+http://some_username:some_password@localhost:8143/1", ) @mock.patch.object(GeventedHTTPTransport, '_done') @mock.patch('raven.transport.http.HTTPTransport.send') def test_does_send(self, send, done): self.client.captureMessage(message='foo') time.sleep(0) self.assertEqual(send.call_count, 1) time.sleep(0) self.assertEquals(done.call_count, 1)
def run(self): in_heroku = 'SENTRY_DSN' in os.environ if in_heroku: client = Client(dsn=os.environ['SENTRY_DSN']) while True: try: logger.info("Worker awaiting data from %s" % self.queue) message = self.get_next_message() logger.info("Worker received a message %s from %s" % (message[0], self.queue)) depickled = pickle.loads(message[1]) logger.info("Depickled data: %s" % depickled) self.send_to_workers(depickled) except Exception: if in_heroku: client.captureException() raise
def test_send_remote_failover(self, should_try, send_remote): should_try.return_value = True client = Client( servers=['http://example.com'], public_key='public', secret_key='secret', project=1, ) # test error send_remote.side_effect = Exception() client.send_remote('http://example.com/api/store', 'foo') self.assertEquals(client.state.status, client.state.ERROR) # test recovery send_remote.side_effect = None client.send_remote('http://example.com/api/store', 'foo') self.assertEquals(client.state.status, client.state.ONLINE)
def setUp(self): self.server_socket = socket(AF_INET, SOCK_DGRAM) self.server_socket.bind(('127.0.0.1', 0)) self.client = Client( servers=["udp://%s:%s" % self.server_socket.getsockname()], key='BassOmatic')
class ThreadedTransportTest(TestCase): def setUp(self): self.url = "threaded+http://some_username:some_password@localhost:8143/1" self.client = Client(dsn=self.url) @mock.patch('raven.transport.http.HTTPTransport.send') def test_does_send(self, send): self.client.captureMessage(message='foo') time.sleep(0.1) # TODO: This test could be more precise by ensuring it's sending the same params that are sent # to the ThreadedHTTPTransport.send() method self.assertEqual(send.call_count, 1) def test_shutdown_waits_for_send(self): url = urlparse(self.url) transport = DummyThreadedScheme(url) transport.send_delay = 0.5 data = self.client.build_msg('raven.events.Message', message='foo') transport.async_send(data, None, None, None) time.sleep(0.1) # this should wait for the message to get sent transport.get_worker().main_thread_terminated() self.assertEqual(len(transport.events), 1) def test_fork_spawns_anew(self): url = urlparse(self.url) transport = DummyThreadedScheme(url) transport.send_delay = 0.5 data = self.client.build_msg('raven.events.Message', message='foo') pid = os.fork() if pid == 0: time.sleep(0.1) transport.async_send(data, None, None, None) # this should wait for the message to get sent transport.get_worker().main_thread_terminated() self.assertEqual(len(transport.events), 1) # Use os._exit here so that py.test gets not confused about # what the hell we're doing here. os._exit(0) else: os.waitpid(pid, 0) def test_fork_with_active_worker(self): # Test threaded transport when forking with an active worker. # Forking a process doesn't clone the worker thread - make sure # logging from both processes still works. event1 = self.client.build_msg('raven.events.Message', message='parent') event2 = self.client.build_msg('raven.events.Message', message='child') url = urlparse(self.url) fd, filename = mkstemp() try: os.close(fd) transport = LoggingThreadedScheme(filename, url) # Log from the parent process - starts the worker thread transport.async_send(event1, None, None, None) childpid = os.fork() if childpid == 0: # Log from the child process transport.async_send(event2, None, None, None) # Ensure threaded worker has finished transport.get_worker().stop() os._exit(0) # Wait for the child process to finish os.waitpid(childpid, 0) assert os.path.isfile(filename) # Ensure threaded worker has finished transport.get_worker().stop() with open(filename, 'r') as logfile: events = dict(x.strip().split() for x in logfile.readlines()) # Check parent and child both logged successfully assert events == { str(os.getpid()): 'parent', str(childpid): 'child', } finally: os.remove(filename)
def setUp(self): try: Client.register_scheme('mock', DummyScheme) except: pass
def test_slug_in_dsn(self): client = Client('http://*****:*****@example.com/slug-name') self.assertEquals(client.servers, ['http://example.com/api/store/']) self.assertEquals(client.project, 'slug-name') self.assertEquals(client.public_key, 'public') self.assertEquals(client.secret_key, 'secret')
def __init__(self, hide_zerorpc_frames=True, client=None, **kwargs): self._sentry_client = client or Client(**kwargs) self._hide_zerorpc_frames = hide_zerorpc_frames
def test_dsn_as_first_arg(self): client = Client('http://*****:*****@example.com/1') self.assertEquals(client.servers, ['http://example.com/api/store/']) self.assertEquals(client.project, '1') self.assertEquals(client.public_key, 'public') self.assertEquals(client.secret_key, 'secret')
def setUp(self): self.url = "threaded+http://some_username:some_password@localhost:8143/1" self.client = Client(dsn=self.url)
def test_get_public_dsn(self): client = Client('http://*****:*****@example.com/1') public_dsn = client.get_public_dsn() self.assertEquals(public_dsn, '//[email protected]/1')
def __init__(self, *args, **kwargs): install_sql_hook = kwargs.pop('install_sql_hook', True) Client.__init__(self, *args, **kwargs) if install_sql_hook: self.install_sql_hook()
def sentry_filter_factory(app, global_conf, **kwargs): client = Client(**kwargs) return Sentry(app, client)
def test_async_send_remote_failover(self, should_try, get_transport): should_try.return_value = True async_transport = AsyncTransport() async_transport.async_send = async_send = mock.Mock() get_transport.return_value = async_transport client = Client(dsn='http://*****:*****@example.com/1', ) # test immediate raise of error async_send.side_effect = Exception() client.send_remote('http://example.com/api/1/store/', client.encode({})) self.assertEquals(client.state.status, client.state.ERROR) # test recovery client.send_remote('http://example.com/api/1/store/', client.encode({})) success_cb = async_send.call_args[0][3] success_cb() self.assertEquals(client.state.status, client.state.ONLINE) # test delayed raise of error client.send_remote('http://example.com/api/1/store/', client.encode({})) failure_cb = async_send.call_args[0][4] failure_cb(Exception()) self.assertEquals(client.state.status, client.state.ERROR)