Exemple #1
0
    def __init__(self, get_response=None):
        self.get_response = get_response

        self.propagator = get_tracer_propagator()
        self.exporter = get_tracer_exporter()
        self.sampler = get_tracer_sampler()

        settings_ = getattr(settings, 'OPENCENSUS', {})
        settings_ = settings_.get('TRACE', {})
        self.blacklist_paths = settings_.get(BLACKLIST_PATHS, None)
        self.blacklist_hostnames = settings_.get(BLACKLIST_HOSTNAMES, None)

        self.resolver = RouteResolver()
Exemple #2
0
class OpencensusMiddleware(_OpencensusMiddleware):
    def __init__(self, get_response=None):
        self.get_response = get_response

        self.propagator = get_tracer_propagator()
        self.exporter = get_tracer_exporter()
        self.sampler = get_tracer_sampler()

        settings_ = getattr(settings, 'OPENCENSUS', {})
        settings_ = settings_.get('TRACE', {})
        self.blacklist_paths = settings_.get(BLACKLIST_PATHS, None)
        self.blacklist_hostnames = settings_.get(BLACKLIST_HOSTNAMES, None)

        self.resolver = RouteResolver()

    def process_view(self, request, view_func, *args, **kwargs):
        """Process view is executed before the view function, here we get the
        function name add set it as the span name.
        """

        # Do not trace if the url is blacklisted
        if utils.disable_tracing_url(request.path, self.blacklist_paths):
            return

        try:
            # Get the current span and set the span name to the current
            # function name of the request.
            tracer = _get_current_tracer()
            span = tracer.current_span()
            span.name = 'Recv.' + self.resolver.resolve(request.path_info)
            tracer.add_attribute_to_current_span(
                attribute_key='django.view',
                attribute_value=utils.get_func_name(view_func))
        except Exception:  # pragma: no cover
            logger.error('Failed to trace request', exc_info=True)
Exemple #3
0
class SentryMiddleware(threading.local):
    resolver = RouteResolver()

    # backwards compat
    @property
    def thread(self):
        return self

    def _get_transaction_from_request(self, request):
        # TODO(dcramer): it'd be nice to pull out parameters
        # and make this a normalized path
        return self.resolver.resolve(request.path)

    def process_request(self, request):
        self._txid = None
        self.thread.request = request

    def process_view(self, request, func, args, kwargs):
        from raven.contrib.django.models import client

        try:
            self._txid = client.transaction.push(
                self._get_transaction_from_request(request))
        except Exception as exc:
            client.error_logger.exception(repr(exc))
        else:
            # we utilize request_finished as the exception gets reported
            # *after* process_response is executed, and thus clearing the
            # transaction there would leave it empty
            # XXX(dcramer): weakref's cause a threading issue in certain
            # versions of Django (e.g. 1.6). While they'd be ideal, we're under
            # the assumption that Django will always call our function except
            # in the situation of a process or thread dying.
            request_finished.connect(self.request_finished, weak=False)

        return None

    def request_finished(self, **kwargs):
        from raven.contrib.django.models import client

        if getattr(self, '_txid', None):
            client.transaction.pop(self._txid)
            self._txid = None

        request_finished.disconnect(self.request_finished)
