Exemplo n.º 1
0
def register_handlers(client):
    from django.core.signals import got_request_exception, request_started, request_finished
    from elasticapm.contrib.django.handlers import exception_handler

    # Connect to Django's internal signal handlers
    got_request_exception.disconnect(dispatch_uid=ERROR_DISPATCH_UID)
    got_request_exception.connect(partial(exception_handler, client),
                                  dispatch_uid=ERROR_DISPATCH_UID,
                                  weak=False)

    request_started.disconnect(dispatch_uid=REQUEST_START_DISPATCH_UID)
    request_started.connect(partial(_request_started_handler, client),
                            dispatch_uid=REQUEST_START_DISPATCH_UID,
                            weak=False)

    request_finished.disconnect(dispatch_uid=REQUEST_FINISH_DISPATCH_UID)
    request_finished.connect(
        lambda sender, **kwargs: client.end_transaction()
        if _should_start_transaction(client) else None,
        dispatch_uid=REQUEST_FINISH_DISPATCH_UID,
        weak=False,
    )

    # If we can import celery, register ourselves as exception handler
    try:
        import celery  # noqa F401
        from elasticapm.contrib.celery import register_exception_tracking

        try:
            register_exception_tracking(client)
        except Exception as e:
            client.logger.exception(
                "Failed installing django-celery hook: %s" % e)
    except ImportError:
        client.logger.debug("Not instrumenting Celery, couldn't import")
Exemplo n.º 2
0
    def request(self, **request):
        """
        The master request method. Compose the environment dictionary and pass
        to the handler, return the result of the handler. Assume defaults for
        the query environment, which can be overridden using the arguments to
        the request.
        """
        environ = self._base_environ(**request)

        # Curry a data dictionary into an instance of the template renderer
        # callback function.
        data = {}
        on_template_render = partial(store_rendered_templates, data)
        signal_uid = "template-render-%s" % id(request)
        signals.template_rendered.connect(on_template_render,
                                          dispatch_uid=signal_uid)
        # Capture exceptions created by the handler.
        exception_uid = "request-exception-%s" % id(request)
        got_request_exception.connect(self.store_exc_info,
                                      dispatch_uid=exception_uid)
        try:
            response = self.handler(environ)
        finally:
            signals.template_rendered.disconnect(dispatch_uid=signal_uid)
            got_request_exception.disconnect(dispatch_uid=exception_uid)
        # Look for a signaled exception, clear the current context exception
        # data, then re-raise the signaled exception. Also clear the signaled
        # exception from the local cache.
        response.exc_info = self.exc_info
        if self.exc_info:
            _, exc_value, _ = self.exc_info
            self.exc_info = None
            if self.raise_request_exception:
                raise exc_value
        # Save the client and request that stimulated the response.
        response.client = self
        response.request = request
        # Add any rendered template detail to the response.
        response.templates = data.get('templates', [])
        response.context = data.get('context')
        response.json = partial(self._parse_json, response)
        # Attach the ResolverMatch instance to the response.
        response.resolver_match = SimpleLazyObject(
            lambda: resolve(request['PATH_INFO']))
        # Flatten a single context. Not really necessary anymore thanks to the
        # __getattr__ flattening in ContextList, but has some edge case
        # backwards compatibility implications.
        if response.context and len(response.context) == 1:
            response.context = response.context[0]
        # Update persistent cookie data.
        if response.cookies:
            self.cookies.update(response.cookies)
        return response
