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)
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
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