def test_session_tracker_adds_session_object_to_queue(self):
     tracker = SessionTracker(self.config)
     tracker.auto_sessions = True
     tracker.start_session()
     self.assertEqual(len(tracker.session_counts), 1)
     for key, value in tracker.session_counts.items():
         self.assertEqual(value, 1)
Exemple #2
0
    def __init__(self, configuration=None, install_sys_hook=True, **kwargs):
        self.configuration = configuration or Configuration()
        self.session_tracker = SessionTracker(self.configuration)
        self.configuration.configure(**kwargs)

        if install_sys_hook:
            self.install_sys_hook()
 def test_session_tracker_adds_session_object_to_queue(self):
     tracker = SessionTracker(self.config)
     tracker.auto_sessions = True
     tracker.start_session()
     self.assertEqual(len(tracker.session_counts), 1)
     for key, value in tracker.session_counts.items():
         self.assertEqual(value, 1)
Exemple #4
0
    def __init__(self, configuration: Optional[Configuration] = None,
                 install_sys_hook=True, **kwargs):
        self.configuration = configuration or Configuration()  # type: Configuration  # noqa: E501
        self.session_tracker = SessionTracker(self.configuration)
        self.configuration.configure(**kwargs)

        if install_sys_hook:
            self.install_sys_hook()
 def test_session_tracker_stores_session_in_threadlocals(self):
     locs = ThreadLocals.get_instance()
     tracker = SessionTracker(self.config)
     tracker.auto_sessions = True
     tracker.start_session()
     session = locs.get_item('bugsnag-session')
     self.assertTrue('id' in session)
     self.assertTrue('startedAt' in session)
     self.assertTrue('events' in session)
     self.assertTrue('handled' in session['events'])
     self.assertTrue('unhandled' in session['events'])
     self.assertEqual(session['events']['handled'], 0)
     self.assertEqual(session['events']['unhandled'], 0)
 def test_session_tracker_stores_session_in_threadlocals(self):
     locs = ThreadLocals.get_instance()
     tracker = SessionTracker(self.config)
     tracker.auto_sessions = True
     tracker.start_session()
     session = locs.get_item('bugsnag-session')
     self.assertTrue('id' in session)
     self.assertTrue('startedAt' in session)
     self.assertTrue('events' in session)
     self.assertTrue('handled' in session['events'])
     self.assertTrue('unhandled' in session['events'])
     self.assertEqual(session['events']['handled'], 0)
     self.assertEqual(session['events']['unhandled'], 0)
Exemple #7
0
    def __init__(self, configuration=None, install_sys_hook=True, **kwargs):
        self.configuration = configuration or Configuration()
        self.session_tracker = SessionTracker(self.configuration)
        self.configuration.configure(**kwargs)

        if install_sys_hook:
            self.install_sys_hook()
 def test_session_tracker_sessions_are_unique(self):
     tracker = SessionTracker(self.config)
     tracker.auto_sessions = True
     locs = ThreadLocals.get_instance()
     tracker.start_session()
     session_one = locs.get_item('bugsnag-session').copy()
     tracker.start_session()
     session_two = locs.get_item('bugsnag-session').copy()
     self.assertNotEqual(session_one['id'], session_two['id'])
 def test_session_tracker_sessions_are_unique(self):
     tracker = SessionTracker(self.config)
     tracker.auto_sessions = True
     locs = ThreadLocals.get_instance()
     tracker.start_session()
     session_one = locs.get_item('bugsnag-session').copy()
     tracker.start_session()
     session_two = locs.get_item('bugsnag-session').copy()
     self.assertNotEqual(session_one['id'], session_two['id'])
Exemple #10
0
class TestSessionMiddleware(unittest.TestCase):
    def setUp(self):
        self.config = Configuration()
        self.config.configure(api_key='fff', auto_capture_sessions=False)
        self.sessiontracker = SessionTracker(self.config)
        self.sessiontracker.auto_sessions = True  # Stub session delivery queue

    def tearDown(self):
        pass

    def test_increment_counts(self):
        """
        Every event should keep a list of prior events which occurred in the
        session
        """
        def next_callable(event):
            pass

        middleware = SessionMiddleware(next_callable)
        self.sessiontracker.start_session()

        event = Notification(Exception('shucks'), self.config, None)
        middleware(event)

        assert event.session['events']['unhandled'] == 0
        assert event.session['events']['handled'] == 1

        event2 = Notification(Exception('oh no'), self.config, None)
        middleware(event2)

        assert event2.session['events']['unhandled'] == 0
        assert event2.session['events']['handled'] == 2

        # Session counts should not change for events already handled
        assert event.session['events']['unhandled'] == 0
        assert event.session['events']['handled'] == 1
