def test_date_params(self): self.store_event( data={ "message": "very bad", "type": "default", "timestamp": iso_format(before_now(minutes=2)), "tags": { "color": "red" }, }, project_id=self.project.id, ) self.store_event( data={ "message": "oh my", "type": "default", "timestamp": iso_format(before_now(days=2)), "tags": { "toy": "train" }, }, project_id=self.project.id, ) params = { "project_id": [self.project.id], "start": self.day_ago, "end": self.min_ago } result = discover.get_facets("", params) keys = {r.key for r in result} assert "color" in keys assert "toy" not in keys
def test_single_project(self): self.store_event( data={ "message": "very bad", "type": "default", "timestamp": iso_format(before_now(minutes=2)), "tags": { "color": "red", "paying": "1" }, }, project_id=self.project.id, ) self.store_event( data={ "message": "very bad", "type": "default", "timestamp": iso_format(before_now(minutes=2)), "tags": { "color": "blue", "paying": "0" }, }, project_id=self.project.id, ) params = { "project_id": [self.project.id], "start": self.day_ago, "end": self.min_ago } result = discover.get_facets("", params) assert len(result) == 5 assert {r.key for r in result} == {"color", "paying", "level"} assert {r.value for r in result} == {"red", "blue", "1", "0", "error"} assert {r.count for r in result} == {1, 2}
def get(self, request, organization): with sentry_sdk.start_span(op="discover.endpoint", description="filter_params") as span: span.set_data("organization", organization) if not features.has("organizations:discover-basic", organization, actor=request.user): return Response(status=404) try: params = self.get_filter_params(request, organization) except NoProjects: return Response([]) params = self.quantize_date_params(request, params) self._validate_project_ids(request, organization, params) with sentry_sdk.start_span(op="discover.endpoint", description="discover_query"): try: facets = discover.get_facets( query=request.GET.get("query"), params=params, referrer="api.organization-events-facets.top-tags", ) except (discover.InvalidSearchQuery, snuba.QueryOutsideRetentionError) as error: raise ParseError(detail=six.text_type(error)) with sentry_sdk.start_span(op="discover.endpoint", description="populate_results") as span: span.set_data("facet_count", len(facets or [])) resp = defaultdict(lambda: {"key": "", "topValues": []}) for row in facets: values = resp[row.key] values["key"] = tagstore.get_standardized_key(row.key) values["topValues"].append({ "name": tagstore.get_tag_value_label(row.key, row.value), "value": row.value, "count": row.count, }) if "project" in resp: # Replace project ids with slugs as that is what we generally expose to users # and filter out projects that the user doesn't have access too. projects = { p.id: p.slug for p in self.get_projects(request, organization) } filtered_values = [] for v in resp["project"]["topValues"]: if v["value"] in projects: name = projects[v["value"]] v.update({"name": name}) filtered_values.append(v) resp["project"]["topValues"] = filtered_values return Response(resp.values())
def test_no_results(self): results = discover.get_facets( "", { "project_id": [self.project.id], "end": self.min_ago, "start": self.day_ago }) assert results == []
def test_project_filter(self): self.store_event( data={ "message": "very bad", "type": "default", "timestamp": iso_format(before_now(minutes=2)), "tags": { "color": "red" }, }, project_id=self.project.id, ) other_project = self.create_project() self.store_event( data={ "message": "very bad", "type": "default", "timestamp": iso_format(before_now(minutes=2)), "tags": { "toy": "train" }, }, project_id=other_project.id, ) params = { "project_id": [self.project.id], "start": self.day_ago, "end": self.min_ago } result = discover.get_facets("", params) keys = {r.key for r in result} assert keys == {"color", "level"} # Query more than one project. params = { "project_id": [self.project.id, other_project.id], "start": self.day_ago, "end": self.min_ago, } result = discover.get_facets("", params) keys = {r.key for r in result} assert keys == {"level", "toy", "color", "project"} projects = [f for f in result if f.key == "project"] assert [p.count for p in projects] == [1, 1]
def get(self, request, organization): if not features.has("organizations:discover-basic", organization, actor=request.user): return Response(status=404) try: params = self.get_filter_params(request, organization) except OrganizationEventsError as error: raise ParseError(detail=six.text_type(error)) except NoProjects: return Response({"detail": "A valid project must be included."}, status=400) try: self._validate_project_ids(request, organization, params) except OrganizationEventsError as error: return Response({"detail": six.text_type(error)}, status=400) try: facets = discover.get_facets( query=request.GET.get("query"), params=params, referrer="api.organization-events-facets.top-tags", ) except discover.InvalidSearchQuery as error: raise ParseError(detail=six.text_type(error)) resp = defaultdict(lambda: {"key": "", "topValues": []}) for row in facets: values = resp[row.key] values["key"] = tagstore.get_standardized_key(row.key) values["topValues"].append({ "name": tagstore.get_tag_value_label(row.key, row.value), "value": row.value, "count": row.count, }) if "project" in resp: # Replace project ids with slugs as that is what we generally expose to users # and filter out projects that the user doesn't have access too. projects = { p.id: p.slug for p in self.get_projects(request, organization) } filtered_values = [] for v in resp["project"]["topValues"]: if v["value"] in projects: name = projects[v["value"]] v.update({"name": name}) filtered_values.append(v) resp["project"]["topValues"] = filtered_values return Response(resp.values())
def get(self, request, organization): if not self.has_feature(organization, request): return Response(status=404) try: params = self.get_snuba_params(request, organization) except NoProjects: return Response([]) with sentry_sdk.start_span(op="discover.endpoint", description="discover_query"): with self.handle_query_errors(): facets = discover.get_facets( query=request.GET.get("query"), params=params, referrer="api.organization-events-facets.top-tags", ) with sentry_sdk.start_span(op="discover.endpoint", description="populate_results") as span: span.set_data("facet_count", len(facets or [])) resp = defaultdict(lambda: {"key": "", "topValues": []}) for row in facets: values = resp[row.key] values["key"] = tagstore.get_standardized_key(row.key) values["topValues"].append({ "name": tagstore.get_tag_value_label(row.key, row.value), "value": row.value, "count": row.count, }) if "project" in resp: # Replace project ids with slugs as that is what we generally expose to users # and filter out projects that the user doesn't have access too. projects = { p.id: p.slug for p in self.get_projects(request, organization) } filtered_values = [] for v in resp["project"]["topValues"]: if v["value"] in projects: name = projects[v["value"]] v.update({"name": name}) filtered_values.append(v) resp["project"]["topValues"] = filtered_values return Response(list(resp.values()))
def test_enviroment_promoted_tag(self): for env in ("prod", "staging", None): self.store_event( data={ "message": "very bad", "type": "default", "environment": env, "timestamp": iso_format(before_now(minutes=2)), }, project_id=self.project.id, ) params = { "project_id": [self.project.id], "start": self.day_ago, "end": self.min_ago } result = discover.get_facets("", params) keys = {r.key for r in result} assert keys == {"environment", "level"} assert {"prod", "staging", None} == {f.value for f in result if f.key == "environment"} assert {1} == {f.count for f in result if f.key == "environment"}