Exemplo n.º 3
0
 async def request(self, **request):
     """
     The master request method. Compose the scope dictionary and pass to the
     handler, return the result of the handler. Assume defaults for the
     query environment, which can be overridden using the arguments to the
     request.
     """
     if "follow" in request:
         raise NotImplementedError(
             "AsyncClient request methods do not accept the follow parameter."
         )
     scope = self._base_scope(**request)
     # Curry a data dictionary into an instance of the template renderer
     # callback function.
     data = {}
     on_template_render = partial(store_rendered_templates, data)
     signal_uid = "template-render-%s" % id(request)
     signals.template_rendered.connect(on_template_render,
                                       dispatch_uid=signal_uid)
     # Capture exceptions created by the handler.
     exception_uid = "request-exception-%s" % id(request)
     got_request_exception.connect(self.store_exc_info,
                                   dispatch_uid=exception_uid)
     try:
         response = await self.handler(scope)
     finally:
         signals.template_rendered.disconnect(dispatch_uid=signal_uid)
         got_request_exception.disconnect(dispatch_uid=exception_uid)
     # Check for signaled exceptions.
     self.check_exception(response)
     # Save the client and request that stimulated the response.
     response.client = self
     response.request = request
     # Add any rendered template detail to the response.
     response.templates = data.get("templates", [])
     response.context = data.get("context")
     response.json = partial(self._parse_json, response)
     # Attach the ResolverMatch instance to the response.
     urlconf = getattr(response.asgi_request, "urlconf", None)
     response.resolver_match = SimpleLazyObject(
         lambda: resolve(request["path"], urlconf=urlconf), )
     # Flatten a single context. Not really necessary anymore thanks to the
     # __getattr__ flattening in ContextList, but has some edge case
     # backwards compatibility implications.
     if response.context and len(response.context) == 1:
         response.context = response.context[0]
     # Update persistent cookie data.
     if response.cookies:
         self.cookies.update(response.cookies)
     return response
Exemplo n.º 4
0
    def request(self, **request):
        """
        The master request method. Compose the environment dictionary and pass
        to the handler, return the result of the handler. Assume defaults for
        the query environment, which can be overridden using the arguments to
        the request.
        """
        environ = self._base_environ(**request)

        # Curry a data dictionary into an instance of the template renderer
        # callback function.
        data = {}
        on_template_render = partial(store_rendered_templates, data)
        signal_uid = "template-render-%s" % id(request)
        signals.template_rendered.connect(on_template_render, dispatch_uid=signal_uid)
        # Capture exceptions created by the handler.
        exception_uid = "request-exception-%s" % id(request)
        got_request_exception.connect(self.store_exc_info, dispatch_uid=exception_uid)
        try:
            response = self.handler(environ)
        finally:
            signals.template_rendered.disconnect(dispatch_uid=signal_uid)
            got_request_exception.disconnect(dispatch_uid=exception_uid)
        # Look for a signaled exception, clear the current context exception
        # data, then re-raise the signaled exception. Also clear the signaled
        # exception from the local cache.
        response.exc_info = self.exc_info
        if self.exc_info:
            _, exc_value, _ = self.exc_info
            self.exc_info = None
            if self.raise_request_exception:
                raise exc_value
        # Save the client and request that stimulated the response.
        response.client = self
        response.request = request
        # Add any rendered template detail to the response.
        response.templates = data.get('templates', [])
        response.context = data.get('context')
        response.json = partial(self._parse_json, response)
        # Attach the ResolverMatch instance to the response.
        response.resolver_match = SimpleLazyObject(lambda: resolve(request['PATH_INFO']))
        # Flatten a single context. Not really necessary anymore thanks to the
        # __getattr__ flattening in ContextList, but has some edge case
        # backwards compatibility implications.
        if response.context and len(response.context) == 1:
            response.context = response.context[0]
        # Update persistent cookie data.
        if response.cookies:
            self.cookies.update(response.cookies)
        return response
Exemplo n.º 5
0
    def test_exception_preservation(self):
        "An exception is preserved and reported correctly, even if sys.exc_clear is called."
        def on_request_exception(sender, request, **kwargs):
            sys.exc_clear()

        got_request_exception.connect(on_request_exception)
        try:
            with self.settings(DEBUG=True):
                handler = WSGIHandler()
                environ = RequestFactory().get(reverse('view_exception', args=(1,))).environ
                response = handler(environ, lambda *a, **k: None)
                self.assertContains(response, '<h2>Traceback ', status_code=500)
                self.assertContains(response, 'raise BrokenException(', status_code=500)
        finally:
            got_request_exception.disconnect(on_request_exception)
Exemplo n.º 6
0
    def test_exception_preservation(self):
        "An exception is preserved and reported correctly, even if sys.exc_clear is called."

        def on_request_exception(sender, request, **kwargs):
            sys.exc_clear()

        got_request_exception.connect(on_request_exception)
        try:
            with self.settings(DEBUG=True):
                handler = WSGIHandler()
                environ = RequestFactory().get(
                    reverse('view_exception', args=(1, ))).environ
                response = handler(environ, lambda *a, **k: None)
                self.assertContains(response,
                                    '<h2>Traceback ',
                                    status_code=500)
                self.assertContains(response,
                                    'raise BrokenException(',
                                    status_code=500)
        finally:
            got_request_exception.disconnect(on_request_exception)