Exemple #11
0
class Client(object):
    """
    A Bugsnag monitoring and reporting client.

    >>> client = Client(api_key='...')
    """
    def __init__(self, configuration=None, install_sys_hook=True, **kwargs):
        self.configuration = configuration or Configuration()
        self.session_tracker = SessionTracker(self.configuration)
        self.configuration.configure(**kwargs)

        if install_sys_hook:
            self.install_sys_hook()

    def capture(self, exceptions=None, **options):
        """
        Run a block of code within the clients context.
        Any exception raised will be reported to bugsnag.

        >>> with client.capture():
        >>>     raise Exception('an exception passed to bugsnag then reraised')

        The context can optionally include specific types to capture.

        >>> with client.capture((TypeError,)):
        >>>     raise Exception('an exception which does get captured')

        Alternately, functions can be decorated to capture any
        exceptions thrown during execution and reraised.

        >>> @client.capture
        >>> def foo():
        >>>     raise Exception('an exception passed to bugsnag then reraised')

        The decoration can optionally include specific types to capture.

        >>> @client.capture((TypeError,))
        >>> def foo():
        >>>     raise Exception('an exception which does not get captured')
        """

        if isinstance(exceptions, FunctionType):
            return ClientContext(self, (Exception, ))(exceptions)

        return ClientContext(self, exceptions, **options)

    def notify(self, exception, asynchronous=None, **options):
        """
        Notify bugsnag of an exception.

        >>> client.notify(Exception('Example'))
        """

        notification = Notification(exception, self.configuration,
                                    RequestConfiguration.get_instance(),
                                    **options)
        self.deliver(notification, asynchronous=asynchronous)

    def notify_exc_info(self,
                        exc_type,
                        exc_value,
                        traceback,
                        asynchronous=None,
                        **options):
        """
        Notify bugsnag of an exception via exc_info.

        >>> client.notify_exc_info(*sys.exc_info())
        """

        exception = exc_value
        options['traceback'] = traceback
        notification = Notification(exception, self.configuration,
                                    RequestConfiguration.get_instance(),
                                    **options)
        self.deliver(notification, asynchronous=asynchronous)

    def excepthook(self, exc_type, exc_value, traceback):
        if self.configuration.auto_notify:
            self.notify_exc_info(
                exc_type,
                exc_value,
                traceback,
                severity='error',
                unhandled=True,
                severity_reason={'type': 'unhandledException'})

    def install_sys_hook(self):
        self.sys_excepthook = sys.excepthook

        def excepthook(*exc_info):
            self.excepthook(*exc_info)

            if self.sys_excepthook:
                self.sys_excepthook(*exc_info)

        sys.excepthook = excepthook
        sys.excepthook.bugsnag_client = self

        if hasattr(threading, 'excepthook'):
            self.threading_excepthook = threading.excepthook

            def threadhook(args):
                self.excepthook(args[0], args[1], args[2])

                if self.threading_excepthook:
                    self.threading_excepthook(args)

            threading.excepthook = threadhook
            threading.excepthook.bugsnag_client = self

    def uninstall_sys_hook(self):
        client = getattr(sys.excepthook, 'bugsnag_client', None)

        if client is self:
            sys.excepthook = self.sys_excepthook
            self.sys_excepthook = None

        if hasattr(threading, 'excepthook'):
            client = getattr(threading.excepthook, 'bugsnag_client', None)
            if client is self:
                threading.excepthook = self.threading_excepthook
                self.threading_excepthook = None

    def deliver(self, notification, asynchronous=None):  # type: ignore
        """
        Deliver the exception notification to Bugsnag.
        """

        if not self.should_deliver(notification):
            return

        def run_middleware():
            initial_severity = notification.severity
            initial_reason = notification.severity_reason.copy()

            def send_payload():
                if asynchronous is None:
                    options = {}
                else:
                    options = {'asynchronous': asynchronous}

                if notification.api_key is None:
                    bugsnag.logger.warning(
                        "No API key configured, couldn't notify")
                    return
                if initial_severity != notification.severity:
                    notification.severity_reason = {
                        'type': 'userCallbackSetSeverity'
                    }
                else:
                    notification.severity_reason = initial_reason
                payload = notification._payload()
                try:
                    self.configuration.delivery.deliver(
                        self.configuration, payload, options)
                except Exception as e:
                    bugsnag.logger.exception('Notifying Bugsnag failed %s', e)
                # Trigger session delivery
                self.session_tracker.send_sessions()

            self.configuration.middleware.run(notification, send_payload)

        self.configuration.internal_middleware.run(notification,
                                                   run_middleware)

    def should_deliver(self, notification):  # type: (Notification) -> bool
        # Return early if we shouldn't notify for current release stage
        if not self.configuration.should_notify():
            return False

        # Return early if we should ignore exceptions of this type
        if self.configuration.should_ignore(notification.exception):
            return False

        return True

    def log_handler(self, extra_fields=None):
        return BugsnagHandler(client=self, extra_fields=extra_fields)
