Beispiel #1
0
    def _search(self, request, project, extra_query_kwargs=None):
        try:
            environment = self._get_environment_from_request(
                request,
                project.organization_id,
            )
        except Environment.DoesNotExist:
            # XXX: The 1000 magic number for `max_hits` is an abstraction leak
            # from `sentry.api.paginator.BasePaginator.get_result`.
            result = CursorResult([], None, None, hits=0, max_hits=1000)
            query_kwargs = {}
        else:
            environments = [environment
                            ] if environment is not None else environment
            query_kwargs = build_query_params_from_request(
                request,
                project.organization,
                [project],
                environments,
            )
            if extra_query_kwargs is not None:
                assert 'environment' not in extra_query_kwargs
                query_kwargs.update(extra_query_kwargs)

            query_kwargs['environments'] = environments
            result = search.query(**query_kwargs)
        return result, query_kwargs
    def get(self, request, organization):
        with sentry_sdk.start_span(op="discover.endpoint", description="filter_params") as span:
            span.set_data("organization", organization)
            try:
                params = self.get_filter_params(request, organization)
            except NoProjects:
                return Response([])

            possible_keys = ["transaction"]
            lookup_keys = {key: request.query_params.get(key) for key in possible_keys}

            if not any(lookup_keys.values()):
                return Response(
                    {
                        "detail": "Must provide one of {} in order to find related events".format(
                            possible_keys
                        )
                    },
                    status=400,
                )

        try:
            with sentry_sdk.start_span(op="discover.endpoint", description="filter_creation"):
                projects = self.get_projects(request, organization)
                query_kwargs = build_query_params_from_request(
                    request, organization, projects, params.get("environment")
                )
                query_kwargs["limit"] = 5
                try:
                    # Need to escape quotes in case some "joker" has a transaction with quotes
                    transaction_name = UNESCAPED_QUOTE_RE.sub('\\"', lookup_keys["transaction"])
                    parsed_terms = parse_search_query('transaction:"{}"'.format(transaction_name))
                except ParseError:
                    return Response({"detail": "Invalid transaction search"}, status=400)

                if query_kwargs.get("search_filters"):
                    query_kwargs["search_filters"].extend(parsed_terms)
                else:
                    query_kwargs["search_filters"] = parsed_terms

            with sentry_sdk.start_span(op="discover.endpoint", description="issue_search"):
                results = search.query(**query_kwargs)
        except discover.InvalidSearchQuery as err:
            raise ParseError(detail=six.text_type(err))

        with sentry_sdk.start_span(op="discover.endpoint", description="serialize_results") as span:
            results = list(results)
            span.set_data("result_length", len(results))
            context = serialize(
                results,
                request.user,
                GroupSerializer(
                    environment_func=self._get_environment_func(request, organization.id)
                ),
            )

        return Response(context)
Beispiel #3
0
    def _search(self, request, organization, projects, environments, extra_query_kwargs=None):
        query_kwargs = build_query_params_from_request(
            request, organization, projects, environments
        )
        if extra_query_kwargs is not None:
            assert "environment" not in extra_query_kwargs
            query_kwargs.update(extra_query_kwargs)

        query_kwargs["environments"] = environments if environments else None
        result = search.query(**query_kwargs)
        return result, query_kwargs
    def _search(self, request, organization, projects, environments, extra_query_kwargs=None):
        query_kwargs = build_query_params_from_request(
            request, organization, projects, environments,
        )
        if extra_query_kwargs is not None:
            assert 'environment' not in extra_query_kwargs
            query_kwargs.update(extra_query_kwargs)

        query_kwargs['environments'] = environments if environments else None
        result = search.query(**query_kwargs)
        return result, query_kwargs