Exemplo n.º 7
0
def register_handlers(client):
    from django.core.signals import got_request_exception
    from elasticapm.contrib.django.handlers import exception_handler

    # Connect to Django's internal signal handler
    dispatch_uid = 'elasticapm-exceptions'
    got_request_exception.disconnect(dispatch_uid=dispatch_uid)
    got_request_exception.connect(partial(exception_handler, client),
                                  dispatch_uid=dispatch_uid,
                                  weak=False)

    # If we can import celery, register ourselves as exception handler
    try:
        import celery  # noqa F401
        from elasticapm.contrib.celery import register_exception_tracking

        try:
            register_exception_tracking(client)
        except Exception as e:
            client.logger.exception(
                'Failed installing django-celery hook: %s' % e)
    except ImportError:
        client.logger.debug("Not instrumenting Celery, couldn't import")
Exemplo n.º 8
0
from __future__ import unicode_literals
Exemplo n.º 9
0
    def request(self, **request):
        """
        The master request method. Composes the environment dictionary
        and passes to the handler, returning the result of the handler.
        Assumes defaults for the query environment, which can be overridden
        using the arguments to the request.
        """
        environ = self._base_environ(**request)

        # Curry a data dictionary into an instance of the template renderer
        # callback function.
        data = {}
        on_template_render = curry(store_rendered_templates, data)
        signal_uid = "template-render-%s" % id(request)
        signals.template_rendered.connect(on_template_render,
                                          dispatch_uid=signal_uid)
        # Capture exceptions created by the handler.
        exception_uid = "request-exception-%s" % id(request)
        got_request_exception.connect(self.store_exc_info,
                                      dispatch_uid=exception_uid)
        try:
            try:
                response = self.handler(environ)
            except TemplateDoesNotExist as e:
                # If the view raises an exception, Django will attempt to show
                # the 500.html template. If that template is not available,
                # we should ignore the error in favor of re-raising the
                # underlying exception that caused the 500 error. Any other
                # template found to be missing during view error handling
                # should be reported as-is.
                if e.args != ('500.html', ):
                    raise

            # Look for a signalled exception, clear the current context
            # exception data, then re-raise the signalled exception.
            # Also make sure that the signalled exception is cleared from
            # the local cache!
            if self.exc_info:
                exc_info = self.exc_info
                self.exc_info = None
                six.reraise(*exc_info)

            # Save the client and request that stimulated the response.
            response.client = self
            response.request = request

            # Add any rendered template detail to the response.
            response.templates = data.get("templates", [])
            response.context = data.get("context")

            response.json = curry(self._parse_json, response)

            # Attach the ResolverMatch instance to the response
            response.resolver_match = SimpleLazyObject(
                lambda: resolve(request['PATH_INFO']))

            # Flatten a single context. Not really necessary anymore thanks to
            # the __getattr__ flattening in ContextList, but has some edge-case
            # backwards-compatibility implications.
            if response.context and len(response.context) == 1:
                response.context = response.context[0]

            # Update persistent cookie data.
            if response.cookies:
                self.cookies.update(response.cookies)

            return response
        finally:
            signals.template_rendered.disconnect(dispatch_uid=signal_uid)
            got_request_exception.disconnect(dispatch_uid=exception_uid)
Exemplo n.º 10
0
 def tearDown(self):
     got_request_exception.disconnect(self._on_request_exception)
     self.exceptions = []