Exemple #4
0
class DjangoClient(Client):
    logger = logging.getLogger('sentry.errors.client.django')
    resolver = RouteResolver()

    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 install_sql_hook(self):
        install_sql_hook()

    def get_user_info(self, request):

        user_info = {
            'ip_address': get_client_ip(request.META),
        }
        user = getattr(request, 'user', None)
        if user is None:
            return user_info

        try:
            if hasattr(user, 'is_authenticated'):
                # is_authenticated was a method in Django < 1.10
                if callable(user.is_authenticated):
                    authenticated = user.is_authenticated()
                else:
                    authenticated = user.is_authenticated
                if not authenticated:
                    return user_info

            user_info['id'] = user.pk

            if hasattr(user, 'email'):
                user_info['email'] = user.email

            if hasattr(user, 'get_username'):
                user_info['username'] = user.get_username()
            elif hasattr(user, 'username'):
                user_info['username'] = user.username
        except Exception:
            # We expect that user objects can be somewhat broken at times
            # and try to just handle as much as possible and ignore errors
            # as good as possible here.
            pass

        return user_info

    def get_data_from_request(self, request):
        result = {}

        result['user'] = self.get_user_info(request)

        try:
            uri = request.build_absolute_uri()
        except SuspiciousOperation:
            # attempt to build a URL for reporting as Django won't allow us to
            # use get_host()
            if request.is_secure():
                scheme = 'https'
            else:
                scheme = 'http'
            host = get_host(request)
            uri = '%s://%s%s' % (scheme, host, request.path)

        if request.method not in ('GET', 'HEAD'):
            try:
                data = request.body
            except Exception:
                try:
                    data = request.raw_post_data
                except Exception:
                    # assume we had a partial read.
                    try:
                        data = request.POST or '<unavailable>'
                    except Exception:
                        data = '<unavailable>'
                    else:
                        if isinstance(data, MultiValueDict):
                            data = dict((k, v[0] if len(v) == 1 else v)
                                        for k, v in iterlists(data))
        else:
            data = None

        environ = request.META

        result.update({
            'request': {
                'method': request.method,
                'url': uri,
                'query_string': request.META.get('QUERY_STRING'),
                'data': data,
                'cookies': dict(request.COOKIES),
                'headers': dict(get_headers(environ)),
                'env': dict(get_environ(environ)),
            }
        })

        return result

    def build_msg(self, *args, **kwargs):
        data = super(DjangoClient, self).build_msg(*args, **kwargs)

        for frame in self._iter_frames(data):
            module = frame.get('module')
            if not module:
                continue

            if module.startswith('django.'):
                frame['in_app'] = False

        if not self.site and 'django.contrib.sites' in settings.INSTALLED_APPS:
            try:
                from django.contrib.sites.models import Site
                site = Site.objects.get_current()
                site_name = site.name or site.domain
                data['tags'].setdefault('site', site_name)
            except Exception:
                # Database error? Fallback to the id
                try:
                    data['tags'].setdefault('site', settings.SITE_ID)
                except AttributeError:
                    # SITE_ID wasn't set, so just ignore
                    pass

        return data

    def capture(self, event_type, request=None, **kwargs):
        if 'data' not in kwargs:
            kwargs['data'] = data = {}
        else:
            data = kwargs['data']

        if request is None:
            request = getattr(SentryMiddleware.thread, 'request', None)

        is_http_request = isinstance(request, HttpRequest)
        if is_http_request:
            data.update(self.get_data_from_request(request))

        if kwargs.get('exc_info'):
            exc_value = kwargs['exc_info'][1]
            # As of r16833 (Django) all exceptions may contain a
            # ``django_template_source`` attribute (rather than the legacy
            # ``TemplateSyntaxError.source`` check) which describes
            # template information.  As of Django 1.9 or so the new
            # template debug thing showed up.
            if hasattr(exc_value, 'django_template_source') or \
               ((isinstance(exc_value, TemplateSyntaxError) and
                isinstance(getattr(exc_value, 'source', None),
                           (tuple, list)) and
                isinstance(exc_value.source[0], Origin))) or \
               hasattr(exc_value, 'template_debug'):
                source = getattr(exc_value, 'django_template_source',
                                 getattr(exc_value, 'source', None))
                debug = getattr(exc_value, 'template_debug', None)
                if source is None:
                    self.logger.info(
                        'Unable to get template source from exception')
                data.update(get_data_from_template(source, debug))

        result = super(DjangoClient, self).capture(event_type, **kwargs)

        if is_http_request and result:
            # attach the sentry object to the request
            request.sentry = {
                'project_id': data.get('project', self.remote.project),
                'id': result,
            }

        return result

    def get_transaction_from_request(self, request):
        return self.resolver.resolve(request.path)
Exemple #5
0
 def test_resolver(self):
     resolver = get_resolver()
     route_resolver = RouteResolver()
     result = route_resolver._resolve(resolver, '/api/v1/example/')
     assert result == '/api/{api_name}/{resource_name}/'
def test_included_match():
    resolver = RouteResolver()
    result = resolver.resolve('/example/foo/bar/baz', example_url_conf)
    assert result == '/example/foo/bar/{param}'
def test_complex_match():
    resolver = RouteResolver()
    result = resolver.resolve('/api/1234/store/', example_url_conf)
    assert result == '/api/{project_id}/store/'
def test_simple_match():
    resolver = RouteResolver()
    result = resolver.resolve('/report/', example_url_conf)
    assert result == '/report/'
Exemple #9
0
def test_simple_match(
):  # TODO: ash add matchedstring to make this test actually test something
    resolver = RouteResolver()
    result = resolver.resolve('/report/', example_url_conf)
    assert result == '/report/'
Exemple #10
0
 def handle(self, *args, **options):
     resolver = get_resolver()
     route_resolver = RouteResolver()
     print(route_resolver._resolve(resolver, '/api/v1/thing/'))
Exemple #11
0
def test_included_match():
    resolver = RouteResolver()
    result = resolver.resolve('/example/foo/bar/baz', example_url_conf)
    assert result == '/example/foo/bar/{param}'
Exemple #12
0
def test_complex_match():
    resolver = RouteResolver()
    result = resolver.resolve('/api/1234/store/', example_url_conf)
    assert result == '/api/{project_id}/store/'
Exemple #13
0
def test_simple_match():
    resolver = RouteResolver()
    result = resolver.resolve('/report/', example_url_conf)
    assert result == '/report/'
Exemple #14
0
def test_no_match():
    resolver = RouteResolver()
    result = resolver.resolve('/foo/bar', example_url_conf)
    assert result == '/foo/bar'
def route_resolver():
    return RouteResolver()
Exemple #16
0
def test_no_match():
    resolver = RouteResolver()
    result = resolver.resolve('/foo/bar', example_url_conf)
    assert result == '/foo/bar'
 def test_resolver(self):
     resolver = get_resolver()
     route_resolver = RouteResolver()
     result = route_resolver._resolve(resolver, '/api/v1/example/')
     assert result == '/api/{api_name}/{resource_name}/'
Exemple #18
0
def test_simple_match():  # TODO: ash add matchedstring to make this test actually test something
    resolver = RouteResolver()
    result = resolver.resolve('/report/', example_url_conf)
    assert result == '/report/'