Exemple #12
0
 def setUp(self):
     self.config = Configuration()
     self.config.configure(api_key='fff', auto_capture_sessions=False)
     self.sessiontracker = SessionTracker(self.config)
     self.sessiontracker.auto_sessions = True  # Stub session delivery queue
Exemple #13
0
class Client(object):
    """
    A Bugsnag monitoring and reporting client.

    >>> client = Client(api_key='...')
    """

    def __init__(self, configuration=None, install_sys_hook=True, **kwargs):
        self.configuration = configuration or Configuration()
        self.session_tracker = SessionTracker(self.configuration)
        self.configuration.configure(**kwargs)

        if install_sys_hook:
            self.install_sys_hook()

    def capture(self, exceptions=None, **options):
        """
        Run a block of code within the clients context.
        Any exception raised will be reported to bugsnag.

        >>> with client.capture():
        >>>     raise Exception('an exception passed to bugsnag then reraised')

        The context can optionally include specific types to capture.

        >>> with client.capture((TypeError,)):
        >>>     raise Exception('an exception which does get captured')

        Alternately, functions can be decorated to capture any
        exceptions thrown during execution and reraised.

        >>> @client.capture
        >>> def foo():
        >>>     raise Exception('an exception passed to bugsnag then reraised')

        The decoration can optionally include specific types to capture.

        >>> @client.capture((TypeError,))
        >>> def foo():
        >>>     raise Exception('an exception which does not get captured')
        """

        if isinstance(exceptions, FunctionType):
            return ClientContext(self, (Exception,))(exceptions)

        return ClientContext(self, exceptions, **options)

    def notify(self, exception, **options):
        """
        Notify bugsnag of an exception.

        >>> client.notify(Exception('Example'))
        """

        notification = Notification(exception, self.configuration,
                                    RequestConfiguration.get_instance(),
                                    **options)
        self.deliver(notification)

    def notify_exc_info(self, exc_type, exc_value, traceback, **options):
        """
        Notify bugsnag of an exception via exc_info.

        >>> client.notify_exc_info(*sys.exc_info())
        """

        exception = exc_value
        options['traceback'] = traceback
        notification = Notification(exception, self.configuration,
                                    RequestConfiguration.get_instance(),
                                    **options)
        self.deliver(notification)

    def excepthook(self, exc_type, exc_value, traceback):
        if self.configuration.auto_notify:
            self.notify_exc_info(
                exc_type, exc_value, traceback,
                severity='error',
                unhandled=True,
                severity_reason={
                    'type': 'unhandledException'
                })

    def install_sys_hook(self):
        self.sys_excepthook = sys.excepthook

        def excepthook(*exc_info):
            self.excepthook(*exc_info)

            if self.sys_excepthook:
                self.sys_excepthook(*exc_info)

        sys.excepthook = excepthook
        sys.excepthook.bugsnag_client = self

    def uninstall_sys_hook(self):
        client = getattr(sys.excepthook, 'bugsnag_client', None)

        if client is self:
            sys.excepthook = self.sys_excepthook
            self.sys_excepthook = None

    def deliver(self, notification):  # type: (Notification) -> None
        """
        Deliver the exception notification to Bugsnag.
        """

        if not self.should_deliver(notification):
            return

        def run_middleware():
            initial_severity = notification.severity
            initial_reason = notification.severity_reason.copy()

            def send_payload():
                if notification.api_key is None:
                    bugsnag.logger.warning(
                        "No API key configured, couldn't notify")
                    return
                if initial_severity != notification.severity:
                    notification.severity_reason = {
                        'type': 'userCallbackSetSeverity'
                    }
                else:
                    notification.severity_reason = initial_reason
                payload = notification._payload()
                try:
                    self.configuration.delivery.deliver(self.configuration,
                                                        payload)
                except Exception as e:
                    bugsnag.logger.exception('Notifying Bugsnag failed %s', e)
                # Trigger session delivery
                self.session_tracker.send_sessions()

            self.configuration.middleware.run(notification, send_payload)

        self.configuration.internal_middleware.run(notification,
                                                   run_middleware)

    def should_deliver(self, notification):  # type: (Notification) -> bool
        # Return early if we shouldn't notify for current release stage
        if not self.configuration.should_notify():
            return False

        # Return early if we should ignore exceptions of this type
        if self.configuration.should_ignore(notification.exception):
            return False

        return True

    def log_handler(self, extra_fields=None):
        return BugsnagHandler(client=self, extra_fields=extra_fields)