Exemplo n.º 11
0
    def request(self, **request):
        """
        The master request method. Composes the environment dictionary
        and passes to the handler, returning the result of the handler.
        Assumes defaults for the query environment, which can be overridden
        using the arguments to the request.
        """
        environ = self._base_environ(**request)

        # Curry a data dictionary into an instance of the template renderer
        # callback function.
        data = {}
        on_template_render = curry(store_rendered_templates, data)
        signal_uid = "template-render-%s" % id(request)
        signals.template_rendered.connect(on_template_render, dispatch_uid=signal_uid)
        # Capture exceptions created by the handler.
        exception_uid = "request-exception-%s" % id(request)
        got_request_exception.connect(self.store_exc_info, dispatch_uid=exception_uid)
        try:
            try:
                response = self.handler(environ)
            except TemplateDoesNotExist as e:
                # If the view raises an exception, Django will attempt to show
                # the 500.html template. If that template is not available,
                # we should ignore the error in favor of re-raising the
                # underlying exception that caused the 500 error. Any other
                # template found to be missing during view error handling
                # should be reported as-is.
                if e.args != ('500.html',):
                    raise

            # Look for a signalled exception, clear the current context
            # exception data, then re-raise the signalled exception.
            # Also make sure that the signalled exception is cleared from
            # the local cache!
            if self.exc_info:
                exc_info = self.exc_info
                self.exc_info = None
                six.reraise(*exc_info)

            # Save the client and request that stimulated the response.
            response.client = self
            response.request = request

            # Add any rendered template detail to the response.
            response.templates = data.get("templates", [])
            response.context = data.get("context")

            response.json = curry(self._parse_json, response)

            # Attach the ResolverMatch instance to the response
            response.resolver_match = SimpleLazyObject(lambda: resolve(request['PATH_INFO']))

            # Flatten a single context. Not really necessary anymore thanks to
            # the __getattr__ flattening in ContextList, but has some edge-case
            # backwards-compatibility implications.
            if response.context and len(response.context) == 1:
                response.context = response.context[0]

            # Update persistent cookie data.
            if response.cookies:
                self.cookies.update(response.cookies)

            return response
        finally:
            signals.template_rendered.disconnect(dispatch_uid=signal_uid)
            got_request_exception.disconnect(dispatch_uid=exception_uid)
Exemplo n.º 12
0
for k in [k for k in sys.modules if k.startswith('django')]:
    del sys.modules[k]

# Force sys.path to have our own directory first, in case we want to import from it.
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))

# Must set this env var *before* importing any part of Django
os.environ['DJANGO_SETTINGS_MODULE'] = 'errorbucket.settings'

import django.core.handlers.wsgi
from django.core.signals import got_request_exception
import django.db
import django.dispatch.dispatcher


def log_exception(*args, **kwds):
    logging.exception('Exception in request:')


got_request_exception.connect(log_exception)  # Log errors.
got_request_exception.disconnect(
    django.db._rollback_on_exception)  # Unregister the rollback event handler.


def main():
    util.run_wsgi_app(django.core.handlers.wsgi.WSGIHandler())


if __name__ == '__main__':
    main()
Exemplo n.º 13
0
    def uninstall(self):
        request_started.disconnect(self.before_request)
        got_request_exception.disconnect(self.exception_handler)

        if self.celery_handler:
            self.celery_handler.uninstall()
Exemplo n.º 14
0
 def tearDown(self):
     got_request_exception.disconnect(self._on_request_exception)
     self.exceptions = []
Exemplo n.º 15
0
import logging, os, sys
from google.appengine.ext.webapp import util

# Remove the standard version of Django.
for k in [k for k in sys.modules if k.startswith('django')]:
    del sys.modules[k]

# Force sys.path to have our own directory first, in case we want to import from it.
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))

# Must set this env var *before* importing any part of Django
os.environ['DJANGO_SETTINGS_MODULE'] = 'errorbucket.settings'

import django.core.handlers.wsgi
from django.core.signals import got_request_exception
import django.db
import django.dispatch.dispatcher

def log_exception(*args, **kwds):
   logging.exception('Exception in request:')

got_request_exception.connect(log_exception) # Log errors.
got_request_exception.disconnect(django.db._rollback_on_exception) # Unregister the rollback event handler.


def main():
  util.run_wsgi_app(django.core.handlers.wsgi.WSGIHandler())

if __name__ == '__main__':
  main()
Exemplo n.º 16
0
# Force Django to reload its settings.
from django.conf import settings
settings._target = None

# Must set this env var before importing any part of Django
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

import logging
import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher

def log_exception(*args, **kwds):
  logging.exception('Exception in request:')

from django.core.signals import got_request_exception
# Log errors.
got_request_exception.connect(log_exception)
# Unregister the rollback event handler.
got_request_exception.disconnect(django.db._rollback_on_exception)

def main():
  # Create a Django application for WSGI.
  application = django.core.handlers.wsgi.WSGIHandler()

  # Run the WSGI CGI handler with that application.
  util.run_wsgi_app(application)

if __name__ == '__main__':
  main()
Exemplo n.º 17
0
    def uninstall(self):
        request_started.disconnect(self.before_request)
        got_request_exception.disconnect(self.exception_handler)

        if self.celery_handler:
            self.celery_handler.uninstall()