Beispiel #5
0
    def get(self, request, organization):
        try:
            # events-meta is still used by events v1 which doesn't require global views
            params = self.get_snuba_params(request, organization, check_global_views=False)
        except NoProjects:
            return Response([])

        with sentry_sdk.start_span(op="discover.endpoint", description="find_lookup_keys") as span:
            possible_keys = ["transaction"]
            lookup_keys = {key: request.query_params.get(key) for key in possible_keys}

            if not any(lookup_keys.values()):
                return Response(
                    {
                        "detail": f"Must provide one of {possible_keys} in order to find related events"
                    },
                    status=400,
                )

        with self.handle_query_errors():
            with sentry_sdk.start_span(op="discover.endpoint", description="filter_creation"):
                projects = self.get_projects(request, organization)
                query_kwargs = build_query_params_from_request(
                    request, organization, projects, params.get("environment")
                )
                query_kwargs["limit"] = 5
                try:
                    # Need to escape quotes in case some "joker" has a transaction with quotes
                    transaction_name = UNESCAPED_QUOTE_RE.sub('\\"', lookup_keys["transaction"])
                    parsed_terms = parse_search_query(f'transaction:"{transaction_name}"')
                except ParseError:
                    return Response({"detail": "Invalid transaction search"}, status=400)

                if query_kwargs.get("search_filters"):
                    query_kwargs["search_filters"].extend(parsed_terms)
                else:
                    query_kwargs["search_filters"] = parsed_terms

            with sentry_sdk.start_span(op="discover.endpoint", description="issue_search"):
                results = search.query(**query_kwargs)

        with sentry_sdk.start_span(op="discover.endpoint", description="serialize_results") as span:
            results = list(results)
            span.set_data("result_length", len(results))
            context = serialize(
                results,
                request.user,
                GroupSerializer(
                    environment_func=self._get_environment_func(request, organization.id)
                ),
            )

        return Response(context)
    def _search(self, request, project, extra_query_kwargs=None):
        try:
            environment = self._get_environment_from_request(
                request,
                project.organization_id,
            )
        except Environment.DoesNotExist:
            # XXX: The 1000 magic number for `max_hits` is an abstraction leak
            # from `sentry.api.paginator.BasePaginator.get_result`.
            result = CursorResult([], None, None, hits=0, max_hits=1000)
            query_kwargs = {}
        else:
            environments = [environment] if environment is not None else environment
            query_kwargs = build_query_params_from_request(
                request, project.organization, [project], environments,
            )
            if extra_query_kwargs is not None:
                assert 'environment' not in extra_query_kwargs
                query_kwargs.update(extra_query_kwargs)

            query_kwargs['environments'] = environments
            result = search.query(**query_kwargs)
        return result, query_kwargs
    def get(self, request, organization):
        """
        Get the stats on an Organization's Issues
        `````````````````````````````
        Return a list of issues (groups) with the requested stats.  All parameters are
        supplied as query string parameters.

        :qparam list groups: A list of group ids
        :qparam list expand: an optional list of strings to opt in to additional data. Supports `inbox`
        :qparam list collapse: an optional list of strings to opt out of certain pieces of data. Supports `stats`, `lifetime`, `filtered`, and `base`

        The ``groupStatsPeriod`` parameter can be used to select the timeline
        stats which should be present. Possible values are: '' (disable),
        '24h', '14d'

        The ``statsPeriod`` parameter can be used to select a date window starting
        from now. Ex. ``14d``.

        The ``start`` and ``end`` parameters can be used to select an absolute
        date period to fetch issues from.

        :qparam string statsPeriod: an optional stat period (can be one of
                                    ``"24h"``, ``"14d"``, and ``""``).
        :qparam string groupStatsPeriod: an optional stat period (can be one of
                                    ``"24h"``, ``"14d"``, and ``""``).
        :qparam string start:       Beginning date. You must also provide ``end``.
        :qparam string end:         End date. You must also provide ``start``.
        """

        stats_period = request.GET.get("groupStatsPeriod")
        try:
            start, end = get_date_range_from_params(request.GET)
        except InvalidParams as e:
            raise ParseError(detail=six.text_type(e))

        expand = request.GET.getlist("expand", [])
        collapse = request.GET.getlist("collapse", ["base"])
        has_inbox = features.has("organizations:inbox", organization, actor=request.user)
        has_workflow_owners = features.has(
            "organizations:workflow-owners", organization=organization, actor=request.user
        )
        projects = self.get_projects(request, organization)
        project_ids = [p.id for p in projects]

        try:
            group_ids = set(map(int, request.GET.getlist("groups")))
        except ValueError:
            raise ParseError(detail="Group ids must be integers")

        if not group_ids:
            raise ParseError(
                detail="You should include `groups` with your request. (i.e. groups=1,2,3)"
            )

        else:
            groups = list(Group.objects.filter(id__in=group_ids, project_id__in=project_ids))
            if not groups:
                raise ParseError(detail="No matching groups found")
            elif len(groups) > 25:
                raise ParseError(detail="Too many groups requested.")
            elif any(g for g in groups if not request.access.has_project_access(g.project)):
                raise PermissionDenied

        if stats_period not in (None, "", "24h", "14d", "auto"):
            raise ParseError(detail=ERR_INVALID_STATS_PERIOD)
        stats_period, stats_period_start, stats_period_end = calculate_stats_period(
            stats_period, start, end
        )

        environments = self.get_environments(request, organization)
        query_kwargs = build_query_params_from_request(
            request, organization, projects, environments
        )
        context = serialize(
            groups,
            request.user,
            StreamGroupSerializerSnuba(
                environment_ids=[env.id for env in environments],
                stats_period=stats_period,
                stats_period_start=stats_period_start,
                stats_period_end=stats_period_end,
                collapse=collapse,
                expand=expand,
                has_inbox=has_inbox,
                has_workflow_owners=has_workflow_owners,
                start=start,
                end=end,
                search_filters=query_kwargs["search_filters"]
                if "search_filters" in query_kwargs
                else None,
            ),
        )

        response = Response(context)
        return response